removed HorribleProxy

added current version of BouncyCastle and xmlsec (using xmlsec instead of jdk internal classes, because of interoperabiltiy with e.g. IBM JDK)
heaps of changes because of above

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1620229 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2014-08-24 23:05:26 +00:00
parent 8962fa8310
commit d0cc2e4267
7 changed files with 275 additions and 942 deletions

View File

@ -25,5 +25,9 @@
<classpathentry kind="lib" path="ooxml-lib/ooxml-schemas-1.1.jar" sourcepath="ooxml-lib/ooxml-schemas-src-1.1.jar"/> <classpathentry kind="lib" path="ooxml-lib/ooxml-schemas-1.1.jar" sourcepath="ooxml-lib/ooxml-schemas-src-1.1.jar"/>
<classpathentry kind="lib" path="ooxml-lib/ooxml-encryption-1.2.jar" sourcepath="ooxml-lib/ooxml-encryption-src-1.2.jar"/> <classpathentry kind="lib" path="ooxml-lib/ooxml-encryption-1.2.jar" sourcepath="ooxml-lib/ooxml-encryption-src-1.2.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="compile-lib/slf4j-api-1.7.7.jar"/>
<classpathentry kind="lib" path="compile-lib/bcpkix-jdk15on-151.jar"/>
<classpathentry kind="lib" path="compile-lib/bcprov-ext-jdk15on-1.51.jar"/>
<classpathentry kind="lib" path="compile-lib/xmlsec-2.0.1.jar"/>
<classpathentry kind="output" path="build/eclipse"/> <classpathentry kind="output" path="build/eclipse"/>
</classpath> </classpath>

View File

@ -61,6 +61,7 @@ under the License.
<property name="main.lib" location="lib"/> <property name="main.lib" location="lib"/>
<property name="ooxml.lib" location="ooxml-lib"/> <property name="ooxml.lib" location="ooxml-lib"/>
<property name="compile.lib" location="compile-lib"/>
<property name="forrest.home" value="${env.FORREST_HOME}"/> <property name="forrest.home" value="${env.FORREST_HOME}"/>
<!-- compiler options options --> <!-- compiler options options -->
@ -146,11 +147,15 @@ under the License.
<property name="main.antlauncher.jar" location="${main.lib}/ant-launcher-1.9.4.jar"/> <property name="main.antlauncher.jar" location="${main.lib}/ant-launcher-1.9.4.jar"/>
<property name="main.antlauncher.url" value="${repository.m2}/maven2/org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar"/> <property name="main.antlauncher.url" value="${repository.m2}/maven2/org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar"/>
<!-- test libs --> <!-- xml signature libs -->
<property name="test.bouncycastle-prov.jar" location="${main.lib}/bcprov-ext-jdk15on-1.51.jar"/> <property name="dsig.xmlsec.jar" location="${compile.lib}/xmlsec-2.0.1.jar"/>
<property name="test.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.51/bcprov-ext-jdk15on-1.51.jar"/> <property name="dsig.xmlsec.url" value="${repository.m2}/maven2/org/apache/santuario/xmlsec/2.0.1/xmlsec-2.0.1.jar"/>
<property name="test.bouncycastle-pkix.jar" location="${main.lib}/bcpkix-jdk15on-151.jar"/> <property name="dsig.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.51.jar"/>
<property name="test.bouncycastle-pkix.url" value="${repository.m2}/maven2/org/bouncycastle/bcpkix-jdk15on/1.51/bcpkix-jdk15on-151.jar"/> <property name="dsig.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.51/bcprov-ext-jdk15on-1.51.jar"/>
<property name="dsig.bouncycastle-pkix.jar" location="${compile.lib}/bcpkix-jdk15on-151.jar"/>
<property name="dsig.bouncycastle-pkix.url" value="${repository.m2}/maven2/org/bouncycastle/bcpkix-jdk15on/1.51/bcpkix-jdk15on-151.jar"/>
<property name="dsig.sl4j-api.jar" location="${compile.lib}/slf4j-api-1.7.7.jar"/>
<property name="dsig.sl4j-api.url" value="${repository.m2}/maven2/org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar"/>
<!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target--> <!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
<property name="ooxml.xmlbeans23.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/> <property name="ooxml.xmlbeans23.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
@ -438,8 +443,16 @@ under the License.
<param name="destfile" value="${rat.jar}"/> <param name="destfile" value="${rat.jar}"/>
</antcall> </antcall>
<antcall target="downloadfile"> <antcall target="downloadfile">
<param name="sourcefile" value="${test.bouncycastle-prov.url}"/> <param name="sourcefile" value="${dsig.bouncycastle-prov.url}"/>
<param name="destfile" value="${test.bouncycastle-prov.jar}"/> <param name="destfile" value="${dsig.bouncycastle-prov.jar}"/>
</antcall>
<antcall target="downloadfile">
<param name="sourcefile" value="${dsig.bouncycastle-pkix.url}"/>
<param name="destfile" value="${dsig.bouncycastle-pkix.jar}"/>
</antcall>
<antcall target="downloadfile">
<param name="sourcefile" value="${dsig.xmlsec.url}"/>
<param name="destfile" value="${dsig.xmlsec.jar}"/>
</antcall> </antcall>
</target> </target>

View File

