diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-21 20:05:33 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-21 20:05:33 +0700 |
commit | 0373cfe00e805772ca49ab459900b986bd83f23c (patch) | |
tree | 97d0d655cf7d129cb77b9045b4053109bfa14fe8 /crypto/src | |
parent | Remove DerUnknownTag class (diff) | |
download | BouncyCastle.NET-ed25519-0373cfe00e805772ca49ab459900b986bd83f23c.tar.xz |
Fix up openssl test cases
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/openssl/PEMReader.cs | 706 |
1 files changed, 353 insertions, 353 deletions
diff --git a/crypto/src/openssl/PEMReader.cs b/crypto/src/openssl/PEMReader.cs index a2fedab96..b3a1177ce 100644 --- a/crypto/src/openssl/PEMReader.cs +++ b/crypto/src/openssl/PEMReader.cs @@ -23,20 +23,20 @@ using Org.BouncyCastle.X509; namespace Org.BouncyCastle.OpenSsl { - /** - * Class for reading OpenSSL PEM encoded streams containing - * X509 certificates, PKCS8 encoded keys and PKCS7 objects. - * <p> - * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and - * Certificates will be returned using the appropriate java.security type.</p> - */ - public class PemReader - : Org.BouncyCastle.Utilities.IO.Pem.PemReader - { + /** + * Class for reading OpenSSL PEM encoded streams containing + * X509 certificates, PKCS8 encoded keys and PKCS7 objects. + * <p> + * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and + * Certificates will be returned using the appropriate java.security type.</p> + */ + public class PemReader + : Org.BouncyCastle.Utilities.IO.Pem.PemReader + { // private static readonly IDictionary parsers = new Hashtable(); - static PemReader() - { + static PemReader() + { // parsers.Add("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); // parsers.Add("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); // parsers.Add("CERTIFICATE", new X509CertificateParser(provider)); @@ -52,323 +52,323 @@ namespace Org.BouncyCastle.OpenSsl // parsers.Add("EC PRIVATE KEY", new ECDSAKeyPairParser(provider)); // parsers.Add("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser(provider)); // parsers.Add("PRIVATE KEY", new PrivateKeyParser(provider)); - } - - private readonly IPasswordFinder pFinder; - - /** - * Create a new PemReader - * - * @param reader the Reader - */ - public PemReader( - TextReader reader) - : this(reader, null) - { - } - - /** - * Create a new PemReader with a password finder - * - * @param reader the Reader - * @param pFinder the password finder - */ - public PemReader( - TextReader reader, - IPasswordFinder pFinder) - : base(reader) - { - this.pFinder = pFinder; - } - - public object ReadObject() - { - PemObject obj = ReadPemObject(); - - if (obj == null) - return null; - - // TODO Follow Java build and map to parser objects? + } + + private readonly IPasswordFinder pFinder; + + /** + * Create a new PemReader + * + * @param reader the Reader + */ + public PemReader( + TextReader reader) + : this(reader, null) + { + } + + /** + * Create a new PemReader with a password finder + * + * @param reader the Reader + * @param pFinder the password finder + */ + public PemReader( + TextReader reader, + IPasswordFinder pFinder) + : base(reader) + { + this.pFinder = pFinder; + } + + public object ReadObject() + { + PemObject obj = ReadPemObject(); + + if (obj == null) + return null; + + // TODO Follow Java build and map to parser objects? // if (parsers.Contains(obj.Type)) // return ((PemObjectParser)parsers[obj.Type]).ParseObject(obj); - if (obj.Type.EndsWith("PRIVATE KEY")) - return ReadPrivateKey(obj); - - switch (obj.Type) - { - case "PUBLIC KEY": - return ReadPublicKey(obj); - case "RSA PUBLIC KEY": - return ReadRsaPublicKey(obj); - case "CERTIFICATE REQUEST": - case "NEW CERTIFICATE REQUEST": - return ReadCertificateRequest(obj); - case "CERTIFICATE": - case "X509 CERTIFICATE": - return ReadCertificate(obj); - case "PKCS7": - return ReadPkcs7(obj); - case "X509 CRL": - return ReadCrl(obj); - case "ATTRIBUTE CERTIFICATE": - return ReadAttributeCertificate(obj); - // TODO Add back in when tests done, and return type issue resolved - //case "EC PARAMETERS": - // return ReadECParameters(obj); - default: - throw new IOException("unrecognised object: " + obj.Type); - } - } - - private AsymmetricKeyParameter ReadRsaPublicKey(PemObject pemObject) - { - RsaPublicKeyStructure rsaPubStructure = RsaPublicKeyStructure.GetInstance( - Asn1Object.FromByteArray(pemObject.Content)); - - return new RsaKeyParameters( - false, // not private - rsaPubStructure.Modulus, - rsaPubStructure.PublicExponent); - } - - private AsymmetricKeyParameter ReadPublicKey(PemObject pemObject) - { - return PublicKeyFactory.CreateKey(pemObject.Content); - } - - /** - * Reads in a X509Certificate. - * - * @return the X509Certificate - * @throws IOException if an I/O error occured - */ - private X509Certificate ReadCertificate(PemObject pemObject) - { - try - { - return new X509CertificateParser().ReadCertificate(pemObject.Content); - } - catch (Exception e) - { - throw new PemException("problem parsing cert: " + e.ToString()); - } - } - - /** - * Reads in a X509CRL. - * - * @return the X509Certificate - * @throws IOException if an I/O error occured - */ - private X509Crl ReadCrl(PemObject pemObject) - { - try - { - return new X509CrlParser().ReadCrl(pemObject.Content); - } - catch (Exception e) - { - throw new PemException("problem parsing cert: " + e.ToString()); - } - } - - /** - * Reads in a PKCS10 certification request. - * - * @return the certificate request. - * @throws IOException if an I/O error occured - */ - private Pkcs10CertificationRequest ReadCertificateRequest(PemObject pemObject) - { - try - { - return new Pkcs10CertificationRequest(pemObject.Content); - } - catch (Exception e) - { - throw new PemException("problem parsing cert: " + e.ToString()); - } - } - - /** - * Reads in a X509 Attribute Certificate. - * - * @return the X509 Attribute Certificate - * @throws IOException if an I/O error occured - */ - private IX509AttributeCertificate ReadAttributeCertificate(PemObject pemObject) - { - return new X509V2AttributeCertificate(pemObject.Content); - } - - /** - * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS - * API. - * - * @return the X509Certificate - * @throws IOException if an I/O error occured - */ - // TODO Consider returning Asn1.Pkcs.ContentInfo - private Asn1.Cms.ContentInfo ReadPkcs7(PemObject pemObject) - { - try - { - return Asn1.Cms.ContentInfo.GetInstance( - Asn1Object.FromByteArray(pemObject.Content)); - } - catch (Exception e) - { - throw new PemException("problem parsing PKCS7 object: " + e.ToString()); - } - } - - /** - * Read a Key Pair - */ - private object ReadPrivateKey(PemObject pemObject) - { - // - // extract the key - // - Debug.Assert(pemObject.Type.EndsWith("PRIVATE KEY")); - - string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); - byte[] keyBytes = pemObject.Content; - - IDictionary fields = Platform.CreateHashtable(); - foreach (PemHeader header in pemObject.Headers) - { - fields[header.Name] = header.Value; - } - - string procType = (string) fields["Proc-Type"]; - - if (procType == "4,ENCRYPTED") - { - if (pFinder == null) - throw new PasswordException("No password finder specified, but a password is required"); - - char[] password = pFinder.GetPassword(); - - if (password == null) - throw new PasswordException("Password is null, but a password is required"); - - string dekInfo = (string) fields["DEK-Info"]; - string[] tknz = dekInfo.Split(','); - - string dekAlgName = tknz[0].Trim(); - byte[] iv = Hex.Decode(tknz[1].Trim()); - - keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); - } - - try - { - AsymmetricKeyParameter pubSpec, privSpec; - Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(keyBytes); - - switch (type) - { - case "RSA": - { - if (seq.Count != 9) - throw new PemException("malformed sequence in RSA private key"); - - RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); - - pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); - privSpec = new RsaPrivateCrtKeyParameters( - rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, - rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, - rsa.Coefficient); - - break; - } - - case "DSA": - { - if (seq.Count != 6) - throw new PemException("malformed sequence in DSA private key"); - - // TODO Create an ASN1 object somewhere for this? - //DerInteger v = (DerInteger)seq[0]; - DerInteger p = (DerInteger)seq[1]; - DerInteger q = (DerInteger)seq[2]; - DerInteger g = (DerInteger)seq[3]; - DerInteger y = (DerInteger)seq[4]; - DerInteger x = (DerInteger)seq[5]; - - DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); - - privSpec = new DsaPrivateKeyParameters(x.Value, parameters); - pubSpec = new DsaPublicKeyParameters(y.Value, parameters); - - break; - } - - case "EC": - { - ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq); - AlgorithmIdentifier algId = new AlgorithmIdentifier( - X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); - - PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); - - // TODO Are the keys returned here ECDSA, as Java version forces? - privSpec = PrivateKeyFactory.CreateKey(privInfo); - - DerBitString pubKey = pKey.GetPublicKey(); - if (pubKey != null) - { - SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes()); - - // TODO Are the keys returned here ECDSA, as Java version forces? - pubSpec = PublicKeyFactory.CreateKey(pubInfo); - } - else - { - pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey( - (ECPrivateKeyParameters)privSpec); - } - - break; - } - - case "ENCRYPTED": - { - char[] password = pFinder.GetPassword(); - - if (password == null) - throw new PasswordException("Password is null, but a password is required"); - - return PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)); - } - - case "": - { - return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)); - } - - default: - throw new ArgumentException("Unknown key type: " + type, "type"); - } - - return new AsymmetricCipherKeyPair(pubSpec, privSpec); - } - catch (IOException e) - { - throw e; - } - catch (Exception e) - { - throw new PemException( - "problem creating " + type + " private key: " + e.ToString()); - } - } - - // TODO Add an equivalent class for ECNamedCurveParameterSpec? - //private ECNamedCurveParameterSpec ReadECParameters( + if (obj.Type.EndsWith("PRIVATE KEY")) + return ReadPrivateKey(obj); + + switch (obj.Type) + { + case "PUBLIC KEY": + return ReadPublicKey(obj); + case "RSA PUBLIC KEY": + return ReadRsaPublicKey(obj); + case "CERTIFICATE REQUEST": + case "NEW CERTIFICATE REQUEST": + return ReadCertificateRequest(obj); + case "CERTIFICATE": + case "X509 CERTIFICATE": + return ReadCertificate(obj); + case "PKCS7": + return ReadPkcs7(obj); + case "X509 CRL": + return ReadCrl(obj); + case "ATTRIBUTE CERTIFICATE": + return ReadAttributeCertificate(obj); + // TODO Add back in when tests done, and return type issue resolved + //case "EC PARAMETERS": + // return ReadECParameters(obj); + default: + throw new IOException("unrecognised object: " + obj.Type); + } + } + + private AsymmetricKeyParameter ReadRsaPublicKey(PemObject pemObject) + { + RsaPublicKeyStructure rsaPubStructure = RsaPublicKeyStructure.GetInstance( + Asn1Object.FromByteArray(pemObject.Content)); + + return new RsaKeyParameters( + false, // not private + rsaPubStructure.Modulus, + rsaPubStructure.PublicExponent); + } + + private AsymmetricKeyParameter ReadPublicKey(PemObject pemObject) + { + return PublicKeyFactory.CreateKey(pemObject.Content); + } + + /** + * Reads in a X509Certificate. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Certificate ReadCertificate(PemObject pemObject) + { + try + { + return new X509CertificateParser().ReadCertificate(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509CRL. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Crl ReadCrl(PemObject pemObject) + { + try + { + return new X509CrlParser().ReadCrl(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a PKCS10 certification request. + * + * @return the certificate request. + * @throws IOException if an I/O error occured + */ + private Pkcs10CertificationRequest ReadCertificateRequest(PemObject pemObject) + { + try + { + return new Pkcs10CertificationRequest(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509 Attribute Certificate. + * + * @return the X509 Attribute Certificate + * @throws IOException if an I/O error occured + */ + private IX509AttributeCertificate ReadAttributeCertificate(PemObject pemObject) + { + return new X509V2AttributeCertificate(pemObject.Content); + } + + /** + * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS + * API. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + // TODO Consider returning Asn1.Pkcs.ContentInfo + private Asn1.Cms.ContentInfo ReadPkcs7(PemObject pemObject) + { + try + { + return Asn1.Cms.ContentInfo.GetInstance( + Asn1Object.FromByteArray(pemObject.Content)); + } + catch (Exception e) + { + throw new PemException("problem parsing PKCS7 object: " + e.ToString()); + } + } + + /** + * Read a Key Pair + */ + private object ReadPrivateKey(PemObject pemObject) + { + // + // extract the key + // + Debug.Assert(pemObject.Type.EndsWith("PRIVATE KEY")); + + string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); + byte[] keyBytes = pemObject.Content; + + IDictionary fields = Platform.CreateHashtable(); + foreach (PemHeader header in pemObject.Headers) + { + fields[header.Name] = header.Value; + } + + string procType = (string) fields["Proc-Type"]; + + if (procType == "4,ENCRYPTED") + { + if (pFinder == null) + throw new PasswordException("No password finder specified, but a password is required"); + + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new PasswordException("Password is null, but a password is required"); + + string dekInfo = (string) fields["DEK-Info"]; + string[] tknz = dekInfo.Split(','); + + string dekAlgName = tknz[0].Trim(); + byte[] iv = Hex.Decode(tknz[1].Trim()); + + keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); + } + + try + { + AsymmetricKeyParameter pubSpec, privSpec; + Asn1Sequence seq = Asn1Sequence.GetInstance(keyBytes); + + switch (type) + { + case "RSA": + { + if (seq.Count != 9) + throw new PemException("malformed sequence in RSA private key"); + + RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); + + pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); + privSpec = new RsaPrivateCrtKeyParameters( + rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, + rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, + rsa.Coefficient); + + break; + } + + case "DSA": + { + if (seq.Count != 6) + throw new PemException("malformed sequence in DSA private key"); + + // TODO Create an ASN1 object somewhere for this? + //DerInteger v = (DerInteger)seq[0]; + DerInteger p = (DerInteger)seq[1]; + DerInteger q = (DerInteger)seq[2]; + DerInteger g = (DerInteger)seq[3]; + DerInteger y = (DerInteger)seq[4]; + DerInteger x = (DerInteger)seq[5]; + + DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); + + privSpec = new DsaPrivateKeyParameters(x.Value, parameters); + pubSpec = new DsaPublicKeyParameters(y.Value, parameters); + + break; + } + + case "EC": + { + ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq); + AlgorithmIdentifier algId = new AlgorithmIdentifier( + X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); + + PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + privSpec = PrivateKeyFactory.CreateKey(privInfo); + + DerBitString pubKey = pKey.GetPublicKey(); + if (pubKey != null) + { + SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + pubSpec = PublicKeyFactory.CreateKey(pubInfo); + } + else + { + pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey( + (ECPrivateKeyParameters)privSpec); + } + + break; + } + + case "ENCRYPTED": + { + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new PasswordException("Password is null, but a password is required"); + + return PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)); + } + + case "": + { + return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)); + } + + default: + throw new ArgumentException("Unknown key type: " + type, "type"); + } + + return new AsymmetricCipherKeyPair(pubSpec, privSpec); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new PemException( + "problem creating " + type + " private key: " + e.ToString()); + } + } + + // TODO Add an equivalent class for ECNamedCurveParameterSpec? + //private ECNamedCurveParameterSpec ReadECParameters( // private X9ECParameters ReadECParameters(PemObject pemObject) // { // DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content); @@ -377,31 +377,31 @@ namespace Org.BouncyCastle.OpenSsl // return GetCurveParameters(oid.Id); // } - //private static ECDomainParameters GetCurveParameters( - private static X9ECParameters GetCurveParameters( - string name) - { - // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) - X9ECParameters ecP = X962NamedCurves.GetByName(name); - - if (ecP == null) - { - ecP = SecNamedCurves.GetByName(name); - if (ecP == null) - { - ecP = NistNamedCurves.GetByName(name); - if (ecP == null) - { - ecP = TeleTrusTNamedCurves.GetByName(name); - - if (ecP == null) - throw new Exception("unknown curve name: " + name); - } - } - } - - //return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); - return ecP; - } - } + //private static ECDomainParameters GetCurveParameters( + private static X9ECParameters GetCurveParameters( + string name) + { + // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) + X9ECParameters ecP = X962NamedCurves.GetByName(name); + + if (ecP == null) + { + ecP = SecNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = NistNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByName(name); + + if (ecP == null) + throw new Exception("unknown curve name: " + name); + } + } + } + + //return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + return ecP; + } + } } |