diff options
Diffstat (limited to 'pkix/src/main/jdk1.3/org/spongycastle')
27 files changed, 2008 insertions, 0 deletions
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java new file mode 100644 index 00000000..eac007e0 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java @@ -0,0 +1,55 @@ +package org.spongycastle.cert.crmf.jcajce; + +import java.security.Provider; +import java.security.PublicKey; + +import org.spongycastle.asn1.crmf.CertReqMsg; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.cert.crmf.CRMFException; +import org.spongycastle.cert.crmf.CertificateRequestMessage; +import org.spongycastle.jcajce.util.DefaultJcaJceHelper; +import org.spongycastle.jcajce.util.NamedJcaJceHelper; +import org.spongycastle.jcajce.util.ProviderJcaJceHelper; + +public class JcaCertificateRequestMessage + extends CertificateRequestMessage +{ + private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper()); + + public JcaCertificateRequestMessage(CertificateRequestMessage certReqMsg) + { + this(certReqMsg.toASN1Structure()); + } + + public JcaCertificateRequestMessage(CertReqMsg certReqMsg) + { + super(certReqMsg); + } + + public JcaCertificateRequestMessage setProvider(String providerName) + { + this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName)); + + return this; + } + + public JcaCertificateRequestMessage setProvider(Provider provider) + { + this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider)); + + return this; + } + + public PublicKey getPublicKey() + throws CRMFException + { + SubjectPublicKeyInfo subjectPublicKeyInfo = getCertTemplate().getPublicKey(); + + if (subjectPublicKeyInfo != null) + { + return helper.toPublicKey(subjectPublicKeyInfo); + } + + return null; + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java new file mode 100644 index 00000000..6b2f8521 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java @@ -0,0 +1,25 @@ +package org.spongycastle.cert.crmf.jcajce; + +import java.math.BigInteger; +import java.security.PublicKey; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.GeneralName; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.cert.crmf.CertificateRequestMessageBuilder; + +public class JcaCertificateRequestMessageBuilder + extends CertificateRequestMessageBuilder +{ + public JcaCertificateRequestMessageBuilder(BigInteger certReqId) + { + super(certReqId); + } + + public JcaCertificateRequestMessageBuilder setPublicKey(PublicKey publicKey) + { + setPublicKey(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); + + return this; + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java new file mode 100644 index 00000000..9e2963c8 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java @@ -0,0 +1,22 @@ +package org.spongycastle.cert.crmf.jcajce; + +import java.security.PrivateKey; + +import org.spongycastle.asn1.pkcs.PrivateKeyInfo; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.GeneralName; +import org.spongycastle.cert.crmf.PKIArchiveControlBuilder; + +public class JcaPKIArchiveControlBuilder + extends PKIArchiveControlBuilder +{ + public JcaPKIArchiveControlBuilder(PrivateKey privateKey, X500Name name) + { + this(privateKey, new GeneralName(name)); + } + + public JcaPKIArchiveControlBuilder(PrivateKey privateKey, GeneralName generalName) + { + super(PrivateKeyInfo.getInstance(privateKey.getEncoded()), generalName); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java new file mode 100644 index 00000000..37a1723c --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java @@ -0,0 +1,151 @@ +package org.spongycastle.cert.jcajce; + +import java.security.GeneralSecurityException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.cert.CRLException; +import org.spongycastle.jce.cert.CertStore; +import java.security.cert.CertificateException; +import org.spongycastle.jce.cert.CollectionCertStoreParameters; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.spongycastle.cert.X509CRLHolder; +import org.spongycastle.cert.X509CertificateHolder; +import org.spongycastle.util.Store; + +/** + * Builder to create a CertStore from certificate and CRL stores. + */ +public class JcaCertStoreBuilder +{ + private List certs = new ArrayList(); + private List crls = new ArrayList(); + private Object provider; + private JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); + private JcaX509CRLConverter crlConverter = new JcaX509CRLConverter(); + private String type = "Collection"; + + /** + * Add a store full of X509CertificateHolder objects. + * + * @param certStore a store of X509CertificateHolder objects. + */ + public JcaCertStoreBuilder addCertificates(Store certStore) + { + certs.addAll(certStore.getMatches(null)); + + return this; + } + + /** + * Add a single certificate. + * + * @param cert the X509 certificate holder containing the certificate. + */ + public JcaCertStoreBuilder addCertificate(X509CertificateHolder cert) + { + certs.add(cert); + + return this; + } + + /** + * Add a store full of X509CRLHolder objects. + * @param crlStore a store of X509CRLHolder objects. + */ + public JcaCertStoreBuilder addCRLs(Store crlStore) + { + crls.addAll(crlStore.getMatches(null)); + + return this; + } + + /** + * Add a single CRL. + * + * @param crl the X509 CRL holder containing the CRL. + */ + public JcaCertStoreBuilder addCRL(X509CRLHolder crl) + { + crls.add(crl); + + return this; + } + + public JcaCertStoreBuilder setProvider(String providerName) + { + certificateConverter.setProvider(providerName); + crlConverter.setProvider(providerName); + this.provider = providerName; + + return this; + } + + public JcaCertStoreBuilder setProvider(Provider provider) + { + certificateConverter.setProvider(provider); + crlConverter.setProvider(provider); + this.provider = provider; + + return this; + } + + /** + * Set the type of the CertStore generated. By default it is "Collection". + * + * @param type type of CertStore passed to CertStore.getInstance(). + * @return the current builder. + */ + public JcaCertStoreBuilder setType(String type) + { + this.type = type; + + return this; + } + + /** + * Build the CertStore from the current inputs. + * + * @return a CertStore. + * @throws GeneralSecurityException + */ + public CertStore build() + throws GeneralSecurityException + { + CollectionCertStoreParameters params = convertHolders(certificateConverter, crlConverter); + + if (provider instanceof String) + { + return CertStore.getInstance(type, params, (String)provider); + } + + if (provider instanceof Provider) + { + return CertStore.getInstance(type, params, (Provider)provider); + } + + return CertStore.getInstance(type, params); + } + + private CollectionCertStoreParameters convertHolders(JcaX509CertificateConverter certificateConverter, JcaX509CRLConverter crlConverter) + throws CertificateException, CRLException + { + List jcaObjs = new ArrayList(certs.size() + crls.size()); + + for (Iterator it = certs.iterator(); it.hasNext();) + { + jcaObjs.add(certificateConverter.getCertificate((X509CertificateHolder)it.next())); + } + + for (Iterator it = crls.iterator(); it.hasNext();) + { + jcaObjs.add(crlConverter.getCRL((X509CRLHolder)it.next())); + } + + return new CollectionCertStoreParameters(jcaObjs); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java new file mode 100644 index 00000000..840dde55 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java @@ -0,0 +1,58 @@ +package org.spongycastle.cert.jcajce; + +import java.security.cert.X509Certificate; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x500.X500NameStyle; +import org.spongycastle.jce.PrincipalUtil; + +public class JcaX500NameUtil +{ + public static X500Name getIssuer(X509Certificate certificate) + { +try +{ + return X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); +} +catch (Exception e) +{ + throw new IllegalStateException(e.toString()); +} + } + + public static X500Name getSubject(X509Certificate certificate) + { +try +{ + return X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); +} +catch (Exception e) +{ + throw new IllegalStateException(e.toString()); +} + } + + public static X500Name getIssuer(X500NameStyle style, X509Certificate certificate) + { +try +{ + return X500Name.getInstance(style, PrincipalUtil.getIssuerX509Principal(certificate).getEncoded()); +} +catch (Exception e) +{ + throw new IllegalStateException(e.toString()); +} + } + + public static X500Name getSubject(X500NameStyle style, X509Certificate certificate) + { +try +{ + return X500Name.getInstance(style, PrincipalUtil.getSubjectX509Principal(certificate).getEncoded()); +} +catch (Exception e) +{ + throw new IllegalStateException(e.toString()); +} + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java new file mode 100644 index 00000000..f40ab480 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java @@ -0,0 +1,138 @@ +package org.spongycastle.cert.jcajce; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.oiw.OIWObjectIdentifiers; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.asn1.x509.AuthorityKeyIdentifier; +import org.spongycastle.asn1.x509.GeneralName; +import org.spongycastle.asn1.x509.GeneralNames; +import org.spongycastle.asn1.x509.SubjectKeyIdentifier; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.cert.X509ExtensionUtils; +import org.spongycastle.operator.DigestCalculator; + +public class JcaX509ExtensionUtils + extends X509ExtensionUtils +{ + /** + * Create a utility class pre-configured with a SHA-1 digest calculator based on the + * default implementation. + * + * @throws java.security.NoSuchAlgorithmException + */ + public JcaX509ExtensionUtils() + throws NoSuchAlgorithmException + { + super(new SHA1DigestCalculator(MessageDigest.getInstance("SHA1"))); + } + + public JcaX509ExtensionUtils(DigestCalculator calculator) + { + super(calculator); + } + + public AuthorityKeyIdentifier createAuthorityKeyIdentifier( + X509Certificate cert) + throws CertificateEncodingException + { + return super.createAuthorityKeyIdentifier(new JcaX509CertificateHolder(cert)); + } + + public AuthorityKeyIdentifier createAuthorityKeyIdentifier( + PublicKey pubKey) + { + return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded())); + } + + public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, GeneralNames generalNames, BigInteger serial) + { + return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), generalNames, serial); + } + + /** + * Return a RFC 3280 type 1 key identifier. As in: + * <pre> + * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the + * value of the BIT STRING subjectPublicKey (excluding the tag, + * length, and number of unused bits). + * </pre> + * @param publicKey the key object containing the key identifier is to be based on. + * @return the key identifier. + */ + public SubjectKeyIdentifier createSubjectKeyIdentifier( + PublicKey publicKey) + { + return super.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); + } + + /** + * Return a RFC 3280 type 2 key identifier. As in: + * <pre> + * (2) The keyIdentifier is composed of a four bit type field with + * the value 0100 followed by the least significant 60 bits of the + * SHA-1 hash of the value of the BIT STRING subjectPublicKey. + * </pre> + * @param publicKey the key object of interest. + * @return the key identifier. + */ + public SubjectKeyIdentifier createTruncatedSubjectKeyIdentifier(PublicKey publicKey) + { + return super.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); + } + + /** + * Return the ASN.1 object contained in a byte[] returned by a getExtensionValue() call. + * + * @param encExtValue DER encoded OCTET STRING containing the DER encoded extension object. + * @return an ASN.1 object + * @throws java.io.IOException on a parsing error. + */ + public static ASN1Primitive parseExtensionValue(byte[] encExtValue) + throws IOException + { + return ASN1Primitive.fromByteArray(ASN1OctetString.getInstance(encExtValue).getOctets()); + } + + private static class SHA1DigestCalculator + implements DigestCalculator + { + private ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + private MessageDigest digest; + + public SHA1DigestCalculator(MessageDigest digest) + { + this.digest = digest; + } + + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); + } + + public OutputStream getOutputStream() + { + return bOut; + } + + public byte[] getDigest() + { + byte[] bytes = digest.digest(bOut.toByteArray()); + + bOut.reset(); + + return bytes; + } + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java new file mode 100644 index 00000000..b67959bc --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java @@ -0,0 +1,31 @@ +package org.spongycastle.cert.jcajce; + +import java.math.BigInteger; +import java.security.PublicKey; +import java.util.Date; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.cert.X509v1CertificateBuilder; + +/** + * JCA helper class to allow JCA objects to be used in the construction of a Version 1 certificate. + */ +public class JcaX509v1CertificateBuilder + extends X509v1CertificateBuilder +{ + /** + * Initialise the builder using a PublicKey. + * + * @param issuer X500Name representing the issuer of this certificate. + * @param serial the serial number for the certificate. + * @param notBefore date before which the certificate is not valid. + * @param notAfter date after which the certificate is not valid. + * @param subject X500Name representing the subject of this certificate. + * @param publicKey the public key to be associated with the certificate. + */ + public JcaX509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) + { + super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java new file mode 100644 index 00000000..4b1f4907 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java @@ -0,0 +1,15 @@ +package org.spongycastle.cert.jcajce; + +import java.util.Date; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cert.X509v2CRLBuilder; + +public class JcaX509v2CRLBuilder + extends X509v2CRLBuilder +{ + public JcaX509v2CRLBuilder(X500Name issuer, Date now) + { + super(issuer, now); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java new file mode 100644 index 00000000..4f7a4a1e --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java @@ -0,0 +1,54 @@ +package org.spongycastle.cert.jcajce; + +import java.math.BigInteger; +import java.security.PublicKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Date; + +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.cert.X509v3CertificateBuilder; + +/** + * JCA helper class to allow JCA objects to be used in the construction of a Version 3 certificate. + */ +public class JcaX509v3CertificateBuilder + extends X509v3CertificateBuilder +{ + /** + * Initialise the builder using a PublicKey. + * + * @param issuer X500Name representing the issuer of this certificate. + * @param serial the serial number for the certificate. + * @param notBefore date before which the certificate is not valid. + * @param notAfter date after which the certificate is not valid. + * @param subject X500Name representing the subject of this certificate. + * @param publicKey the public key to be associated with the certificate. + */ + public JcaX509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey) + { + super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) + * copying the extension value from another certificate. + * + * @param oid the type of the extension to be copied. + * @param critical true if the extension is to be marked critical, false otherwise. + * @param certificate the source of the extension to be copied. + * @return the builder instance. + */ + public JcaX509v3CertificateBuilder copyAndAddExtension( + ASN1ObjectIdentifier oid, + boolean critical, + X509Certificate certificate) + throws CertificateEncodingException + { + this.copyAndAddExtension(oid, critical, new JcaX509CertificateHolder(certificate)); + + return this; + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java new file mode 100644 index 00000000..a28a7c56 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java @@ -0,0 +1,30 @@ +package org.spongycastle.cert.jcajce; + +import java.security.Provider; +import java.security.NoSuchProviderException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; + +class ProviderCertHelper + extends CertHelper +{ + private final Provider provider; + + ProviderCertHelper(Provider provider) + { + this.provider = provider; + } + + protected CertificateFactory createCertificateFactory(String type) + throws CertificateException + { + try + { + return CertificateFactory.getInstance(type, provider.getName()); + } + catch (NoSuchProviderException e) + { + throw new CertificateException(e.toString()); + } + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java new file mode 100644 index 00000000..41d9072c --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java @@ -0,0 +1,19 @@ +package org.spongycastle.cert.ocsp.jcajce; + +import java.security.PublicKey; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.cert.ocsp.OCSPException; +import org.spongycastle.cert.ocsp.RespID; +import org.spongycastle.operator.DigestCalculator; + +public class JcaRespID + extends RespID +{ + public JcaRespID(PublicKey pubKey, DigestCalculator digCalc) + throws OCSPException + { + super(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), digCalc); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java new file mode 100644 index 00000000..cede4acc --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java @@ -0,0 +1,34 @@ +package org.spongycastle.cert.selector.jcajce; + +import org.spongycastle.jce.cert.X509CertSelector; + +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cert.selector.X509CertificateHolderSelector; + +public class JcaSelectorConverter +{ + public JcaSelectorConverter() + { + + } + + public X509CertificateHolderSelector getCertificateHolderSelector(X509CertSelector certSelector) + { +try +{ + if (certSelector.getSubjectKeyIdentifier() != null) + { + return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); + } + else + { + return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); + } +} +catch (Exception e) +{ +throw new IllegalArgumentException("conversion failed: " + e.toString()); +} + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java new file mode 100644 index 00000000..b2dbb563 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java @@ -0,0 +1,57 @@ +package org.spongycastle.cert.selector.jcajce; + +import java.io.IOException; +import java.math.BigInteger; +import org.spongycastle.jce.cert.X509CertSelector; + +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cert.selector.X509CertificateHolderSelector; + +public class JcaX509CertSelectorConverter +{ + public JcaX509CertSelectorConverter() + { + } + + protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyIdentifier) + { + X509CertSelector selector = new X509CertSelector(); + + if (issuer != null) + { + try + { + selector.setIssuer(issuer.getEncoded()); + } + catch (IOException e) + { + throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); + } + } + + if (serialNumber != null) + { + selector.setSerialNumber(serialNumber); + } + + if (subjectKeyIdentifier != null) + { + try + { + selector.setSubjectKeyIdentifier(new DEROctetString(subjectKeyIdentifier).getEncoded()); + } + catch (IOException e) + { + throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage()); + } + } + + return selector; + } + + public X509CertSelector getCertSelector(X509CertificateHolderSelector holderSelector) + { + return doConversion(holderSelector.getIssuer(), holderSelector.getSerialNumber(), holderSelector.getSubjectKeyIdentifier()); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java new file mode 100644 index 00000000..3280af2a --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java @@ -0,0 +1,57 @@ +package org.spongycastle.cert.selector.jcajce; + +import java.math.BigInteger; +import java.security.cert.X509Certificate; + +import org.spongycastle.jce.X509Principal; +import org.spongycastle.jce.PrincipalUtil; + +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.X509Extension; +import org.spongycastle.cert.selector.X509CertificateHolderSelector; + +public class JcaX509CertificateHolderSelector + extends X509CertificateHolderSelector +{ + /** + * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in + * certificate. + * + * @param certificate certificate providing the issue and serial number and subject key identifier. + */ + public JcaX509CertificateHolderSelector(X509Certificate certificate) + { + super(convertPrincipal(certificate), certificate.getSerialNumber(), getSubjectKeyId(certificate)); + } + + private static X500Name convertPrincipal(X509Certificate issuer) + { + if (issuer == null) + { + return null; + } +try +{ + return X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(issuer).toASN1Primitive()); +} +catch (Exception e) +{ + throw new IllegalArgumentException("conversion failed: " + e.toString()); +} + } + + private static byte[] getSubjectKeyId(X509Certificate cert) + { + byte[] ext = cert.getExtensionValue(X509Extension.subjectKeyIdentifier.getId()); + + if (ext != null) + { + return ASN1OctetString.getInstance(ASN1OctetString.getInstance(ext).getOctets()).getOctets(); + } + else + { + return null; + } + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java new file mode 100644 index 00000000..c6d0cebe --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java @@ -0,0 +1,54 @@ +package org.spongycastle.cms.jcajce; + +import org.spongycastle.jce.cert.X509CertSelector; + +import org.spongycastle.asn1.ASN1OctetString; +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cms.KeyTransRecipientId; +import org.spongycastle.cms.SignerId; + +public class JcaSelectorConverter +{ + public JcaSelectorConverter() + { + + } + + public SignerId getSignerId(X509CertSelector certSelector) + { +try +{ + if (certSelector.getSubjectKeyIdentifier() != null) + { + return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); + } + else + { + return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); + } +} +catch (Exception e) +{ + throw new IllegalArgumentException("conversion failed: " + e.toString()); +} + } + + public KeyTransRecipientId getKeyTransRecipientId(X509CertSelector certSelector) + { +try +{ + if (certSelector.getSubjectKeyIdentifier() != null) + { + return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets()); + } + else + { + return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber()); + } +} +catch (Exception e) +{ + throw new IllegalArgumentException("conversion failed: " + e.toString()); +} + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java new file mode 100644 index 00000000..99650cfb --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java @@ -0,0 +1,36 @@ +package org.spongycastle.cms.jcajce; + +import java.math.BigInteger; +import java.security.cert.X509Certificate; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cms.SignerId; +import org.spongycastle.jce.PrincipalUtil; +import org.spongycastle.jce.X509Principal; + +public class JcaSignerId + extends SignerId +{ + private static X509Principal getPrincipal(X509Certificate cert) + { + try + { + return PrincipalUtil.getIssuerX509Principal(cert); + } + catch (Exception e) + { + throw new IllegalArgumentException("unable to extract principle"); + } + } + + /** + * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in + * certificate. + * + * @param certificate certificate providing the issue and serial number and subject key identifier. + */ + public JcaSignerId(X509Certificate certificate) + { + super(X500Name.getInstance(getPrincipal(certificate).getEncoded()), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate)); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java new file mode 100644 index 00000000..594ed1d5 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java @@ -0,0 +1,24 @@ +package org.spongycastle.cms.jcajce; + +import org.spongycastle.jce.cert.X509CertSelector; + +import org.spongycastle.cms.KeyTransRecipientId; +import org.spongycastle.cms.SignerId; + +public class JcaX509CertSelectorConverter + extends org.spongycastle.cert.selector.jcajce.JcaX509CertSelectorConverter +{ + public JcaX509CertSelectorConverter() + { + } + + public X509CertSelector getCertSelector(KeyTransRecipientId recipientId) + { + return doConversion(recipientId.getIssuer(), recipientId.getSerialNumber(), recipientId.getSubjectKeyIdentifier()); + } + + public X509CertSelector getCertSelector(SignerId signerId) + { + return doConversion(signerId.getIssuer(), signerId.getSerialNumber(), signerId.getSubjectKeyIdentifier()); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java new file mode 100644 index 00000000..91875037 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java @@ -0,0 +1,32 @@ +package org.spongycastle.cms.jcajce; + +import java.math.BigInteger; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import org.spongycastle.jce.PrincipalUtil; +import org.spongycastle.jce.X509Principal; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cms.KeyAgreeRecipientId; + +public class JceKeyAgreeRecipientId + extends KeyAgreeRecipientId +{ + public JceKeyAgreeRecipientId(X509Certificate certificate) + { + super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber()); + } + + private static X509Principal extractIssuer(X509Certificate certificate) + { + try + { + return PrincipalUtil.getIssuerX509Principal(certificate); + } + catch (CertificateEncodingException e) + { + throw new IllegalStateException("can't extract issuer"); + } + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java new file mode 100644 index 00000000..5bac48b5 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java @@ -0,0 +1,30 @@ +package org.spongycastle.cms.jcajce; + +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.cms.KeyTransRecipientId; +import org.spongycastle.jce.PrincipalUtil; +import org.spongycastle.jce.X509Principal; + +public class JceKeyTransRecipientId + extends KeyTransRecipientId +{ + public JceKeyTransRecipientId(X509Certificate certificate) + { + super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate)); + } + + private static X509Principal extractIssuer(X509Certificate certificate) + { + try + { + return PrincipalUtil.getIssuerX509Principal(certificate); + } + catch (CertificateEncodingException e) + { + throw new IllegalStateException("can't extract issuer"); + } + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java new file mode 100644 index 00000000..4bc4dfa3 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java @@ -0,0 +1,23 @@ +package org.spongycastle.eac.jcajce; + +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; + +class ProviderEACHelper + implements EACHelper +{ + private final Provider provider; + + ProviderEACHelper(Provider provider) + { + this.provider = provider; + } + + public KeyFactory createKeyFactory(String type) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return KeyFactory.getInstance(type, provider.getName()); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java new file mode 100644 index 00000000..dcdd1e1c --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java @@ -0,0 +1,23 @@ +package org.spongycastle.eac.operator.jcajce; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.Signature; + +class ProviderEACHelper + extends EACHelper +{ + private final Provider provider; + + ProviderEACHelper(Provider provider) + { + this.provider = provider; + } + + protected Signature createSignature(String type) + throws NoSuchAlgorithmException, NoSuchProviderException + { + return Signature.getInstance(type, provider.getName()); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java new file mode 100644 index 00000000..a4de4911 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java @@ -0,0 +1,44 @@ +package org.spongycastle.operator.jcajce; + + +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.spec.AlgorithmParameterSpec; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.spongycastle.asn1.pkcs.RSAESOAEPparams; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder; + +public class JcaAlgorithmParametersConverter +{ + public JcaAlgorithmParametersConverter() + { + } + + public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters) + throws InvalidAlgorithmParameterException + { + try + { + ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded()); + + return new AlgorithmIdentifier(algId, params); + } + catch (IOException e) + { + throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage()); + } + } + + public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec) + throws InvalidAlgorithmParameterException + { + throw new InvalidAlgorithmParameterException("unknown parameter spec passed."); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java new file mode 100644 index 00000000..419f0939 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java @@ -0,0 +1,470 @@ +package org.spongycastle.operator.jcajce; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PublicKey; +import java.security.Signature; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +//import java.security.spec.PSSParameterSpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +import javax.crypto.Cipher; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.DERNull; +import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import org.spongycastle.asn1.kisa.KISAObjectIdentifiers; +import org.spongycastle.asn1.nist.NISTObjectIdentifiers; +import org.spongycastle.asn1.ntt.NTTObjectIdentifiers; +import org.spongycastle.asn1.oiw.OIWObjectIdentifiers; +import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.spongycastle.asn1.pkcs.RSASSAPSSparams; +import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.asn1.x9.X9ObjectIdentifiers; +import org.spongycastle.cert.X509CertificateHolder; +import org.spongycastle.jcajce.util.JcaJceHelper; +import org.spongycastle.operator.OperatorCreationException; + +class OperatorHelper +{ + private static final Map oids = new HashMap(); + private static final Map asymmetricWrapperAlgNames = new HashMap(); + private static final Map symmetricWrapperAlgNames = new HashMap(); + private static final Map symmetricKeyAlgNames = new HashMap(); + + static + { + // + // reverse mappings + // + oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); + oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); + oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); + oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); + oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); + oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); + oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); + + oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); + oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); + oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); + oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); + oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); + oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); + oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); + oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); + oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); + oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); + oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); + oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); + + oids.put(OIWObjectIdentifiers.idSHA1, "SHA-1"); + oids.put(NISTObjectIdentifiers.id_sha224, "SHA-224"); + oids.put(NISTObjectIdentifiers.id_sha256, "SHA-256"); + oids.put(NISTObjectIdentifiers.id_sha384, "SHA-384"); + oids.put(NISTObjectIdentifiers.id_sha512, "SHA-512"); + oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128"); + oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160"); + oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-256"); + + asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding"); + + symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap"); + symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap"); + symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap"); + symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap"); + symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap"); + symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap"); + symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap"); + symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap"); + symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap"); + symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); + + symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES"); + symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES"); + symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES"); + symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES"); + symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede"); + symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2"); + } + + private JcaJceHelper helper; + + OperatorHelper(JcaJceHelper helper) + { + this.helper = helper; + } + + Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames) + throws OperatorCreationException + { + try + { + String cipherName = null; + + if (!extraAlgNames.isEmpty()) + { + cipherName = (String)extraAlgNames.get(algorithm); + } + + if (cipherName == null) + { + cipherName = (String)asymmetricWrapperAlgNames.get(algorithm); + } + + if (cipherName != null) + { + try + { + // this is reversed as the Sun policy files now allow unlimited strength RSA + return helper.createCipher(cipherName); + } + catch (NoSuchAlgorithmException e) + { + // try alternate for RSA + if (cipherName.equals("RSA/ECB/PKCS1Padding")) + { + try + { + return helper.createCipher("RSA/NONE/PKCS1Padding"); + } + catch (NoSuchAlgorithmException ex) + { + // Ignore + } + } + // Ignore + } + } + + return helper.createCipher(algorithm.getId()); + } + catch (GeneralSecurityException e) + { + throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); + } + } + + Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm) + throws OperatorCreationException + { + try + { + String cipherName = (String)symmetricWrapperAlgNames.get(algorithm); + + if (cipherName != null) + { + try + { + // this is reversed as the Sun policy files now allow unlimited strength RSA + return helper.createCipher(cipherName); + } + catch (NoSuchAlgorithmException e) + { + // Ignore + } + } + return helper.createCipher(algorithm.getId()); + } + catch (GeneralSecurityException e) + { + throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e); + } + } + + AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId) + throws OperatorCreationException + { + AlgorithmParameters parameters; + + if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) + { + return null; + } + + try + { + parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId()); + } + catch (NoSuchAlgorithmException e) + { + return null; // There's a good chance there aren't any! + } + catch (NoSuchProviderException e) + { + throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e); + } + + try + { + parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded()); + } + catch (IOException e) + { + throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e); + } + + return parameters; + } + + MessageDigest createDigest(AlgorithmIdentifier digAlgId) + throws GeneralSecurityException + { + MessageDigest dig; + + try + { + dig = helper.createDigest(getDigestAlgName(digAlgId.getAlgorithm())); + } + catch (NoSuchAlgorithmException e) + { + // + // try an alternate + // + if (oids.get(digAlgId.getAlgorithm()) != null) + { + String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm()); + + dig = helper.createDigest(digestAlgorithm); + } + else + { + throw e; + } + } + + return dig; + } + + Signature createSignature(AlgorithmIdentifier sigAlgId) + throws GeneralSecurityException + { + Signature sig; + + try + { + sig = helper.createSignature(getSignatureName(sigAlgId)); + } + catch (NoSuchAlgorithmException e) + { + // + // try an alternate + // + if (oids.get(sigAlgId.getAlgorithm()) != null) + { + String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm()); + + sig = helper.createSignature(signatureAlgorithm); + } + else + { + throw e; + } + } + + return sig; + } + + public Signature createRawSignature(AlgorithmIdentifier algorithm) + { + Signature sig; + + try + { + String algName = getSignatureName(algorithm); + + algName = "NONE" + algName.substring(algName.indexOf("WITH")); + + sig = helper.createSignature(algName); + + // RFC 4056 + // When the id-RSASSA-PSS algorithm identifier is used for a signature, + // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. +/* + if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) + { + AlgorithmParameters params = helper.createAlgorithmParameters(algName); + + JcaJceUtils.loadParameters(params, algorithm.getParameters()); + + PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class); + sig.setParameter(spec); + } +*/ + } + catch (Exception e) + { + return null; + } + + return sig; + } + + private static String getSignatureName( + AlgorithmIdentifier sigAlgId) + { + ASN1Encodable params = sigAlgId.getParameters(); + + if (params != null && !DERNull.INSTANCE.equals(params)) + { + if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) + { + RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); + return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1"; + } + } + + if (oids.containsKey(sigAlgId.getAlgorithm())) + { + return (String)oids.get(sigAlgId.getAlgorithm()); + } + + return sigAlgId.getAlgorithm().getId(); + } + + private static String getDigestAlgName( + ASN1ObjectIdentifier digestAlgOID) + { + if (PKCSObjectIdentifiers.md5.equals(digestAlgOID)) + { + return "MD5"; + } + else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID)) + { + return "SHA512"; + } + else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.getId(); + } + } + + public X509Certificate convertCertificate(X509CertificateHolder certHolder) + throws CertificateException + { + + try + { + CertificateFactory certFact = helper.createCertificateFactory("X.509"); + + return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded())); + } + catch (IOException e) + { + throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e); + } + catch (NoSuchAlgorithmException e) + { + throw new OpCertificateException("cannot create certificate factory: " + e.getMessage(), e); + } + catch (NoSuchProviderException e) + { + throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e); + } + } + + public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo) + throws OperatorCreationException + { + try + { + KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId()); + + return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded())); + } + catch (IOException e) + { + throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e); + } + catch (NoSuchAlgorithmException e) + { + throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e); + } + catch (NoSuchProviderException e) + { + throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e); + } + catch (InvalidKeySpecException e) + { + throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e); + } + } + + // TODO: put somewhere public so cause easily accessed + private static class OpCertificateException + extends CertificateException + { + private Throwable cause; + + public OpCertificateException(String msg, Throwable cause) + { + super(msg); + + this.cause = cause; + } + + public Throwable getCause() + { + return cause; + } + } + + String getKeyAlgorithmName(ASN1ObjectIdentifier oid) + { + + String name = (String)symmetricKeyAlgNames.get(oid); + + if (name != null) + { + return name; + } + + return oid.getId(); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java new file mode 100644 index 00000000..2e0000e0 --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java @@ -0,0 +1,25 @@ +package org.spongycastle.pkcs.jcajce; + +import java.security.PublicKey; + +import org.spongycastle.asn1.x500.X500Name; +import org.spongycastle.asn1.x509.SubjectPublicKeyInfo; +import org.spongycastle.pkcs.PKCS10CertificationRequestBuilder; + +/** + * Extension of the PKCS#10 builder to support PublicKey and X500Principal objects. + */ +public class JcaPKCS10CertificationRequestBuilder + extends PKCS10CertificationRequestBuilder +{ + /** + * Create a PKCS#10 builder for the passed in subject and JCA public key. + * + * @param subject an X500Name containing the subject associated with the request we are building. + * @param publicKey a JCA public key that is to be associated with the request we are building. + */ + public JcaPKCS10CertificationRequestBuilder(X500Name subject, PublicKey publicKey) + { + super(subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java new file mode 100644 index 00000000..0b5cb6fd --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java @@ -0,0 +1,204 @@ +package org.spongycastle.tsp.cms; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.MalformedURLException; + +import org.spongycastle.asn1.ASN1InputStream; +import org.spongycastle.asn1.DERIA5String; +import org.spongycastle.asn1.cms.AttributeTable; +import org.spongycastle.asn1.cms.CMSObjectIdentifiers; +import org.spongycastle.asn1.cms.ContentInfo; +import org.spongycastle.asn1.cms.Evidence; +import org.spongycastle.asn1.cms.TimeStampAndCRL; +import org.spongycastle.asn1.cms.TimeStampTokenEvidence; +import org.spongycastle.asn1.cms.TimeStampedData; +import org.spongycastle.cms.CMSException; +import org.spongycastle.operator.DigestCalculator; +import org.spongycastle.operator.DigestCalculatorProvider; +import org.spongycastle.operator.OperatorCreationException; +import org.spongycastle.tsp.TimeStampToken; + +public class CMSTimeStampedData +{ + private TimeStampedData timeStampedData; + private ContentInfo contentInfo; + private TimeStampDataUtil util; + + public CMSTimeStampedData(ContentInfo contentInfo) + { + this.initialize(contentInfo); + } + + public CMSTimeStampedData(InputStream in) + throws IOException + { + try + { + initialize(ContentInfo.getInstance(new ASN1InputStream(in).readObject())); + } + catch (ClassCastException e) + { + throw new IOException("Malformed content: " + e); + } + catch (IllegalArgumentException e) + { + throw new IOException("Malformed content: " + e); + } + } + + public CMSTimeStampedData(byte[] baseData) + throws IOException + { + this(new ByteArrayInputStream(baseData)); + } + + private void initialize(ContentInfo contentInfo) + { + this.contentInfo = contentInfo; + + if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) + { + this.timeStampedData = TimeStampedData.getInstance(contentInfo.getContent()); + } + else + { + throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); + } + + util = new TimeStampDataUtil(this.timeStampedData); + } + + public byte[] calculateNextHash(DigestCalculator calculator) + throws CMSException + { + return util.calculateNextHash(calculator); + } + + /** + * Return a new timeStampedData object with the additional token attached. + * + * @throws CMSException + */ + public CMSTimeStampedData addTimeStamp(TimeStampToken token) + throws CMSException + { + TimeStampAndCRL[] timeStamps = util.getTimeStamps(); + TimeStampAndCRL[] newTimeStamps = new TimeStampAndCRL[timeStamps.length + 1]; + + System.arraycopy(timeStamps, 0, newTimeStamps, 0, timeStamps.length); + + newTimeStamps[timeStamps.length] = new TimeStampAndCRL(token.toCMSSignedData().toASN1Structure()); + + return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUri(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps))))); + } + + public byte[] getContent() + { + if (timeStampedData.getContent() != null) + { + return timeStampedData.getContent().getOctets(); + } + + return null; + } + + public URL getDataUri() + throws MalformedURLException + { + DERIA5String dataURI = this.timeStampedData.getDataUri(); + + if (dataURI != null) + { + return new URL(dataURI.getString()); + } + + return null; + } + + public String getFileName() + { + return util.getFileName(); + } + + public String getMediaType() + { + return util.getMediaType(); + } + + public AttributeTable getOtherMetaData() + { + return util.getOtherMetaData(); + } + + public TimeStampToken[] getTimeStampTokens() + throws CMSException + { + return util.getTimeStampTokens(); + } + + /** + * Initialise the passed in calculator with the MetaData for this message, if it is + * required as part of the initial message imprint calculation. + * + * @param calculator the digest calculator to be initialised. + * @throws CMSException if the MetaData is required and cannot be processed + */ + public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) + throws CMSException + { + util.initialiseMessageImprintDigestCalculator(calculator); + } + + /** + * Returns an appropriately initialised digest calculator based on the message imprint algorithm + * described in the first time stamp in the TemporalData for this message. If the metadata is required + * to be included in the digest calculation, the returned calculator will be pre-initialised. + * + * @param calculatorProvider a provider of DigestCalculator objects. + * @return an initialised digest calculator. + * @throws OperatorCreationException if the provider is unable to create the calculator. + */ + public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) + throws OperatorCreationException + { + return util.getMessageImprintDigestCalculator(calculatorProvider); + } + + /** + * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. + * + * @param calculatorProvider provider for digest calculators + * @param dataDigest the calculated data digest for the message + * @throws ImprintDigestInvalidException if an imprint digest fails to compare + * @throws CMSException if an exception occurs processing the message. + */ + public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) + throws ImprintDigestInvalidException, CMSException + { + util.validate(calculatorProvider, dataDigest); + } + + /** + * Validate the passed in timestamp token against the tokens and data present in the message. + * + * @param calculatorProvider provider for digest calculators + * @param dataDigest the calculated data digest for the message. + * @param timeStampToken the timestamp token of interest. + * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. + * @throws CMSException if an exception occurs processing the message. + */ + public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) + throws ImprintDigestInvalidException, CMSException + { + util.validate(calculatorProvider, dataDigest, timeStampToken); + } + + public byte[] getEncoded() + throws IOException + { + return contentInfo.getEncoded(); + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java new file mode 100644 index 00000000..2b1a695f --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java @@ -0,0 +1,207 @@ +package org.spongycastle.tsp.cms; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import org.spongycastle.asn1.BERTags; +import org.spongycastle.asn1.DERIA5String; +import org.spongycastle.asn1.cms.AttributeTable; +import org.spongycastle.asn1.cms.CMSObjectIdentifiers; +import org.spongycastle.asn1.cms.ContentInfoParser; +import org.spongycastle.asn1.cms.TimeStampedDataParser; +import org.spongycastle.cms.CMSContentInfoParser; +import org.spongycastle.cms.CMSException; +import org.spongycastle.operator.DigestCalculator; +import org.spongycastle.operator.DigestCalculatorProvider; +import org.spongycastle.operator.OperatorCreationException; +import org.spongycastle.tsp.TimeStampToken; +import org.spongycastle.util.io.Streams; + +public class CMSTimeStampedDataParser + extends CMSContentInfoParser +{ + private TimeStampedDataParser timeStampedData; + private TimeStampDataUtil util; + + public CMSTimeStampedDataParser(InputStream in) + throws CMSException + { + super(in); + + initialize(_contentInfo); + } + + public CMSTimeStampedDataParser(byte[] baseData) + throws CMSException + { + this(new ByteArrayInputStream(baseData)); + } + + private void initialize(ContentInfoParser contentInfo) + throws CMSException + { + try + { + if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType())) + { + this.timeStampedData = TimeStampedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE)); + } + else + { + throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId()); + } + } + catch (IOException e) + { + throw new CMSException("parsing exception: " + e.getMessage(), e); + } + } + + public byte[] calculateNextHash(DigestCalculator calculator) + throws CMSException + { + return util.calculateNextHash(calculator); + } + + public InputStream getContent() + { + if (timeStampedData.getContent() != null) + { + return timeStampedData.getContent().getOctetStream(); + } + + return null; + } + + public URL getDataUri() + throws MalformedURLException + { + DERIA5String dataURI = this.timeStampedData.getDataUri(); + + if (dataURI != null) + { + return new URL(dataURI.getString()); + } + + return null; + } + + /** + * Initialise the passed in calculator with the MetaData for this message, if it is + * required as part of the initial message imprint calculation. + * + * @param calculator the digest calculator to be initialised. + * @throws CMSException if the MetaData is required and cannot be processed + */ + public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) + throws CMSException + { + util.initialiseMessageImprintDigestCalculator(calculator); + } + + /** + * Returns an appropriately initialised digest calculator based on the message imprint algorithm + * described in the first time stamp in the TemporalData for this message. If the metadata is required + * to be included in the digest calculation, the returned calculator will be pre-initialised. + * + * @param calculatorProvider a provider of DigestCalculator objects. + * @return an initialised digest calculator. + * @throws OperatorCreationException if the provider is unable to create the calculator. + */ + public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider) + throws OperatorCreationException + { + try + { + parseTimeStamps(); + } + catch (CMSException e) + { + throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e); + } + + return util.getMessageImprintDigestCalculator(calculatorProvider); + } + + public String getFileName() + { + return util.getFileName(); + } + + public String getMediaType() + { + return util.getMediaType(); + } + + public AttributeTable getOtherMetaData() + { + return util.getOtherMetaData(); + } + + public TimeStampToken[] getTimeStampTokens() + throws CMSException + { + parseTimeStamps(); + + return util.getTimeStampTokens(); + } + + /** + * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData. + * + * @param calculatorProvider provider for digest calculators + * @param dataDigest the calculated data digest for the message + * @throws ImprintDigestInvalidException if an imprint digest fails to compare + * @throws CMSException if an exception occurs processing the message. + */ + public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest) + throws ImprintDigestInvalidException, CMSException + { + parseTimeStamps(); + + util.validate(calculatorProvider, dataDigest); + } + + /** + * Validate the passed in timestamp token against the tokens and data present in the message. + * + * @param calculatorProvider provider for digest calculators + * @param dataDigest the calculated data digest for the message. + * @param timeStampToken the timestamp token of interest. + * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare. + * @throws CMSException if an exception occurs processing the message. + */ + public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken) + throws ImprintDigestInvalidException, CMSException + { + parseTimeStamps(); + + util.validate(calculatorProvider, dataDigest, timeStampToken); + } + + private void parseTimeStamps() + throws CMSException + { + try + { + if (util == null) + { + InputStream cont = this.getContent(); + + if (cont != null) + { + Streams.drain(cont); + } + + util = new TimeStampDataUtil(timeStampedData); + } + } + catch (IOException e) + { + throw new CMSException("unable to parse evidence block: " + e.getMessage(), e); + } + } +} diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java new file mode 100644 index 00000000..614a744b --- /dev/null +++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java @@ -0,0 +1,90 @@ +package org.spongycastle.tsp.cms; + +import java.net.URL; + +import org.spongycastle.asn1.ASN1Boolean; +import org.spongycastle.asn1.DERBoolean; +import org.spongycastle.asn1.DERIA5String; +import org.spongycastle.asn1.DERUTF8String; +import org.spongycastle.asn1.cms.Attributes; +import org.spongycastle.asn1.cms.MetaData; +import org.spongycastle.cms.CMSException; +import org.spongycastle.operator.DigestCalculator; +import org.spongycastle.util.Integers; + +public class CMSTimeStampedGenerator +{ + protected MetaData metaData; + protected URL dataUri; + + /** + * Set the dataURL to be included in message. + * + * @param dataUri URL for the data the initial message imprint digest is based on. + */ + public void setDataUri(URL dataUri) + { + this.dataUri = dataUri; + } + + /** + * Set the MetaData for the generated message. + * + * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. + * @param fileName optional file name, may be null. + * @param mediaType optional media type, may be null. + */ + public void setMetaData(boolean hashProtected, String fileName, String mediaType) + { + setMetaData(hashProtected, fileName, mediaType, null); + } + + /** + * Set the MetaData for the generated message. + * + * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise. + * @param fileName optional file name, may be null. + * @param mediaType optional media type, may be null. + * @param attributes optional attributes, may be null. + */ + public void setMetaData(boolean hashProtected, String fileName, String mediaType, Attributes attributes) + { + DERUTF8String asn1FileName = null; + + if (fileName != null) + { + asn1FileName = new DERUTF8String(fileName); + } + + DERIA5String asn1MediaType = null; + + if (mediaType != null) + { + asn1MediaType = new DERIA5String(mediaType); + } + + setMetaData(hashProtected, asn1FileName, asn1MediaType, attributes); + } + + private void setMetaData(boolean hashProtected, DERUTF8String fileName, DERIA5String mediaType, Attributes attributes) + { + this.metaData = new MetaData(ASN1Boolean.getInstance(hashProtected), fileName, mediaType, attributes); + } + + /** + * Initialise the passed in calculator with the MetaData for this message, if it is + * required as part of the initial message imprint calculation. After initialisation the + * calculator can then be used to calculate the initial message imprint digest for the first + * timestamp. + * + * @param calculator the digest calculator to be initialised. + * @throws CMSException if the MetaData is required and cannot be processed + */ + public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator) + throws CMSException + { + MetaDataUtil util = new MetaDataUtil(metaData); + + util.initialiseMessageImprintDigestCalculator(calculator); + } +} |