@ -1,427 +0,0 @@
package org.apache.poi.poifs.crypt.dsig;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Date;
import javax.security.auth.x500.X500Principal;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.XMLSignatureException;
import org.apache.poi.poifs.crypt.dsig.HorribleProxy.ProxyIf;
import org.w3c.dom.Node;
public interface HorribleProxies {
public static final String xmlSecBase = "org.jcp.xml.dsig.internal.dom";
// public static final String xmlSecBase = "org.apache.jcp.xml.dsig.internal.dom";
public interface ASN1InputStreamIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ASN1InputStream";
ASN1OctetStringIf readObject$ASNString() throws IOException;
DEROctetStringIf readObject$DERString() throws IOException;
ASN1IntegerIf readObject$Integer() throws IOException;
ASN1SequenceIf readObject$Sequence() throws IOException;
Object readObject$Object() throws IOException;
}
public interface ASN1IntegerIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ASN1Integer";
BigInteger getPositiveValue();
}
public interface ASN1ObjectIdentifierIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ASN1ObjectIdentifier";
String getId();
}
public interface ASN1OctetStringIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ASN1OctetString";
byte[] getOctets();
}
public interface ASN1SequenceIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ASN1Sequence";
}
public interface AuthorityInformationAccessIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.AuthorityInformationAccess";
}
public interface AuthorityKeyIdentifierIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.AuthorityKeyIdentifier";
byte[] getKeyIdentifier();
}
public interface BasicConstraintsIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.BasicConstraints";
}
public interface BasicOCSPRespIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.BasicOCSPResp";
Date getProducedAt();
RespIDIf getResponderId();
}
public interface BcDigestCalculatorProviderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.bc.BcDigestCalculatorProvider";
}
public interface BcRSASignerInfoVerifierBuilderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder";
SignerInformationVerifierIf build(X509CertificateHolderIf holder);
}
public interface CanonicalizerIf extends ProxyIf {
String delegateClass = "com.sun.org.apache.xml.internal.security.c14n.Canonicalizer";
byte[] canonicalizeSubtree(Node node) throws Exception;
}
public interface CRLNumberIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.CRLNumber";
}
public interface DefaultDigestAlgorithmIdentifierFinderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder";
}
public interface DistributionPointNameIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.DistributionPointName";
}
public interface DistributionPointIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.DistributionPoint";
}
public interface DERIA5StringIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.DERIA5String";
}
public interface DEROctetStringIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.DEROctetString";
byte[] getOctets();
}
public interface DERTaggedObjectIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.DERTaggedObject";
int getTagNo();
ASN1OctetStringIf getObject$String();
Object getObject$Object();
}
public interface DERSequenceIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.DERSequence";
}
public interface DOMKeyInfoIf extends ProxyIf {
String delegateClass = xmlSecBase+".DOMKeyInfo";
void marshal(Node parent, Node nextSibling, String dsPrefix, DOMCryptoContext context) throws MarshalException;
}
public interface DOMReferenceIf extends ProxyIf {
String delegateClass = xmlSecBase+".DOMReference";
void digest(XMLSignContext paramXMLSignContext) throws XMLSignatureException;
byte[] getDigestValue();
}
public interface DOMSignedInfoIf extends ProxyIf {
String delegateClass = xmlSecBase+".DOMSignedInfo";
void canonicalize(XMLCryptoContext paramXMLCryptoContext, ByteArrayOutputStream paramByteArrayOutputStream);
}
public interface XMLSignatureIf extends ProxyIf {
String delegateClass = "com.sun.org.apache.xml.internal.security.signature.XMLSignature";
String ALGO_ID_SIGNATURE_RSA_SHA1();
String ALGO_ID_SIGNATURE_RSA_SHA256();
String ALGO_ID_SIGNATURE_RSA_SHA384();
String ALGO_ID_SIGNATURE_RSA_SHA512();
String ALGO_ID_MAC_HMAC_RIPEMD160();
}
public interface DOMXMLSignatureIf extends ProxyIf {
String delegateClass = xmlSecBase+".DOMXMLSignature";
void marshal(Node node, String prefix, DOMCryptoContext context) throws MarshalException;
}
public interface ExtensionsIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.Extensions";
}
public interface ExtensionIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.Extension";
}
public interface GeneralNameIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.GeneralName";
int uniformResourceIdentifier();
}
public interface GeneralNamesIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.GeneralNames";
}
public interface InitIf extends ProxyIf {
String delegateClass = "com.sun.org.apache.xml.internal.security.Init";
void init();
}
public interface JcaDigestCalculatorProviderBuilderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder";
JcaDigestCalculatorProviderBuilderIf setProvider(String provider);
DigestCalculatorProviderIf build();
}
public interface JcaContentSignerBuilderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.jcajce.JcaContentSignerBuilder";
JcaContentSignerBuilderIf setProvider(String provider);
ContentSignerIf build(PrivateKey paramPrivateKey);
}
public interface ContentSignerIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.ContentSigner";
}
public interface DigestCalculatorProviderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.DigestCalculatorProvider";
DigestCalculatorIf get(AlgorithmIdentifierIf paramAlgorithmIdentifier);
}
public interface DigestCalculatorIf extends ProxyIf {
String delegateClass = "org.bouncycastle.operator.DigestCalculator";
}
public interface AlgorithmIdentifierIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.AlgorithmIdentifier";
}
public interface KeyUsageIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.KeyUsage";
int digitalSignature();
}
public interface OCSPObjectIdentifiersIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers";
ASN1ObjectIdentifierIf id_pkix_ocsp_nonce();
}
public interface OCSPRespIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.OCSPResp";
BasicOCSPRespIf getResponseObject();
byte[] getEncoded() throws IOException;
}
public interface PKIFailureInfoIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.cmp.PKIFailureInfo";
int intValue();
}
public interface RespIDIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.RespID";
ResponderIDIf toASN1Object();
}
public interface ResponderIDIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.ocsp.ResponderID";
DERTaggedObjectIf toASN1Object();
}
public interface SignerIdIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cms.SignerId";
BigInteger getSerialNumber();
X500Principal getIssuer();
}
public interface SignerInformationVerifierIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cms.SignerInformationVerifier";
}
public interface StoreIf extends ProxyIf {
String delegateClass = "org.bouncycastle.util.Store";
Collection<Certificate> getMatches(Object selector) throws Exception;
}
public interface SubjectKeyIdentifierIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.SubjectKeyIdentifier";
byte[] getKeyIdentifier();
}
public interface SubjectPublicKeyInfoIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.SubjectPublicKeyInfo";
}
public interface TimeStampRequestGeneratorIf extends ProxyIf {
String delegateClass = "org.bouncycastle.tsp.TimeStampRequestGenerator";
void setCertReq(boolean certReq);
void setReqPolicy(String reqPolicy);
TimeStampRequestIf generate(String igestAlgorithmOID, byte[] digest, BigInteger nonce);
}
public interface TimeStampRequestIf extends ProxyIf {
String delegateClass = "org.bouncycastle.tsp.TimeStampRequest";
byte[] getEncoded() throws IOException;
}
public interface TimeStampResponseIf extends ProxyIf {
String delegateClass = "org.bouncycastle.tsp.TimeStampResponse";
void validate(TimeStampRequestIf request) throws Exception;
int getStatus();
String getStatusString();
PKIFailureInfoIf getFailInfo();
TimeStampTokenIf getTimeStampToken();
}
public interface TimeStampTokenIf extends ProxyIf {
String delegateClass = "org.bouncycastle.tsp.TimeStampToken";
SignerIdIf getSID();
StoreIf getCertificates();
StoreIf getCRLs();
TimeStampTokenInfoIf getTimeStampInfo();
byte[] getEncoded() throws IOException;
void validate(SignerInformationVerifierIf verifier) throws Exception;
}
public interface TimeStampTokenInfoIf extends ProxyIf {
String delegateClass = "org.bouncycastle.tsp.TimeStampTokenInfo";
Date getGenTime();
}
public interface X509CertificateHolderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.X509CertificateHolder";
}
public interface X509NameIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.X509Name";
String toString$delegate();
}
public interface X509PrincipalIf extends ProxyIf {
String delegateClass = "org.bouncycastle.jce.X509Principal";
String getName();
}
public interface X509V3CertificateGeneratorIf extends ProxyIf {
String delegateClass = "org.bouncycastle.x509.X509V3CertificateGenerator";
void reset();
void setPublicKey(PublicKey key);
void setSignatureAlgorithm(String signatureAlgorithm);
void setNotBefore(Date date);
void setNotAfter(Date date);
void setIssuerDN(X509PrincipalIf issuerDN);
void setSubjectDN(X509PrincipalIf issuerDN);
void setSerialNumber(BigInteger serialNumber);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, SubjectKeyIdentifierIf value);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, AuthorityKeyIdentifierIf value);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, BasicConstraintsIf value);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, DERSequenceIf value);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, AuthorityInformationAccessIf value);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, KeyUsageIf value);
X509Certificate generate(PrivateKey issuerPrivateKey);
}
public interface OCSPReqIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.OCSPReq";
ReqIf[] getRequestList();
}
public interface OCSPReqBuilderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.OCSPReqBuilder";
OCSPReqBuilderIf addRequest(CertificateIDIf certId);
OCSPReqBuilderIf setRequestExtensions(ExtensionsIf paramExtensions);
OCSPReqIf build();
}
public interface OCSPRespBuilderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.OCSPRespBuilder";
OCSPRespIf build(int status, BasicOCSPRespIf basicOcspResp);
int SUCCESSFUL();
}
public interface BasicOCSPRespBuilderIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder";
BasicOCSPRespBuilderIf addResponse(CertificateIDIf certificateID, CertificateStatusIf certificateStatus);
BasicOCSPRespBuilderIf setResponseExtensions(ExtensionsIf paramExtensions);
BasicOCSPRespIf build(ContentSignerIf paramContentSigner, X509CertificateHolderIf[] paramArrayOfX509CertificateHolder, Date paramDate);
}
public interface CertificateIDIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.CertificateID";
AlgorithmIdentifierIf HASH_SHA1();
}
public interface X509ExtensionsIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.X509Extensions";
ASN1ObjectIdentifierIf AuthorityKeyIdentifier();
ASN1ObjectIdentifierIf SubjectKeyIdentifier();
ASN1ObjectIdentifierIf BasicConstraints();
ASN1ObjectIdentifierIf CRLDistributionPoints();
ASN1ObjectIdentifierIf AuthorityInfoAccess();
ASN1ObjectIdentifierIf KeyUsage();
ASN1ObjectIdentifierIf CRLNumber();
}
public interface X509ObjectIdentifiersIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.X509ObjectIdentifiers";
ASN1ObjectIdentifierIf ocspAccessMethod();
}
public interface X509V2CRLGeneratorIf extends ProxyIf {
String delegateClass = "org.bouncycastle.x509.X509V2CRLGenerator";
void setIssuerDN(X500Principal issuerDN);
void setThisUpdate(Date date);
void setNextUpdate(Date date);
void setSignatureAlgorithm(String algorithm);
void addExtension(ASN1ObjectIdentifierIf oid, boolean critical, CRLNumberIf value);
X509CRL generate(PrivateKey privateKey);
}
public interface ReqIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.Req";
CertificateIDIf getCertID();
}
public interface CertificateStatusIf extends ProxyIf {
String delegateClass = "org.bouncycastle.cert.ocsp.CertificateStatus";
CertificateStatusIf GOOD();
}
public interface RevokedStatusIf extends ProxyIf {
String delegateClass = "org.bouncycastle.ocsp.RevokedStatus";
}
public interface CRLReasonIf extends ProxyIf {
String delegateClass = "org.bouncycastle.asn1.x509.CRLReason";
int unspecified();
int privilegeWithdrawn();
}
}

