From d0cc2e4267caf951fe2cec059ba3c313703be1b5 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 24 Aug 2014 23:05:26 +0000 Subject: [PATCH] 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 --- .classpath | 4 + build.xml | 27 +- .../poi/poifs/crypt/dsig/HorribleProxies.java | 427 ------------------ .../poi/poifs/crypt/dsig/HorribleProxy.java | 264 ----------- .../poi/poifs/crypt/dsig/SignatureInfo.java | 100 ++-- .../apache/poi/poifs/crypt/PkiTestUtils.java | 318 ++++++------- .../poi/poifs/crypt/TestSignatureInfo.java | 77 ++-- 7 files changed, 275 insertions(+), 942 deletions(-) delete mode 100644 src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxies.java delete mode 100644 src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxy.java diff --git a/.classpath b/.classpath index 2445269b1..0a1d88f45 100644 --- a/.classpath +++ b/.classpath @@ -25,5 +25,9 @@ + + + + diff --git a/build.xml b/build.xml index a83ccaea6..8f27b57fe 100644 --- a/build.xml +++ b/build.xml @@ -61,6 +61,7 @@ under the License. + @@ -146,11 +147,15 @@ under the License. - - - - - + + + + + + + + + @@ -438,8 +443,16 @@ under the License. - - + + + + + + + + + + diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxies.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxies.java deleted file mode 100644 index 8a0ce9694..000000000 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxies.java +++ /dev/null @@ -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 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(); - } -} diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxy.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxy.java deleted file mode 100644 index d64b4ebc7..000000000 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/HorribleProxy.java +++ /dev/null @@ -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 newProxy(Class 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 createProxy(Class 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 cType = (Class)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)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 dc = getDelegateClass((Class)types[i].getComponentType()); - int dcArrSize = (pifs==null ? 0 : pifs.length); - Object[] dcArr = (Object[])Array.newInstance(dc, dcArrSize); - for (int j=0;j)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 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; - } -} diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java index 96ac896a6..e7eb140e1 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java @@ -26,21 +26,22 @@ package org.apache.poi.poifs.crypt.dsig; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.security.Key; import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; import java.security.Provider; -import java.security.Security; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.LinkedList; import java.util.List; import javax.crypto.Cipher; +import javax.xml.crypto.MarshalException; import javax.xml.crypto.dsig.XMLSignature; import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.dom.DOMValidateContext; import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; +import javax.xml.parsers.ParserConfigurationException; import org.apache.poi.EncryptedDocumentException; 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.CryptoFunctions; 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.XmlSignatureService; import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.util.SAXHelper; +import org.apache.xml.security.Init; import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.w3c.dom.Document; -import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; 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[] { 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14 }; @@ -108,31 +114,33 @@ public class SignatureInfo { public boolean verifySignature() { initXmlProvider(); // http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html - List signers = new LinkedList(); + List signers = new ArrayList(); return getSignersAndValidate(signers, true); } - public void confirmSignature(Key key, X509Certificate x509) - throws NoSuchAlgorithmException, IOException { + public void confirmSignature(PrivateKey key, X509Certificate x509) + throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException { confirmSignature(key, x509, HashAlgorithm.sha1); } - public void confirmSignature(Key key, X509Certificate x509, HashAlgorithm hashAlgo) - throws NoSuchAlgorithmException, IOException { + public void confirmSignature(PrivateKey key, X509Certificate x509, HashAlgorithm hashAlgo) + throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException { XmlSignatureService signatureService = createSignatureService(hashAlgo, pkg); + + Document document = SAXHelper.getDocumentBuilder().newDocument(); // operate List 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 byte[] signatureValue = signDigest(key, hashAlgo, digestInfo.digestValue); // 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 , ChainingMode.ecb, null, Cipher.ENCRYPT_MODE, "PKCS1Padding"); @@ -156,7 +164,7 @@ public class SignatureInfo { public List getSigners() { initXmlProvider(); - List signers = new LinkedList(); + List signers = new ArrayList(); getSignersAndValidate(signers, false); return signers; } @@ -201,7 +209,7 @@ public class SignatureInfo { } protected List getSignatureParts(boolean onlyFirst) { - List packageParts = new LinkedList(); + List packageParts = new ArrayList(); PackageRelationshipCollection sigOrigRels = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN); for (PackageRelationship rel : sigOrigRels) { @@ -227,17 +235,32 @@ public class SignatureInfo { } public static XMLSignatureFactory getSignatureFactory() { - Provider p = Security.getProvider("XMLDSig"); - assert(p != null); - return XMLSignatureFactory.getInstance("DOM", p); + return XMLSignatureFactory.getInstance("DOM", getProvider()); } public static KeyInfoFactory getKeyInfoFactory() { - Provider p = Security.getProvider("XMLDSig"); - assert(p != null); - return KeyInfoFactory.getInstance("DOM", p); + return KeyInfoFactory.getInstance("DOM", getProvider()); } + // 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) { XmlCursor rootCursor = root.newCursor(); insertXChild(rootCursor, child); @@ -252,12 +275,22 @@ public class SignatureInfo { childCursor.dispose(); } - public static void setPrefix(XmlObject xobj, String ns, String prefix) { - for (XmlCursor cur = xobj.newCursor(); cur.hasNextToken(); cur.toNextToken()) { - if (cur.isStart()) { - Element el = (Element)cur.getDomNode(); - if (ns.equals(el.getNamespaceURI())) el.setPrefix(prefix); - } +// public static void setPrefix(XmlObject xobj, String ns, String prefix) { +// XmlCursor cur; +// for (cur = xobj.newCursor(); cur.hasNextToken(); cur.toNextToken()) { +// if (cur.isStart()) { +// 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 c = cl.loadClass("org.bouncycastle.jce.provider.BouncyCastleProvider"); - bcProv = (Provider)c.newInstance(); - Security.addProvider(bcProv); - } + CryptoFunctions.registerBouncyCastle(); } catch (Exception e) { throw new RuntimeException("Xml & BouncyCastle-Provider initialization failed", e); } diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java index f2b9ba800..24d002d27 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java @@ -16,25 +16,18 @@ ==================================================================== */ 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.InputStream; import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; -import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; -import java.security.SignatureException; import java.security.cert.CRLException; +import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.spec.RSAKeyGenParameterSpec; @@ -52,45 +45,49 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1InputStreamIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.AuthorityInformationAccessIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.AuthorityKeyIdentifierIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicConstraintsIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicOCSPRespBuilderIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicOCSPRespIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CRLNumberIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CRLReasonIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CertificateIDIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CertificateStatusIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ContentSignerIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DERIA5StringIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DEROctetStringIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DERSequenceIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DigestCalculatorIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DistributionPointIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DistributionPointNameIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ExtensionIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ExtensionsIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.GeneralNameIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.GeneralNamesIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.JcaContentSignerBuilderIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.JcaDigestCalculatorProviderBuilderIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.KeyUsageIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPObjectIdentifiersIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPReqBuilderIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPReqIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespBuilderIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ReqIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.RevokedStatusIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SubjectKeyIdentifierIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SubjectPublicKeyInfoIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509CertificateHolderIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509ExtensionsIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509ObjectIdentifiersIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509PrincipalIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509V2CRLGeneratorIf; -import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509V3CertificateGeneratorIf; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.DERIA5String; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.AuthorityInformationAccess; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.CRLNumber; +import org.bouncycastle.asn1.x509.CRLReason; +import org.bouncycastle.asn1.x509.DistributionPoint; +import org.bouncycastle.asn1.x509.DistributionPointName; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.KeyUsage; +import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; +import org.bouncycastle.cert.X509CRLHolder; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v2CRLBuilder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.ocsp.BasicOCSPResp; +import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; +import org.bouncycastle.cert.ocsp.CertificateID; +import org.bouncycastle.cert.ocsp.CertificateStatus; +import org.bouncycastle.cert.ocsp.OCSPReq; +import org.bouncycastle.cert.ocsp.OCSPReqBuilder; +import org.bouncycastle.cert.ocsp.OCSPResp; +import org.bouncycastle.cert.ocsp.OCSPRespBuilder; +import org.bouncycastle.cert.ocsp.Req; +import org.bouncycastle.cert.ocsp.RevokedStatus; +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.Node; import org.xml.sax.InputSource; @@ -111,27 +108,21 @@ public class PkiTestUtils { return keyPair; } - private static SubjectKeyIdentifierIf createSubjectKeyId(PublicKey publicKey) - throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException - , IllegalAccessException, InvocationTargetException, NoSuchFieldException { - ByteArrayInputStream bais = new ByteArrayInputStream(publicKey.getEncoded()); - ASN1InputStreamIf asnObj = newProxy(ASN1InputStreamIf.class, bais); - SubjectPublicKeyInfoIf info = - newProxy(SubjectPublicKeyInfoIf.class, asnObj.readObject$Sequence()); - SubjectKeyIdentifierIf keyId = newProxy(SubjectKeyIdentifierIf.class, info); + @SuppressWarnings("resource") + private static SubjectKeyIdentifier createSubjectKeyId(PublicKey publicKey) + throws IOException { + ASN1InputStream asnObj = new ASN1InputStream(publicKey.getEncoded()); + SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(asnObj.readObject()); + SubjectKeyIdentifier keyId = SubjectKeyIdentifier.getInstance(info.getEncoded()); return keyId; } - private static AuthorityKeyIdentifierIf createAuthorityKeyId(PublicKey publicKey) - throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException - , IllegalAccessException, InvocationTargetException, NoSuchFieldException { - - ByteArrayInputStream bais = new ByteArrayInputStream(publicKey.getEncoded()); - ASN1InputStreamIf asnObj = newProxy(ASN1InputStreamIf.class, bais); - SubjectPublicKeyInfoIf info = - newProxy(SubjectPublicKeyInfoIf.class, asnObj.readObject$Sequence()); - AuthorityKeyIdentifierIf keyId = newProxy(AuthorityKeyIdentifierIf.class, info); - + @SuppressWarnings("resource") + private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey publicKey) + throws IOException { + ASN1InputStream asnObj = new ASN1InputStream(publicKey.getEncoded()); + SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(asnObj.readObject()); + AuthorityKeyIdentifier keyId = AuthorityKeyIdentifier.getInstance(info); return keyId; } @@ -139,88 +130,76 @@ public class PkiTestUtils { String subjectDn, Date notBefore, Date notAfter, X509Certificate issuerCertificate, PrivateKey issuerPrivateKey, boolean caFlag, int pathLength, String crlUri, String ocspUri, - KeyUsageIf keyUsage) - throws IOException, InvalidKeyException, IllegalStateException, NoSuchAlgorithmException - , SignatureException, CertificateException, InvocationTargetException, IllegalAccessException - , InstantiationException, NoSuchMethodException, ClassNotFoundException, NoSuchFieldException + KeyUsage keyUsage) + throws IOException, OperatorCreationException, CertificateException { String signatureAlgorithm = "SHA1withRSA"; - X509V3CertificateGeneratorIf certificateGenerator = newProxy(X509V3CertificateGeneratorIf.class); - certificateGenerator.reset(); - certificateGenerator.setPublicKey(subjectPublicKey); - 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()); + X500Name issuerName; + if (issuerCertificate != null) { + issuerName = new X509CertificateHolder(issuerCertificate.getEncoded()).getIssuer(); } 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(), - false, createSubjectKeyId(subjectPublicKey)); - PublicKey issuerPublicKey; - issuerPublicKey = subjectPublicKey; - certificateGenerator.addExtension( - X509Extensions.AuthorityKeyIdentifier(), false, - createAuthorityKeyId(issuerPublicKey)); + X509v3CertificateBuilder certificateGenerator = new X509v3CertificateBuilder( + issuerName + , new BigInteger(128, new SecureRandom()) + , notBefore + , notAfter + , new X500Name(subjectDn) + , subjectPublicKeyInfo + ); + + certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyId(subjectPublicKey)); + certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, createAuthorityKeyId(subjectPublicKey)); if (caFlag) { - BasicConstraintsIf bc; + BasicConstraints bc; if (-1 == pathLength) { - bc = newProxy(BasicConstraintsIf.class, true); + bc = new BasicConstraints(true); } 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) { - GeneralNameIf gn = newProxy(GeneralNameIf.class); - int uri = gn.uniformResourceIdentifier(); - DERIA5StringIf crlUriDer = newProxy(DERIA5StringIf.class, crlUri); - gn = newProxy(GeneralNameIf.class, uri, crlUriDer); + int uri = GeneralName.uniformResourceIdentifier; + DERIA5String crlUriDer = new DERIA5String(crlUri); + GeneralName gn = new GeneralName(uri, crlUriDer); - DERSequenceIf gnDer = newProxy(DERSequenceIf.class, gn); - GeneralNamesIf gns = newProxy(GeneralNamesIf.class, gnDer); + DERSequence gnDer = new DERSequence(gn); + GeneralNames gns = GeneralNames.getInstance(gnDer); - DistributionPointNameIf dpn = newProxy(DistributionPointNameIf.class, 0, gns); - DistributionPointIf distp = newProxy(DistributionPointIf.class, dpn, null, null); - DERSequenceIf distpDer = newProxy(DERSequenceIf.class, distp); - certificateGenerator.addExtension(X509Extensions.CRLDistributionPoints(), false, distpDer); + DistributionPointName dpn = new DistributionPointName(0, gns); + DistributionPoint distp = new DistributionPoint(dpn, null, null); + DERSequence distpDer = new DERSequence(distp); + certificateGenerator.addExtension(Extension.cRLDistributionPoints, false, distpDer); } if (null != ocspUri) { - GeneralNameIf ocspName = newProxy(GeneralNameIf.class); - int uri = ocspName.uniformResourceIdentifier(); - ocspName = newProxy(GeneralNameIf.class, uri, ocspUri); + int uri = GeneralName.uniformResourceIdentifier; + GeneralName ocspName = new GeneralName(uri, ocspUri); - X509ObjectIdentifiersIf X509ObjectIdentifiers = newProxy(X509ObjectIdentifiersIf.class); - AuthorityInformationAccessIf authorityInformationAccess = - newProxy(AuthorityInformationAccessIf.class - , X509ObjectIdentifiers.ocspAccessMethod(), ocspName); + AuthorityInformationAccess authorityInformationAccess = + new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspName); - certificateGenerator.addExtension( - X509Extensions.AuthorityInfoAccess(), false, - authorityInformationAccess); + certificateGenerator.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess); } if (null != keyUsage) { - certificateGenerator.addExtension(X509Extensions.KeyUsage(), true, keyUsage); + certificateGenerator.addExtension(Extension.keyUsage, true, keyUsage); } - X509Certificate certificate; - certificate = certificateGenerator.generate(issuerPrivateKey); + JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm); + signerBuilder.setProvider("BC"); + + X509CertificateHolder certHolder = + certificateGenerator.build(signerBuilder.build(issuerPrivateKey)); /* * 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 * we might run into trouble when trying to use the CertPath validator. */ - CertificateFactory certificateFactory = CertificateFactory - .getInstance("X.509"); - certificate = (X509Certificate) certificateFactory - .generateCertificate(new ByteArrayInputStream(certificate - .getEncoded())); - return certificate; +// CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); +// certificate = (X509Certificate) certificateFactory +// .generateCertificate(new ByteArrayInputStream(certificate +// .getEncoded())); + return new JcaX509CertificateConverter().getCertificate(certHolder); } static Document loadDocument(InputStream documentInputStream) @@ -264,93 +242,79 @@ public class PkiTestUtils { return stringWriter.getBuffer().toString(); } - public static X509CRL generateCrl(X509Certificate issuer, - PrivateKey issuerPrivateKey) throws InvalidKeyException, - 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")); + public static X509CRL generateCrl(X509Certificate issuer, PrivateKey issuerPrivateKey) + throws CertificateEncodingException, IOException, CRLException, OperatorCreationException { - crlGenerator.addExtension(X509Extensions.CRLNumber(), false, crlNumber); - X509CRL x509Crl = crlGenerator.generate(issuerPrivateKey); - return x509Crl; + X509CertificateHolder holder = new X509CertificateHolder(issuer.getEncoded()); + X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(holder.getIssuer(), new Date()); + 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, X509Certificate ocspResponderCertificate, PrivateKey ocspResponderPrivateKey, String signatureAlgorithm, long nonceTimeinMillis) throws Exception { - CertificateIDIf certId = newProxy(CertificateIDIf.class); - DigestCalculatorIf digestCalc = - newProxy(JcaDigestCalculatorProviderBuilderIf.class) - .setProvider("BC").build().get(certId.HASH_SHA1()); - X509CertificateHolderIf issuerHolder = newProxy(X509CertificateHolderIf.class, issuerCertificate.getEncoded()); - certId = newProxy(CertificateIDIf.class, digestCalc, issuerHolder, certificate.getSerialNumber()); + DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder() + .setProvider("BC").build().get(CertificateID.HASH_SHA1); + X509CertificateHolder issuerHolder = new X509CertificateHolder(issuerCertificate.getEncoded()); + CertificateID certId = new CertificateID(digestCalc, issuerHolder, certificate.getSerialNumber()); // request //create a nonce to avoid replay attack BigInteger nonce = BigInteger.valueOf(nonceTimeinMillis); - OCSPObjectIdentifiersIf oidIf = newProxy(OCSPObjectIdentifiersIf.class); - DEROctetStringIf nonceDer = newProxy(DEROctetStringIf.class, nonce.toByteArray()); - ExtensionIf ext = newProxy(ExtensionIf.class, oidIf.id_pkix_ocsp_nonce(), true, nonceDer); - ExtensionsIf exts = newProxy(ExtensionsIf.class, ext); + DEROctetString nonceDer = new DEROctetString(nonce.toByteArray()); + Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, nonceDer); + Extensions exts = new Extensions(ext); - OCSPReqBuilderIf ocspReqBuilder = newProxy(OCSPReqBuilderIf.class); + OCSPReqBuilder ocspReqBuilder = new OCSPReqBuilder(); ocspReqBuilder.addRequest(certId); ocspReqBuilder.setRequestExtensions(exts); - OCSPReqIf ocspReq = ocspReqBuilder.build(); + OCSPReq ocspReq = ocspReqBuilder.build(); - SubjectPublicKeyInfoIf keyInfo = newProxy(SubjectPublicKeyInfoIf.class - , certId.HASH_SHA1(), ocspResponderCertificate.getPublicKey().getEncoded()); + SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo + (CertificateID.HASH_SHA1, ocspResponderCertificate.getPublicKey().getEncoded()); - BasicOCSPRespBuilderIf basicOCSPRespBuilder = - newProxy(BasicOCSPRespBuilderIf.class, keyInfo, digestCalc); + BasicOCSPRespBuilder basicOCSPRespBuilder = new BasicOCSPRespBuilder(keyInfo, digestCalc); basicOCSPRespBuilder.setResponseExtensions(exts); // request processing - ReqIf[] requestList = ocspReq.getRequestList(); - for (ReqIf ocspRequest : requestList) { - CertificateIDIf certificateID = ocspRequest.getCertID(); - CertificateStatusIf certificateStatus; + Req[] requestList = ocspReq.getRequestList(); + for (Req ocspRequest : requestList) { + CertificateID certificateID = ocspRequest.getCertID(); + CertificateStatus certificateStatus = CertificateStatus.GOOD; if (revoked) { - CRLReasonIf crlr = newProxy(CRLReasonIf.class); - RevokedStatusIf rs = newProxy(RevokedStatusIf.class, new Date(), crlr.privilegeWithdrawn()); - certificateStatus = newProxy(CertificateStatusIf.class, rs.getDelegate()); - } else { - CertificateStatusIf cs = newProxy(CertificateStatusIf.class); - certificateStatus = cs.GOOD(); + certificateStatus = new RevokedStatus(new Date(), CRLReason.privilegeWithdrawn); } basicOCSPRespBuilder.addResponse(certificateID, certificateStatus); } // basic response generation - X509CertificateHolderIf[] chain = null; + X509CertificateHolder[] chain = null; if (!ocspResponderCertificate.equals(issuerCertificate)) { // TODO: HorribleProxy can't convert array input params yet - chain = new X509CertificateHolderIf[] { - newProxy(X509CertificateHolderIf.class, ocspResponderCertificate), + chain = new X509CertificateHolder[] { + new X509CertificateHolder(ocspResponderCertificate.getEncoded()), issuerHolder }; } - ContentSignerIf contentSigner = newProxy(JcaContentSignerBuilderIf.class, "SHA1withRSA") + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA") .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); - OCSPRespIf ocspResp = ocspRespBuilder.build(ocspRespBuilder.SUCCESSFUL(), basicOCSPResp); + OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder(); + OCSPResp ocspResp = ocspRespBuilder.build(OCSPRespBuilder.SUCCESSFUL, basicOCSPResp); return ocspResp; } diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java index b329474e5..43a6b549b 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java @@ -52,13 +52,11 @@ import javax.xml.crypto.KeySelector; import javax.xml.crypto.dsig.XMLSignature; import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.dom.DOMValidateContext; +import javax.xml.parsers.DocumentBuilderFactory; import org.apache.poi.POIDataSamples; import org.apache.poi.openxml4j.opc.OPCPackage; 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.facets.EnvelopedSignatureFacet; 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.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.SAXHelper; 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.QualifyingPropertiesType; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.w3.x2000.x09.xmldsig.SignatureDocument; +import org.w3c.dom.Document; public class TestSignatureInfo { private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class); @@ -199,7 +202,9 @@ public class TestSignatureInfo { pkg.close(); } + @SuppressWarnings("unused") @Test + @Ignore public void testSignEnvelopingDocument() throws Exception { String testFile = "hello-world-unsigned.xlsx"; 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); 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://tsa.belgium.be/connect String tspServiceUrl = "http://timestamping.edelweb.fr/service/tsp"; - TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() { - @Override - public void validate(List 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()); + + TimeStampService timeStampService; + if (tspServiceUrl == null) { + timeStampService = new TimeStampService(){ + public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception { + revocationData.addCRL(crl); + return "time-stamp-token".getBytes(); } + }; + } else { + TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() { + @Override + public void validate(List 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 timeStampService = new TSPTimeStampService(tspServiceUrl, tspValidator); + timeStampService = tspService; + } List certificateChain = new ArrayList(); /* @@ -246,7 +260,7 @@ public class TestSignatureInfo { final RevocationData revocationData = new RevocationData(); revocationData.addCRL(crl); - OCSPRespIf ocspResp = PkiTestUtils.createOcspResp(x509, false, + OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false, x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis()); revocationData.addOCSP(ocspResp.getEncoded()); @@ -263,16 +277,19 @@ public class TestSignatureInfo { xadesSignatureFacet, xadesXLSignatureFacet); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().newDocument(); // operate - DigestInfo digestInfo = testedInstance.preSign(null, certificateChain, null, null, null); + DigestInfo digestInfo = testedInstance.preSign(document, null, keyPair.getPrivate(), certificateChain, null, null, null); // verify assertNotNull(digestInfo); assertEquals(HashAlgorithm.sha1, digestInfo.hashAlgo); assertNotNull(digestInfo.digestValue); - SignatureDocument sigDoc = testedInstance.getSignatureDocument(); + SignatureDocument sigDoc = SignatureDocument.Factory.parse(document); String certDigestXQuery = "declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; " + "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); // Operate: postSign - testedInstance.postSign(signatureValue, certificateChain); + testedInstance.postSign(document, signatureValue, certificateChain); DOMValidateContext domValidateContext = new DOMValidateContext( KeySelector.singletonKeySelector(keyPair.getPublic()), - testedInstance.getSignatureDocument().getDomNode()); + document); XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory(); XMLSignature xmlSignature = xmlSignatureFactory .unmarshalXMLSignature(domValidateContext); boolean validity = xmlSignature.validate(domValidateContext); assertTrue(validity); + sigDoc = SignatureDocument.Factory.parse(document); xoList = sigDoc.selectPath(certDigestXQuery); assertEquals(xoList.length, 1); certDigest = (DigestAlgAndValueType)xoList[0]; @@ -320,9 +338,11 @@ public class TestSignatureInfo { signatureService.initFacets(cal.getTime()); initKeyPair(alias, signerDn); + Document document = SAXHelper.getDocumentBuilder().newDocument(); + // operate List 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 assertNotNull(digestInfo); @@ -336,7 +356,7 @@ public class TestSignatureInfo { byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue); // operate: postSign - signatureService.postSign(signatureValue, Collections.singletonList(x509)); + signatureService.postSign(document, signatureValue, Collections.singletonList(x509)); // verify: signature SignatureInfo si = new SignatureInfo(pkgCopy); @@ -370,8 +390,7 @@ public class TestSignatureInfo { Date notBefore = cal.getTime(); cal.add(Calendar.YEAR, 1); Date notAfter = cal.getTime(); - KeyUsageIf keyUsage = HorribleProxy.newProxy(KeyUsageIf.class); - keyUsage = HorribleProxy.newProxy(KeyUsageIf.class, keyUsage.digitalSignature()); + KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature); x509 = PkiTestUtils.generateCertificate(keyPair.getPublic(), subjectDN , notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage);