diff options
Diffstat (limited to 'prov/src/main/jdk1.3/org/spongycastle/jce/PKCS10CertificationRequest.java')
-rw-r--r-- | prov/src/main/jdk1.3/org/spongycastle/jce/PKCS10CertificationRequest.java | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/prov/src/main/jdk1.3/org/spongycastle/jce/PKCS10CertificationRequest.java b/prov/src/main/jdk1.3/org/spongycastle/jce/PKCS10CertificationRequest.java new file mode 100644 index 00000000..b9bc6e52 --- /dev/null +++ b/prov/src/main/jdk1.3/org/spongycastle/jce/PKCS10CertificationRequest.java @@ -0,0 +1,583 @@ +package org.spongycastle.jce; + +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Set; + +import org.spongycastle.asn1.ASN1Encodable; +import org.spongycastle.asn1.ASN1Encoding; +import org.spongycastle.asn1.ASN1InputStream; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.ASN1Set; +import org.spongycastle.asn1.DERBitString; +import org.spongycastle.asn1.DERNull; +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import org.spongycastle.asn1.nist.NISTObjectIdentifiers; +import org.spongycastle.asn1.oiw.OIWObjectIdentifiers; +import org.spongycastle.asn1.pkcs.CertificationRequest; +import org.spongycastle.asn1.pkcs.CertificationRequestInfo; +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.x509.X509Name; +import org.spongycastle.asn1.x9.X9ObjectIdentifiers; +import org.spongycastle.jce.provider.BouncyCastleProvider; +import org.spongycastle.util.Strings; + +/** + * A class for verifying and creating PKCS10 Certification requests. + * <pre> + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + * signature BIT STRING + * } + * + * CertificationRequestInfo ::= SEQUENCE { + * version INTEGER { v1(0) } (v1,...), + * subject Name, + * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, + * attributes [0] Attributes{{ CRIAttributes }} + * } + * + * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }} + * + * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { + * type ATTRIBUTE.&id({IOSet}), + * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) + * } + * </pre> + * @deprecated use classes in org.spongycastle.pkcs. + */ +public class PKCS10CertificationRequest + extends CertificationRequest +{ + private static Hashtable algorithms = new Hashtable(); + private static Hashtable params = new Hashtable(); + private static Hashtable keyAlgorithms = new Hashtable(); + private static Hashtable oids = new Hashtable(); + private static Set noParams = new HashSet(); + + static + { + algorithms.put("MD2WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.2")); + algorithms.put("MD2WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.2")); + algorithms.put("MD5WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4")); + algorithms.put("MD5WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4")); + algorithms.put("RSAWITHMD5", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4")); + algorithms.put("SHA1WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5")); + algorithms.put("SHA1WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5")); + algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); + algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); + algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); + algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); + algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); + algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); + algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); + algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); + algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); + algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); + algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); + algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); + algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); + algorithms.put("RSAWITHSHA1", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5")); + algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); + algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); + algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); + algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); + algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); + algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); + algorithms.put("SHA1WITHDSA", new ASN1ObjectIdentifier("1.2.840.10040.4.3")); + algorithms.put("DSAWITHSHA1", new ASN1ObjectIdentifier("1.2.840.10040.4.3")); + algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); + algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); + algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); + algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); + algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); + algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); + algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); + algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); + algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); + algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); + algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); + algorithms.put("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); + algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); + algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); + algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); + + // + // 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"); + + // + // key types + // + keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); + keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA"); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); + noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); + noParams.add(NISTObjectIdentifiers.dsa_with_sha224); + noParams.add(NISTObjectIdentifiers.dsa_with_sha256); + + // + // RFC 4491 + // + noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); + noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull()); + params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull()); + params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull()); + params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull()); + params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull()); + params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); + } + + private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) + { + return new RSASSAPSSparams( + hashAlgId, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), + new ASN1Integer(saltSize), + new ASN1Integer(1)); + } + + private static ASN1Sequence toDERSequence( + byte[] bytes) + { + try + { + ASN1InputStream dIn = new ASN1InputStream(bytes); + + return (ASN1Sequence)dIn.readObject(); + } + catch (Exception e) + { + throw new IllegalArgumentException("badly encoded request"); + } + } + + /** + * construct a PKCS10 certification request from a DER encoded + * byte stream. + */ + public PKCS10CertificationRequest( + byte[] bytes) + { + super(toDERSequence(bytes)); + } + + public PKCS10CertificationRequest( + ASN1Sequence sequence) + { + super(sequence); + } + + /** + * create a PKCS10 certfication request using the BC provider. + */ + public PKCS10CertificationRequest( + String signatureAlgorithm, + X509Name subject, + PublicKey key, + ASN1Set attributes, + PrivateKey signingKey) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException + { + this(signatureAlgorithm, subject, key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME); + } + + + /** + * create a PKCS10 certfication request using the named provider. + */ + public PKCS10CertificationRequest( + String signatureAlgorithm, + X509Name subject, + PublicKey key, + ASN1Set attributes, + PrivateKey signingKey, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException + { + String algorithmName = Strings.toUpperCase(signatureAlgorithm); + ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName); + + if (sigOID == null) + { + try + { + sigOID = new ASN1ObjectIdentifier(algorithmName); + } + catch (Exception e) + { + throw new IllegalArgumentException("Unknown signature type requested"); + } + } + + if (subject == null) + { + throw new IllegalArgumentException("subject must not be null"); + } + + if (key == null) + { + throw new IllegalArgumentException("public key must not be null"); + } + + if (noParams.contains(sigOID)) + { + this.sigAlgId = new AlgorithmIdentifier(sigOID); + } + else if (params.containsKey(algorithmName)) + { + this.sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName)); + } + else + { + this.sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE); + } + + try + { + ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded()); + this.reqInfo = new CertificationRequestInfo(subject, new SubjectPublicKeyInfo(seq), attributes); + } + catch (IOException e) + { + throw new IllegalArgumentException("can't encode public key"); + } + + Signature sig; + if (provider == null) + { + sig = Signature.getInstance(signatureAlgorithm); + } + else + { + sig = Signature.getInstance(signatureAlgorithm, provider); + } + + sig.initSign(signingKey); + + try + { + sig.update(reqInfo.getEncoded(ASN1Encoding.DER)); + } + catch (Exception e) + { + throw new IllegalArgumentException("exception encoding TBS cert request - " + e); + } + + this.sigBits = new DERBitString(sig.sign()); + } + + /** + * return the public key associated with the certification request - + * the public key is created using the BC provider. + */ + public PublicKey getPublicKey() + throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException + { + return getPublicKey(BouncyCastleProvider.PROVIDER_NAME); + } + + public PublicKey getPublicKey( + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException + { + SubjectPublicKeyInfo subjectPKInfo = reqInfo.getSubjectPublicKeyInfo(); + + + try + { + X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); + AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm(); + try + { + if (provider == null) + { + return KeyFactory.getInstance(keyAlg.getAlgorithm().getId()).generatePublic(xspec); + } + else + { + return KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), provider).generatePublic(xspec); + } + } + catch (NoSuchAlgorithmException e) + { + // + // try an alternate + // + if (keyAlgorithms.get(keyAlg.getObjectId()) != null) + { + String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getObjectId()); + + if (provider == null) + { + return KeyFactory.getInstance(keyAlgorithm).generatePublic(xspec); + } + else + { + return KeyFactory.getInstance(keyAlgorithm, provider).generatePublic(xspec); + } + } + + throw e; + } + } + catch (InvalidKeySpecException e) + { + throw new InvalidKeyException("error decoding public key"); + } + catch (IOException e) + { + throw new InvalidKeyException("error decoding public key"); + } + } + + /** + * verify the request using the BC provider. + */ + public boolean verify() + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException + { + return verify(BouncyCastleProvider.PROVIDER_NAME); + } + + /** + * verify the request using the passed in provider. + */ + public boolean verify( + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException + { + return verify(this.getPublicKey(provider), provider); + } + + /** + * verify the request using the passed in public key and the provider.. + */ + public boolean verify( + PublicKey pubKey, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException, SignatureException + { + Signature sig; + + try + { + if (provider == null) + { + sig = Signature.getInstance(getSignatureName(sigAlgId)); + } + else + { + sig = Signature.getInstance(getSignatureName(sigAlgId), provider); + } + } + catch (NoSuchAlgorithmException e) + { + // + // try an alternate + // + if (oids.get(sigAlgId.getObjectId()) != null) + { + String signatureAlgorithm = (String)oids.get(sigAlgId.getObjectId()); + + if (provider == null) + { + sig = Signature.getInstance(signatureAlgorithm); + } + else + { + sig = Signature.getInstance(signatureAlgorithm, provider); + } + } + else + { + throw e; + } + } + + setSignatureParameters(sig, sigAlgId.getParameters(), provider); + + sig.initVerify(pubKey); + + try + { + sig.update(reqInfo.getEncoded(ASN1Encoding.DER)); + } + catch (Exception e) + { + throw new SignatureException("exception encoding TBS cert request - " + e); + } + + return sig.verify(sigBits.getBytes()); + } + + /** + * return a DER encoded byte array representing this object + */ + public byte[] getEncoded() + { + try + { + return this.getEncoded(ASN1Encoding.DER); + } + catch (IOException e) + { + throw new RuntimeException(e.toString()); + } + } + + private void setSignatureParameters( + Signature signature, + ASN1Encodable params, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException, SignatureException, InvalidKeyException + { + if (params != null && !DERNull.INSTANCE.equals(params)) + { + AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), provider); + + try + { + sigParams.init(params.toASN1Primitive().getEncoded(ASN1Encoding.DER)); + } + catch (IOException e) + { + throw new SignatureException("IOException decoding parameters: " + e.getMessage()); + } + } + } + + static String getSignatureName( + AlgorithmIdentifier sigAlgId) + { + ASN1Encodable params = sigAlgId.getParameters(); + + if (params != null && !DERNull.INSTANCE.equals(params)) + { + if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) + { + RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params); + return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1"; + } + } + + return sigAlgId.getObjectId().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(); + } + } +} |