View File

@ -1,264 +0,0 @@
package org.apache.poi.poifs.crypt.dsig;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import org.apache.poi.util.MethodUtils;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
public class HorribleProxy implements InvocationHandler {
private static final POILogger LOG = POILogFactory.getLogger(HorribleProxy.class);
protected static interface ProxyIf {
Object getDelegate();
void setInitDeferred(boolean initDeferred);
};
private final Class<?> delegateClass;
private Object delegateRef;
private boolean initDeferred = true;
protected HorribleProxy(Class<?> delegateClass, Object delegateRef) {
this.delegateClass = delegateClass;
// delegateRef can be null, then we have to deal with deferred initialisation
this.delegateRef = delegateRef;
initDeferred = (delegateRef == null);
}
/**
* Create new instance by constructor
*
* @param proxyClass
* @param initargs
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public static <T extends ProxyIf> T newProxy(Class<T> proxyClass, Object ... initargs)
throws InvocationTargetException, IllegalAccessException, InstantiationException
, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> delegateClass = getDelegateClass(proxyClass);
Object delegateRef;
if (initargs.length == 0) {
delegateRef = null;
} else if (initargs.length == 1 && delegateClass.isAssignableFrom(initargs[0].getClass())) {
delegateRef = initargs[0];
} else {
Class<?> paramTypes[] = updateMethodArgs(null, initargs);
Constructor<?> cons = null;
try {
cons = delegateClass.getConstructor(paramTypes);
} catch (Exception e) {
// fallback - find constructor with same amount of parameters
// horrible et al. ...
cons = MethodUtils.getMatchingAccessibleConstructor(delegateClass, paramTypes);
if (cons == null) {
throw new RuntimeException("There's no constructor for the given arguments.");
}
}
delegateRef = cons.newInstance(initargs);
}
HorribleProxy hp = new HorribleProxy(delegateClass, delegateRef);
return (T)Proxy.newProxyInstance(cl, new Class<?>[]{proxyClass}, hp);
}
/**
* Create new instance by factory method
*
* @param proxyClass
* @param factoryMethod
* @param initargs
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public static <T extends ProxyIf> T createProxy(Class<T> proxyClass, String factoryMethod, Object ... initargs)
throws InvocationTargetException, IllegalAccessException, InstantiationException
, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> delegateClass = getDelegateClass(proxyClass);
Class<?> paramTypes[] = updateMethodArgs(null, initargs);
Method facMethod = delegateClass.getMethod(factoryMethod, paramTypes);
Object delegateRef = facMethod.invoke(null, initargs);
if (delegateRef == null) {
return null;
}
HorribleProxy hp = new HorribleProxy(delegateClass, delegateRef);
return (T)Proxy.newProxyInstance(cl, new Class<?>[]{proxyClass}, hp);
}
@SuppressWarnings("unchecked")
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Exception {
String methodName = method.getName().replaceFirst("\\$.*", "");
if (Object.class == method.getDeclaringClass()) {
if ("equals".equals(methodName)) {
return proxy == args[0];
} else if ("hashCode".equals(methodName)) {
return System.identityHashCode(proxy);
} else if ("toString".equals(methodName)) {
return proxy.getClass().getName() + "@"
+ Integer.toHexString(System.identityHashCode(proxy))
+ ", with InvocationHandler " + this;
} else {
throw new IllegalStateException(String.valueOf(method));
}
}
if ("getDelegate".equals(methodName)) {
initDeferred();
return delegateRef;
} else if ("setInitDeferred".equals(methodName)) {
initDeferred = (Boolean)args[0];
return null;
}
Class<?> methodParams[] = updateMethodArgs(method.getParameterTypes(), args);
Object ret = null;
boolean isStaticField = false;
if (methodParams.length == 0) {
// check for static fields first
try {
Field f = delegateClass.getDeclaredField(methodName);
ret = f.get(delegateRef);
if (ret == null) return null;
isStaticField = true;
} catch (NoSuchFieldException e) {
LOG.log(POILogger.DEBUG, "No static field '"+methodName+"' in class '"+delegateClass.getCanonicalName()+"' - trying method now.");
}
}
if (!isStaticField) {
Method methodImpl = null;
try {
methodImpl = delegateClass.getMethod(methodName, methodParams);
} catch (Exception e) {
// fallback - if methodName is distinct, try to use it
// in case we can't provide method declaration in the Proxy interface
// ... and of course, this is horrible ...
methodImpl = MethodUtils.getMatchingAccessibleMethod(delegateClass, methodName, methodParams);
if (methodImpl == null) {
throw new RuntimeException("There's no method '"+methodName+"' for the given arguments.");
}
}
if (!Modifier.isStatic(methodImpl.getModifiers())) {
initDeferred();
}
ret = methodImpl.invoke(delegateRef, args);
}
Class<?> retType = method.getReturnType();
if (retType.isArray()) {
if (ProxyIf.class.isAssignableFrom(retType.getComponentType())) {
Class<? extends ProxyIf> cType = (Class<? extends ProxyIf>)retType.getComponentType();
ProxyIf paRet[] = (ProxyIf[])Array.newInstance(cType, ((Object[])ret).length);
for (int i=0; i<((Object[])ret).length; i++) {
paRet[i] = newProxy(cType, ((Object[])ret)[i]);
paRet[i].setInitDeferred(false);
}
ret = paRet;
}
} else if (ProxyIf.class.isAssignableFrom(retType)) {
ProxyIf pRet = newProxy((Class<? extends ProxyIf>)retType, ret);
pRet.setInitDeferred(false);
ret = pRet;
}
return ret;
}
@SuppressWarnings("unchecked")
private static Class<?>[] updateMethodArgs(Class<?> types[], Object args[])
throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
if (args == null) return new Class<?>[0];
if (types == null) types = new Class<?>[args.length];
if (types.length != args.length) {
throw new IllegalArgumentException();
}
for (int i=0; i<types.length; i++) {
if (types[i] == null) {
if (args[i] == null) {
throw new IllegalArgumentException();
}
types[i] = args[i].getClass();
}
if (types[i].isArray()) {
// TODO: check for null arguments ...
if (ProxyIf.class.isAssignableFrom(types[i].getComponentType())) {
ProxyIf pifs[] = (ProxyIf[])args[i];
Class<?> dc = getDelegateClass((Class<? extends ProxyIf>)types[i].getComponentType());
int dcArrSize = (pifs==null ? 0 : pifs.length);
Object[] dcArr = (Object[])Array.newInstance(dc, dcArrSize);
for (int j=0;j<dcArrSize;j++) {
dcArr[j] = pifs[j].getDelegate();
}
args[i] = dcArr;
types[i] = dcArr.getClass();
}
} else if (ProxyIf.class.isAssignableFrom(types[i])) {
types[i] = getDelegateClass((Class<? extends ProxyIf>)types[i]);
if (args[i] != null) {
args[i] = ((ProxyIf)args[i]).getDelegate();
}
}
}
return types;
}
private void initDeferred() throws Exception {
if (delegateRef != null || !initDeferred) return;
// currently works only for empty constructor
delegateRef = delegateClass.getConstructor().newInstance();
}
private static Class<?> getDelegateClass(Class<? extends ProxyIf> proxyClass)
throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
Field delegateField;
try {
delegateField = proxyClass.getDeclaredField("delegateClass");
} catch (NoSuchFieldException e) {
// sometimes a proxy interface is returned as proxyClass
// this has to be asked for the real ProxyIf interface
Class<?> ifs[] = proxyClass.getInterfaces();
if (ifs == null || ifs.length != 1) {
throw new IllegalArgumentException();
}
delegateField = ifs[0].getDeclaredField("delegateClass");
}
String delegateClassName = (String)delegateField.get(null);
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> delegateClass = Class.forName(delegateClassName, true, cl);
return delegateClass;
}
}

View File

@ -26,21 +26,22 @@ package org.apache.poi.poifs.crypt.dsig;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.security.Key;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider; import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.XMLSignature; import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext; import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@ -53,19 +54,24 @@ import org.apache.poi.poifs.crypt.ChainingMode;
import org.apache.poi.poifs.crypt.CipherAlgorithm; import org.apache.poi.poifs.crypt.CipherAlgorithm;
import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.InitIf;
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService; import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService; import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo; import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.SAXHelper; import org.apache.poi.util.SAXHelper;
import org.apache.xml.security.Init;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class SignatureInfo { public class SignatureInfo {
public static final String XmlNS = "http://www.w3.org/2000/xmlns/";
public static final String XmlDSigNS = XMLSignature.XMLNS;
public static final byte[] SHA1_DIGEST_INFO_PREFIX = new byte[] public static final byte[] SHA1_DIGEST_INFO_PREFIX = new byte[]
{ 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14 }; { 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14 };
@ -108,31 +114,33 @@ public class SignatureInfo {
public boolean verifySignature() { public boolean verifySignature() {
initXmlProvider(); initXmlProvider();
// http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html // http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html
List<X509Certificate> signers = new LinkedList<X509Certificate>(); List<X509Certificate> signers = new ArrayList<X509Certificate>();
return getSignersAndValidate(signers, true); return getSignersAndValidate(signers, true);
} }
public void confirmSignature(Key key, X509Certificate x509) public void confirmSignature(PrivateKey key, X509Certificate x509)
throws NoSuchAlgorithmException, IOException { throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException {
confirmSignature(key, x509, HashAlgorithm.sha1); confirmSignature(key, x509, HashAlgorithm.sha1);
} }
public void confirmSignature(Key key, X509Certificate x509, HashAlgorithm hashAlgo) public void confirmSignature(PrivateKey key, X509Certificate x509, HashAlgorithm hashAlgo)
throws NoSuchAlgorithmException, IOException { throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException {
XmlSignatureService signatureService = createSignatureService(hashAlgo, pkg); XmlSignatureService signatureService = createSignatureService(hashAlgo, pkg);
Document document = SAXHelper.getDocumentBuilder().newDocument();
// operate // operate
List<X509Certificate> x509Chain = Collections.singletonList(x509); List<X509Certificate> x509Chain = Collections.singletonList(x509);
DigestInfo digestInfo = signatureService.preSign(null, x509Chain, null, null, null); DigestInfo digestInfo = signatureService.preSign(document, null, key, x509Chain, null, null, null);
// setup: key material, signature value // setup: key material, signature value
byte[] signatureValue = signDigest(key, hashAlgo, digestInfo.digestValue); byte[] signatureValue = signDigest(key, hashAlgo, digestInfo.digestValue);
// operate: postSign // operate: postSign
signatureService.postSign(signatureValue, Collections.singletonList(x509)); signatureService.postSign(document, signatureValue, Collections.singletonList(x509));
} }
public static byte[] signDigest(Key key, HashAlgorithm hashAlgo, byte digest[]) { public static byte[] signDigest(PrivateKey key, HashAlgorithm hashAlgo, byte digest[]) {
Cipher cipher = CryptoFunctions.getCipher(key, CipherAlgorithm.rsa Cipher cipher = CryptoFunctions.getCipher(key, CipherAlgorithm.rsa
, ChainingMode.ecb, null, Cipher.ENCRYPT_MODE, "PKCS1Padding"); , ChainingMode.ecb, null, Cipher.ENCRYPT_MODE, "PKCS1Padding");
@ -156,7 +164,7 @@ public class SignatureInfo {
public List<X509Certificate> getSigners() { public List<X509Certificate> getSigners() {
initXmlProvider(); initXmlProvider();
List<X509Certificate> signers = new LinkedList<X509Certificate>(); List<X509Certificate> signers = new ArrayList<X509Certificate>();
getSignersAndValidate(signers, false); getSignersAndValidate(signers, false);
return signers; return signers;
} }
@ -201,7 +209,7 @@ public class SignatureInfo {
} }
protected List<PackagePart> getSignatureParts(boolean onlyFirst) { protected List<PackagePart> getSignatureParts(boolean onlyFirst) {
List<PackagePart> packageParts = new LinkedList<PackagePart>(); List<PackagePart> packageParts = new ArrayList<PackagePart>();
PackageRelationshipCollection sigOrigRels = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN); PackageRelationshipCollection sigOrigRels = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
for (PackageRelationship rel : sigOrigRels) { for (PackageRelationship rel : sigOrigRels) {
@ -227,17 +235,32 @@ public class SignatureInfo {
} }
public static XMLSignatureFactory getSignatureFactory() { public static XMLSignatureFactory getSignatureFactory() {
Provider p = Security.getProvider("XMLDSig"); return XMLSignatureFactory.getInstance("DOM", getProvider());
assert(p != null);
return XMLSignatureFactory.getInstance("DOM", p);
} }
public static KeyInfoFactory getKeyInfoFactory() { public static KeyInfoFactory getKeyInfoFactory() {
Provider p = Security.getProvider("XMLDSig"); return KeyInfoFactory.getInstance("DOM", getProvider());
assert(p != null);
return KeyInfoFactory.getInstance("DOM", p);
} }
// currently classes are linked to Apache Santuario, so this might be superfluous
public static Provider getProvider() {
String dsigProviderNames[] = {
System.getProperty("jsr105Provider"),
"org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI", // Santuario xmlsec
"org.jcp.xml.dsig.internal.dom.XMLDSigRI" // JDK xmlsec
};
for (String pn : dsigProviderNames) {
if (pn == null) continue;
try {
return (Provider)Class.forName(pn).newInstance();
} catch (Exception e) {
LOG.log(POILogger.DEBUG, "XMLDsig-Provider '"+pn+"' can't be found - trying next.");
}
}
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
}
public static void insertXChild(XmlObject root, XmlObject child) { public static void insertXChild(XmlObject root, XmlObject child) {
XmlCursor rootCursor = root.newCursor(); XmlCursor rootCursor = root.newCursor();
insertXChild(rootCursor, child); insertXChild(rootCursor, child);
@ -252,12 +275,22 @@ public class SignatureInfo {
childCursor.dispose(); childCursor.dispose();
} }
public static void setPrefix(XmlObject xobj, String ns, String prefix) { // public static void setPrefix(XmlObject xobj, String ns, String prefix) {
for (XmlCursor cur = xobj.newCursor(); cur.hasNextToken(); cur.toNextToken()) { // XmlCursor cur;
if (cur.isStart()) { // for (cur = xobj.newCursor(); cur.hasNextToken(); cur.toNextToken()) {
Element el = (Element)cur.getDomNode(); // if (cur.isStart()) {
if (ns.equals(el.getNamespaceURI())) el.setPrefix(prefix); // Element el = (Element)cur.getDomNode();
} // if (ns.equals(el.getNamespaceURI())) el.setPrefix(prefix);
// }
// }
// cur.dispose();
// }
public static void setPrefix(Node el, String ns, String prefix) {
if (ns.equals(el.getNamespaceURI())) el.setPrefix(prefix);
NodeList nl = el.getChildNodes();
for (int i=0; i<nl.getLength(); i++) {
setPrefix(nl.item(i), ns, prefix);
} }
} }
@ -280,18 +313,9 @@ public class SignatureInfo {
isInitialized = true; isInitialized = true;
try { try {
InitIf init = HorribleProxy.newProxy(InitIf.class); Init.init();
init.init();
RelationshipTransformService.registerDsigProvider(); RelationshipTransformService.registerDsigProvider();
CryptoFunctions.registerBouncyCastle();
Provider bcProv = Security.getProvider("BC");
if (bcProv == null) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> c = cl.loadClass("org.bouncycastle.jce.provider.BouncyCastleProvider");
bcProv = (Provider)c.newInstance();
Security.addProvider(bcProv);
}
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Xml & BouncyCastle-Provider initialization failed", e); throw new RuntimeException("Xml & BouncyCastle-Provider initialization failed", e);
} }

View File

@ -16,25 +16,18 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.poifs.crypt; package org.apache.poi.poifs.crypt;
import static org.apache.poi.poifs.crypt.dsig.HorribleProxy.newProxy;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.CRLException; import java.security.cert.CRLException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.RSAKeyGenParameterSpec;
@ -52,45 +45,49 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1InputStreamIf; import org.bouncycastle.asn1.ASN1InputStream;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.AuthorityInformationAccessIf; import org.bouncycastle.asn1.ASN1Sequence;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.AuthorityKeyIdentifierIf; import org.bouncycastle.asn1.DERIA5String;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicConstraintsIf; import org.bouncycastle.asn1.DEROctetString;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicOCSPRespBuilderIf; import org.bouncycastle.asn1.DERSequence;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicOCSPRespIf; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CRLNumberIf; import org.bouncycastle.asn1.x500.X500Name;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CRLReasonIf; import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CertificateIDIf; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CertificateStatusIf; import org.bouncycastle.asn1.x509.BasicConstraints;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ContentSignerIf; import org.bouncycastle.asn1.x509.CRLNumber;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DERIA5StringIf; import org.bouncycastle.asn1.x509.CRLReason;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DEROctetStringIf; import org.bouncycastle.asn1.x509.DistributionPoint;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DERSequenceIf; import org.bouncycastle.asn1.x509.DistributionPointName;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DigestCalculatorIf; import org.bouncycastle.asn1.x509.Extension;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DistributionPointIf; import org.bouncycastle.asn1.x509.Extensions;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DistributionPointNameIf; import org.bouncycastle.asn1.x509.GeneralName;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ExtensionIf; import org.bouncycastle.asn1.x509.GeneralNames;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ExtensionsIf; import org.bouncycastle.asn1.x509.KeyUsage;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.GeneralNameIf; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.GeneralNamesIf; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.JcaContentSignerBuilderIf; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.JcaDigestCalculatorProviderBuilderIf; import org.bouncycastle.cert.X509CRLHolder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.KeyUsageIf; import org.bouncycastle.cert.X509CertificateHolder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPObjectIdentifiersIf; import org.bouncycastle.cert.X509v2CRLBuilder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPReqBuilderIf; import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPReqIf; import org.bouncycastle.cert.jcajce.JcaX509CRLConverter;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespBuilderIf; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespIf; import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ReqIf; import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.RevokedStatusIf; import org.bouncycastle.cert.ocsp.CertificateID;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SubjectKeyIdentifierIf; import org.bouncycastle.cert.ocsp.CertificateStatus;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SubjectPublicKeyInfoIf; import org.bouncycastle.cert.ocsp.OCSPReq;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509CertificateHolderIf; import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509ExtensionsIf; import org.bouncycastle.cert.ocsp.OCSPResp;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509ObjectIdentifiersIf; import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509PrincipalIf; import org.bouncycastle.cert.ocsp.Req;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509V2CRLGeneratorIf; import org.bouncycastle.cert.ocsp.RevokedStatus;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509V3CertificateGeneratorIf; import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@ -111,27 +108,21 @@ public class PkiTestUtils {
return keyPair; return keyPair;
} }
private static SubjectKeyIdentifierIf createSubjectKeyId(PublicKey publicKey) @SuppressWarnings("resource")
throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException private static SubjectKeyIdentifier createSubjectKeyId(PublicKey publicKey)
, IllegalAccessException, InvocationTargetException, NoSuchFieldException { throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(publicKey.getEncoded()); ASN1InputStream asnObj = new ASN1InputStream(publicKey.getEncoded());
ASN1InputStreamIf asnObj = newProxy(ASN1InputStreamIf.class, bais); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(asnObj.readObject());
SubjectPublicKeyInfoIf info = SubjectKeyIdentifier keyId = SubjectKeyIdentifier.getInstance(info.getEncoded());
newProxy(SubjectPublicKeyInfoIf.class, asnObj.readObject$Sequence());
SubjectKeyIdentifierIf keyId = newProxy(SubjectKeyIdentifierIf.class, info);
return keyId; return keyId;
} }
private static AuthorityKeyIdentifierIf createAuthorityKeyId(PublicKey publicKey) @SuppressWarnings("resource")
throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey publicKey)
, IllegalAccessException, InvocationTargetException, NoSuchFieldException { throws IOException {
ASN1InputStream asnObj = new ASN1InputStream(publicKey.getEncoded());
ByteArrayInputStream bais = new ByteArrayInputStream(publicKey.getEncoded()); SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(asnObj.readObject());
ASN1InputStreamIf asnObj = newProxy(ASN1InputStreamIf.class, bais); AuthorityKeyIdentifier keyId = AuthorityKeyIdentifier.getInstance(info);
SubjectPublicKeyInfoIf info =
newProxy(SubjectPublicKeyInfoIf.class, asnObj.readObject$Sequence());
AuthorityKeyIdentifierIf keyId = newProxy(AuthorityKeyIdentifierIf.class, info);
return keyId; return keyId;
} }
@ -139,88 +130,76 @@ public class PkiTestUtils {
String subjectDn, Date notBefore, Date notAfter, String subjectDn, Date notBefore, Date notAfter,
X509Certificate issuerCertificate, PrivateKey issuerPrivateKey, X509Certificate issuerCertificate, PrivateKey issuerPrivateKey,
boolean caFlag, int pathLength, String crlUri, String ocspUri, boolean caFlag, int pathLength, String crlUri, String ocspUri,
KeyUsageIf keyUsage) KeyUsage keyUsage)
throws IOException, InvalidKeyException, IllegalStateException, NoSuchAlgorithmException throws IOException, OperatorCreationException, CertificateException
, SignatureException, CertificateException, InvocationTargetException, IllegalAccessException
, InstantiationException, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException
{ {
String signatureAlgorithm = "SHA1withRSA"; String signatureAlgorithm = "SHA1withRSA";
X509V3CertificateGeneratorIf certificateGenerator = newProxy(X509V3CertificateGeneratorIf.class); X500Name issuerName;
certificateGenerator.reset(); if (issuerCertificate != null) {
certificateGenerator.setPublicKey(subjectPublicKey); issuerName = new X509CertificateHolder(issuerCertificate.getEncoded()).getIssuer();
certificateGenerator.setSignatureAlgorithm(signatureAlgorithm);
certificateGenerator.setNotBefore(notBefore);
certificateGenerator.setNotAfter(notAfter);
X509PrincipalIf subjectDN = newProxy(X509PrincipalIf.class, subjectDn);
X509PrincipalIf issuerDN;
if (null != issuerCertificate) {
issuerDN = newProxy(X509PrincipalIf.class, issuerCertificate
.getSubjectX500Principal().toString());
} else { } else {
issuerDN = subjectDN; issuerName = new X500Name(subjectDn);
} }
certificateGenerator.setIssuerDN(issuerDN);
certificateGenerator.setSubjectDN(subjectDN);
certificateGenerator.setSerialNumber(new BigInteger(128,
new SecureRandom()));
X509ExtensionsIf X509Extensions = newProxy(X509ExtensionsIf.class); SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(
ASN1Sequence.getInstance(subjectPublicKey.getEncoded()));
certificateGenerator.addExtension(X509Extensions.SubjectKeyIdentifier(), X509v3CertificateBuilder certificateGenerator = new X509v3CertificateBuilder(
false, createSubjectKeyId(subjectPublicKey)); issuerName
PublicKey issuerPublicKey; , new BigInteger(128, new SecureRandom())
issuerPublicKey = subjectPublicKey; , notBefore
certificateGenerator.addExtension( , notAfter
X509Extensions.AuthorityKeyIdentifier(), false, , new X500Name(subjectDn)
createAuthorityKeyId(issuerPublicKey)); , subjectPublicKeyInfo
);
certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyId(subjectPublicKey));
certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, createAuthorityKeyId(subjectPublicKey));
if (caFlag) { if (caFlag) {
BasicConstraintsIf bc; BasicConstraints bc;
if (-1 == pathLength) { if (-1 == pathLength) {
bc = newProxy(BasicConstraintsIf.class, true); bc = new BasicConstraints(true);
} else { } else {
bc = newProxy(BasicConstraintsIf.class, pathLength); bc = new BasicConstraints(pathLength);
} }
certificateGenerator.addExtension(X509Extensions.BasicConstraints(), false, bc); certificateGenerator.addExtension(Extension.basicConstraints, false, bc);
} }
if (null != crlUri) { if (null != crlUri) {
GeneralNameIf gn = newProxy(GeneralNameIf.class); int uri = GeneralName.uniformResourceIdentifier;
int uri = gn.uniformResourceIdentifier(); DERIA5String crlUriDer = new DERIA5String(crlUri);
DERIA5StringIf crlUriDer = newProxy(DERIA5StringIf.class, crlUri); GeneralName gn = new GeneralName(uri, crlUriDer);
gn = newProxy(GeneralNameIf.class, uri, crlUriDer);
DERSequenceIf gnDer = newProxy(DERSequenceIf.class, gn); DERSequence gnDer = new DERSequence(gn);
GeneralNamesIf gns = newProxy(GeneralNamesIf.class, gnDer); GeneralNames gns = GeneralNames.getInstance(gnDer);
DistributionPointNameIf dpn = newProxy(DistributionPointNameIf.class, 0, gns); DistributionPointName dpn = new DistributionPointName(0, gns);
DistributionPointIf distp = newProxy(DistributionPointIf.class, dpn, null, null); DistributionPoint distp = new DistributionPoint(dpn, null, null);
DERSequenceIf distpDer = newProxy(DERSequenceIf.class, distp); DERSequence distpDer = new DERSequence(distp);
certificateGenerator.addExtension(X509Extensions.CRLDistributionPoints(), false, distpDer); certificateGenerator.addExtension(Extension.cRLDistributionPoints, false, distpDer);
} }
if (null != ocspUri) { if (null != ocspUri) {
GeneralNameIf ocspName = newProxy(GeneralNameIf.class); int uri = GeneralName.uniformResourceIdentifier;
int uri = ocspName.uniformResourceIdentifier(); GeneralName ocspName = new GeneralName(uri, ocspUri);
ocspName = newProxy(GeneralNameIf.class, uri, ocspUri);
X509ObjectIdentifiersIf X509ObjectIdentifiers = newProxy(X509ObjectIdentifiersIf.class); AuthorityInformationAccess authorityInformationAccess =
AuthorityInformationAccessIf authorityInformationAccess = new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspName);
newProxy(AuthorityInformationAccessIf.class
, X509ObjectIdentifiers.ocspAccessMethod(), ocspName);
certificateGenerator.addExtension( certificateGenerator.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess);
X509Extensions.AuthorityInfoAccess(), false,
authorityInformationAccess);
} }
if (null != keyUsage) { if (null != keyUsage) {
certificateGenerator.addExtension(X509Extensions.KeyUsage(), true, keyUsage); certificateGenerator.addExtension(Extension.keyUsage, true, keyUsage);
} }
X509Certificate certificate; JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm);
certificate = certificateGenerator.generate(issuerPrivateKey); signerBuilder.setProvider("BC");
X509CertificateHolder certHolder =
certificateGenerator.build(signerBuilder.build(issuerPrivateKey));
/* /*
* Next certificate factory trick is needed to make sure that the * Next certificate factory trick is needed to make sure that the
@ -228,12 +207,11 @@ public class PkiTestUtils {
* security provider instead of BouncyCastle. If we don't do this trick * security provider instead of BouncyCastle. If we don't do this trick
* we might run into trouble when trying to use the CertPath validator. * we might run into trouble when trying to use the CertPath validator.
*/ */
CertificateFactory certificateFactory = CertificateFactory // CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
.getInstance("X.509"); // certificate = (X509Certificate) certificateFactory
certificate = (X509Certificate) certificateFactory // .generateCertificate(new ByteArrayInputStream(certificate
.generateCertificate(new ByteArrayInputStream(certificate // .getEncoded()));
.getEncoded())); return new JcaX509CertificateConverter().getCertificate(certHolder);
return certificate;
} }
static Document loadDocument(InputStream documentInputStream) static Document loadDocument(InputStream documentInputStream)
@ -264,93 +242,79 @@ public class PkiTestUtils {
return stringWriter.getBuffer().toString(); return stringWriter.getBuffer().toString();
} }
public static X509CRL generateCrl(X509Certificate issuer, public static X509CRL generateCrl(X509Certificate issuer, PrivateKey issuerPrivateKey)
PrivateKey issuerPrivateKey) throws InvalidKeyException, throws CertificateEncodingException, IOException, CRLException, OperatorCreationException {
CRLException, IllegalStateException, NoSuchAlgorithmException,
SignatureException, InvocationTargetException, IllegalAccessException,
InstantiationException, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException {
X509V2CRLGeneratorIf crlGenerator = newProxy(X509V2CRLGeneratorIf.class);
crlGenerator.setIssuerDN(issuer.getSubjectX500Principal());
Date now = new Date();
crlGenerator.setThisUpdate(now);
crlGenerator.setNextUpdate(new Date(now.getTime() + 100000));
crlGenerator.setSignatureAlgorithm("SHA1withRSA");
X509ExtensionsIf X509Extensions = newProxy(X509ExtensionsIf.class);
CRLNumberIf crlNumber = newProxy(CRLNumberIf.class, new BigInteger("1234"));
crlGenerator.addExtension(X509Extensions.CRLNumber(), false, crlNumber); X509CertificateHolder holder = new X509CertificateHolder(issuer.getEncoded());
X509CRL x509Crl = crlGenerator.generate(issuerPrivateKey); X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(holder.getIssuer(), new Date());
return x509Crl; crlBuilder.setNextUpdate(new Date(new Date().getTime() + 100000));
JcaContentSignerBuilder contentBuilder = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC");
CRLNumber crlNumber = new CRLNumber(new BigInteger("1234"));
crlBuilder.addExtension(Extension.cRLNumber, false, crlNumber);
X509CRLHolder x509Crl = crlBuilder.build(contentBuilder.build(issuerPrivateKey));
return new JcaX509CRLConverter().setProvider("BC").getCRL(x509Crl);
} }
public static OCSPRespIf createOcspResp(X509Certificate certificate, public static OCSPResp createOcspResp(X509Certificate certificate,
boolean revoked, X509Certificate issuerCertificate, boolean revoked, X509Certificate issuerCertificate,
X509Certificate ocspResponderCertificate, X509Certificate ocspResponderCertificate,
PrivateKey ocspResponderPrivateKey, String signatureAlgorithm, PrivateKey ocspResponderPrivateKey, String signatureAlgorithm,
long nonceTimeinMillis) long nonceTimeinMillis)
throws Exception { throws Exception {
CertificateIDIf certId = newProxy(CertificateIDIf.class); DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()
DigestCalculatorIf digestCalc = .setProvider("BC").build().get(CertificateID.HASH_SHA1);
newProxy(JcaDigestCalculatorProviderBuilderIf.class) X509CertificateHolder issuerHolder = new X509CertificateHolder(issuerCertificate.getEncoded());
.setProvider("BC").build().get(certId.HASH_SHA1()); CertificateID certId = new CertificateID(digestCalc, issuerHolder, certificate.getSerialNumber());
X509CertificateHolderIf issuerHolder = newProxy(X509CertificateHolderIf.class, issuerCertificate.getEncoded());
certId = newProxy(CertificateIDIf.class, digestCalc, issuerHolder, certificate.getSerialNumber());
// request // request
//create a nonce to avoid replay attack //create a nonce to avoid replay attack
BigInteger nonce = BigInteger.valueOf(nonceTimeinMillis); BigInteger nonce = BigInteger.valueOf(nonceTimeinMillis);
OCSPObjectIdentifiersIf oidIf = newProxy(OCSPObjectIdentifiersIf.class); DEROctetString nonceDer = new DEROctetString(nonce.toByteArray());
DEROctetStringIf nonceDer = newProxy(DEROctetStringIf.class, nonce.toByteArray()); Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, nonceDer);
ExtensionIf ext = newProxy(ExtensionIf.class, oidIf.id_pkix_ocsp_nonce(), true, nonceDer); Extensions exts = new Extensions(ext);
ExtensionsIf exts = newProxy(ExtensionsIf.class, ext);
OCSPReqBuilderIf ocspReqBuilder = newProxy(OCSPReqBuilderIf.class); OCSPReqBuilder ocspReqBuilder = new OCSPReqBuilder();
ocspReqBuilder.addRequest(certId); ocspReqBuilder.addRequest(certId);
ocspReqBuilder.setRequestExtensions(exts); ocspReqBuilder.setRequestExtensions(exts);
OCSPReqIf ocspReq = ocspReqBuilder.build(); OCSPReq ocspReq = ocspReqBuilder.build();
SubjectPublicKeyInfoIf keyInfo = newProxy(SubjectPublicKeyInfoIf.class SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo
, certId.HASH_SHA1(), ocspResponderCertificate.getPublicKey().getEncoded()); (CertificateID.HASH_SHA1, ocspResponderCertificate.getPublicKey().getEncoded());
BasicOCSPRespBuilderIf basicOCSPRespBuilder = BasicOCSPRespBuilder basicOCSPRespBuilder = new BasicOCSPRespBuilder(keyInfo, digestCalc);
newProxy(BasicOCSPRespBuilderIf.class, keyInfo, digestCalc);
basicOCSPRespBuilder.setResponseExtensions(exts); basicOCSPRespBuilder.setResponseExtensions(exts);
// request processing // request processing
ReqIf[] requestList = ocspReq.getRequestList(); Req[] requestList = ocspReq.getRequestList();
for (ReqIf ocspRequest : requestList) { for (Req ocspRequest : requestList) {
CertificateIDIf certificateID = ocspRequest.getCertID(); CertificateID certificateID = ocspRequest.getCertID();
CertificateStatusIf certificateStatus; CertificateStatus certificateStatus = CertificateStatus.GOOD;
if (revoked) { if (revoked) {
CRLReasonIf crlr = newProxy(CRLReasonIf.class); certificateStatus = new RevokedStatus(new Date(), CRLReason.privilegeWithdrawn);
RevokedStatusIf rs = newProxy(RevokedStatusIf.class, new Date(), crlr.privilegeWithdrawn());
certificateStatus = newProxy(CertificateStatusIf.class, rs.getDelegate());
} else {
CertificateStatusIf cs = newProxy(CertificateStatusIf.class);
certificateStatus = cs.GOOD();
} }
basicOCSPRespBuilder.addResponse(certificateID, certificateStatus); basicOCSPRespBuilder.addResponse(certificateID, certificateStatus);
} }
// basic response generation // basic response generation
X509CertificateHolderIf[] chain = null; X509CertificateHolder[] chain = null;
if (!ocspResponderCertificate.equals(issuerCertificate)) { if (!ocspResponderCertificate.equals(issuerCertificate)) {
// TODO: HorribleProxy can't convert array input params yet // TODO: HorribleProxy can't convert array input params yet
chain = new X509CertificateHolderIf[] { chain = new X509CertificateHolder[] {
newProxy(X509CertificateHolderIf.class, ocspResponderCertificate), new X509CertificateHolder(ocspResponderCertificate.getEncoded()),
issuerHolder issuerHolder
}; };
} }
ContentSignerIf contentSigner = newProxy(JcaContentSignerBuilderIf.class, "SHA1withRSA") ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA")
.setProvider("BC").build(ocspResponderPrivateKey); .setProvider("BC").build(ocspResponderPrivateKey);
BasicOCSPRespIf basicOCSPResp = basicOCSPRespBuilder.build(contentSigner, chain, new Date(nonceTimeinMillis)); BasicOCSPResp basicOCSPResp = basicOCSPRespBuilder.build(contentSigner, chain, new Date(nonceTimeinMillis));
OCSPRespBuilderIf ocspRespBuilder = newProxy(OCSPRespBuilderIf.class); OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder();
OCSPRespIf ocspResp = ocspRespBuilder.build(ocspRespBuilder.SUCCESSFUL(), basicOCSPResp); OCSPResp ocspResp = ocspRespBuilder.build(OCSPRespBuilder.SUCCESSFUL, basicOCSPResp);
return ocspResp; return ocspResp;
} }

