package org.jboss.resteasy.security.smime;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.jboss.resteasy.security.doseta.i18n.Messages;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Providers;
import java.io.ByteArrayInputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Base64;
public class PKCS7SignatureInput<T>
{
private PublicKey publicKey;
private X509Certificate certificate;
private Class<?> type;
private Type genericType;
private CMSSignedData data;
private Annotation[] annotations;
private Providers providers;
private Object entity;
public PKCS7SignatureInput()
{
}
public PKCS7SignatureInput(final CMSSignedData data)
{
this.data = data;
}
public PKCS7SignatureInput(final String base64)
{
try
{
byte[] bytes = Base64.getDecoder().decode(base64);
this.data = new CMSSignedData(bytes);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
public PKCS7SignatureInput(final byte[] bytes)
{
try
{
this.data = new CMSSignedData(bytes);
}
catch (CMSException e)
{
throw new RuntimeException(e);
}
}
public PublicKey getPublicKey()
{
return publicKey;
}
public void setPublicKey(PublicKey publicKey)
{
this.publicKey = publicKey;
}
public X509Certificate getCertificate()
{
return certificate;
}
public void setCertificate(X509Certificate certificate)
{
this.certificate = certificate;
}
public Class<?> getType()
{
return type;
}
public void setType(Class<?> type)
{
this.type = type;
}
public void setType(GenericType<?> type)
{
this.type = type.getRawType();
this.genericType = type.getType();
}
public Type getGenericType()
{
return genericType;
}
public void setGenericType(Type genericType)
{
this.genericType = genericType;
}
public CMSSignedData getData()
{
return data;
}
public void setData(CMSSignedData data)
{
this.data = data;
}
public Annotation[] getAnnotations()
{
return annotations;
}
public void setAnnotations(Annotation[] annotations)
{
this.annotations = annotations;
}
public Providers getProviders()
{
return providers;
}
public void setProviders(Providers providers)
{
this.providers = providers;
}
@SuppressWarnings("unchecked")
public T getEntity(MediaType mediaType)
{
return (T)getEntity(type, genericType, annotations, mediaType);
}
public <T2> T2 getEntity(Class<T2> type, MediaType mediaType)
{
return getEntity(type, type, annotations, mediaType);
}
@SuppressWarnings("unchecked")
public <T2> T2 getEntity(GenericType<T2> gt, MediaType mediaType)
{
return getEntity((Class<T2>) gt.getRawType(), gt.getType(), annotations, mediaType);
}
@SuppressWarnings("unchecked")
public <T2> T2 getEntity(GenericType<T2> gt, Annotation[] ann, MediaType mediaType)
{
return getEntity((Class<T2>) gt.getRawType(), gt.getType(), ann, mediaType);
}
@SuppressWarnings({"rawtypes", "unchecked"})
public <T2> T2 getEntity(Class<T2> t, Type gt, Annotation[] ann, MediaType mediaType)
{
if (entity != null) return (T2)entity;
byte[] bytes = (byte[])data.getSignedContent().getContent();
MessageBodyReader reader = providers.getMessageBodyReader(t, gt, ann, mediaType);
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
try
{
entity = reader.readFrom(t, gt, ann, mediaType, new MultivaluedMapImpl<String, String>(), is);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return (T2)entity;
}
public boolean verify() throws Exception
{
if (certificate != null) return verify(certificate);
else if (publicKey != null) return verify(publicKey);
else throw new NullPointerException(Messages.MESSAGES.certificateNorPublicKeySet());
}
public boolean verify(X509Certificate certificate) throws Exception
{
for (Object info : data.getSignerInfos().getSigners())
{
SignerInformation signer = (SignerInformation)info;
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certificate)))
{
return true;
}
}
return false;
}
public boolean verify(PublicKey publicKey) throws Exception
{
for (Object info : data.getSignerInfos().getSigners())
{
SignerInformation signer = (SignerInformation)info;
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(publicKey)))
{
return true;
}
}
return false;
}
}