View File

@ -52,13 +52,11 @@ import javax.xml.crypto.KeySelector;
import javax.xml.crypto.dsig.XMLSignature; import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext; import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.KeyUsageIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo; import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet; import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet; import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
@ -75,12 +73,17 @@ import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.SAXHelper;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.etsi.uri.x01903.v13.DigestAlgAndValueType; import org.etsi.uri.x01903.v13.DigestAlgAndValueType;
import org.etsi.uri.x01903.v13.QualifyingPropertiesType; import org.etsi.uri.x01903.v13.QualifyingPropertiesType;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.w3.x2000.x09.xmldsig.SignatureDocument; import org.w3.x2000.x09.xmldsig.SignatureDocument;
import org.w3c.dom.Document;
public class TestSignatureInfo { public class TestSignatureInfo {
private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class); private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class);
@ -199,7 +202,9 @@ public class TestSignatureInfo {
pkg.close(); pkg.close();
} }
@SuppressWarnings("unused")
@Test @Test
@Ignore
public void testSignEnvelopingDocument() throws Exception { public void testSignEnvelopingDocument() throws Exception {
String testFile = "hello-world-unsigned.xlsx"; String testFile = "hello-world-unsigned.xlsx";
OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
@ -213,28 +218,37 @@ public class TestSignatureInfo {
XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(null, null, signaturePolicyService); XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(null, null, signaturePolicyService);
final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate()); final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate());
// TimeStampService timeStampService = new TimeStampService(){
// public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception {
// revocationData.addCRL(crl);
// return "time-stamp-token".getBytes();
// }
// };
// http://timestamping.edelweb.fr/service/tsp // http://timestamping.edelweb.fr/service/tsp
// http://tsa.belgium.be/connect // http://tsa.belgium.be/connect
String tspServiceUrl = "http://timestamping.edelweb.fr/service/tsp"; String tspServiceUrl = "http://timestamping.edelweb.fr/service/tsp";
TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() {
@Override TimeStampService timeStampService;
public void validate(List<X509Certificate> certificateChain, if (tspServiceUrl == null) {
RevocationData revocationData) throws Exception { timeStampService = new TimeStampService(){
for (X509Certificate certificate : certificateChain) { public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception {
LOG.log(POILogger.DEBUG, "certificate: " + certificate.getSubjectX500Principal()); revocationData.addCRL(crl);
LOG.log(POILogger.DEBUG, "validity: " + certificate.getNotBefore() + " - " + certificate.getNotAfter()); return "time-stamp-token".getBytes();
} }
};
} else {
TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() {
@Override
public void validate(List<X509Certificate> certificateChain,
RevocationData revocationData) throws Exception {
for (X509Certificate certificate : certificateChain) {
LOG.log(POILogger.DEBUG, "certificate: " + certificate.getSubjectX500Principal());
LOG.log(POILogger.DEBUG, "validity: " + certificate.getNotBefore() + " - " + certificate.getNotAfter());
}
}
};
TSPTimeStampService tspService = new TSPTimeStampService(tspServiceUrl, tspValidator);
if (tspServiceUrl.contains("edelweb")) {
tspService.setRequestContentType("application/timestamp-request");
tspService.setResponseContentType("application/timestamp-response");
} }
}; timeStampService = tspService;
}
TimeStampService timeStampService = new TSPTimeStampService(tspServiceUrl, tspValidator);
List<X509Certificate> certificateChain = new ArrayList<X509Certificate>(); List<X509Certificate> certificateChain = new ArrayList<X509Certificate>();
/* /*
@ -246,7 +260,7 @@ public class TestSignatureInfo {
final RevocationData revocationData = new RevocationData(); final RevocationData revocationData = new RevocationData();
revocationData.addCRL(crl); revocationData.addCRL(crl);
OCSPRespIf ocspResp = PkiTestUtils.createOcspResp(x509, false, OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false,
x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis()); x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis());
revocationData.addOCSP(ocspResp.getEncoded()); revocationData.addOCSP(ocspResp.getEncoded());
@ -263,16 +277,19 @@ public class TestSignatureInfo {
xadesSignatureFacet, xadesXLSignatureFacet); xadesSignatureFacet, xadesXLSignatureFacet);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document document = dbf.newDocumentBuilder().newDocument();
// operate // operate
DigestInfo digestInfo = testedInstance.preSign(null, certificateChain, null, null, null); DigestInfo digestInfo = testedInstance.preSign(document, null, keyPair.getPrivate(), certificateChain, null, null, null);
// verify // verify
assertNotNull(digestInfo); assertNotNull(digestInfo);
assertEquals(HashAlgorithm.sha1, digestInfo.hashAlgo); assertEquals(HashAlgorithm.sha1, digestInfo.hashAlgo);
assertNotNull(digestInfo.digestValue); assertNotNull(digestInfo.digestValue);
SignatureDocument sigDoc = testedInstance.getSignatureDocument(); SignatureDocument sigDoc = SignatureDocument.Factory.parse(document);
String certDigestXQuery = String certDigestXQuery =
"declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; " "declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; "
+ "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; " + "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; "
@ -286,17 +303,18 @@ public class TestSignatureInfo {
byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue); byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue);
// Operate: postSign // Operate: postSign
testedInstance.postSign(signatureValue, certificateChain); testedInstance.postSign(document, signatureValue, certificateChain);
DOMValidateContext domValidateContext = new DOMValidateContext( DOMValidateContext domValidateContext = new DOMValidateContext(
KeySelector.singletonKeySelector(keyPair.getPublic()), KeySelector.singletonKeySelector(keyPair.getPublic()),
testedInstance.getSignatureDocument().getDomNode()); document);
XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory(); XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory();
XMLSignature xmlSignature = xmlSignatureFactory XMLSignature xmlSignature = xmlSignatureFactory
.unmarshalXMLSignature(domValidateContext); .unmarshalXMLSignature(domValidateContext);
boolean validity = xmlSignature.validate(domValidateContext); boolean validity = xmlSignature.validate(domValidateContext);
assertTrue(validity); assertTrue(validity);
sigDoc = SignatureDocument.Factory.parse(document);
xoList = sigDoc.selectPath(certDigestXQuery); xoList = sigDoc.selectPath(certDigestXQuery);
assertEquals(xoList.length, 1); assertEquals(xoList.length, 1);
certDigest = (DigestAlgAndValueType)xoList[0]; certDigest = (DigestAlgAndValueType)xoList[0];
@ -320,9 +338,11 @@ public class TestSignatureInfo {
signatureService.initFacets(cal.getTime()); signatureService.initFacets(cal.getTime());
initKeyPair(alias, signerDn); initKeyPair(alias, signerDn);
Document document = SAXHelper.getDocumentBuilder().newDocument();
// operate // operate
List<X509Certificate> x509Chain = Collections.singletonList(x509); List<X509Certificate> x509Chain = Collections.singletonList(x509);
DigestInfo digestInfo = signatureService.preSign(null, x509Chain, null, null, null); DigestInfo digestInfo = signatureService.preSign(document, null, keyPair.getPrivate(), x509Chain, null, null, null);
// verify // verify
assertNotNull(digestInfo); assertNotNull(digestInfo);
@ -336,7 +356,7 @@ public class TestSignatureInfo {
byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue); byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue);
// operate: postSign // operate: postSign
signatureService.postSign(signatureValue, Collections.singletonList(x509)); signatureService.postSign(document, signatureValue, Collections.singletonList(x509));
// verify: signature // verify: signature
SignatureInfo si = new SignatureInfo(pkgCopy); SignatureInfo si = new SignatureInfo(pkgCopy);
@ -370,8 +390,7 @@ public class TestSignatureInfo {
Date notBefore = cal.getTime(); Date notBefore = cal.getTime();
cal.add(Calendar.YEAR, 1); cal.add(Calendar.YEAR, 1);
Date notAfter = cal.getTime(); Date notAfter = cal.getTime();
KeyUsageIf keyUsage = HorribleProxy.newProxy(KeyUsageIf.class); KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature);
keyUsage = HorribleProxy.newProxy(KeyUsageIf.class, keyUsage.digitalSignature());
x509 = PkiTestUtils.generateCertificate(keyPair.getPublic(), subjectDN x509 = PkiTestUtils.generateCertificate(keyPair.getPublic(), subjectDN
, notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage); , notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage);