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 | |
parent | Remove DerUnknownTag class (diff) | |
download | BouncyCastle.NET-ed25519-0373cfe00e805772ca49ab459900b986bd83f23c.tar.xz |
Fix up openssl test cases
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/src/openssl/PEMReader.cs | 706 | ||||
-rw-r--r-- | crypto/test/src/openssl/test/ReaderTest.cs | 673 |
2 files changed, 689 insertions, 690 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; + } + } } diff --git a/crypto/test/src/openssl/test/ReaderTest.cs b/crypto/test/src/openssl/test/ReaderTest.cs index d27ed742f..e3990b562 100644 --- a/crypto/test/src/openssl/test/ReaderTest.cs +++ b/crypto/test/src/openssl/test/ReaderTest.cs @@ -13,44 +13,44 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.OpenSsl.Tests { - /** - * basic class for reading test.pem - the password is "secret" - */ - [TestFixture] - public class ReaderTest - : SimpleTest - { - private class Password - : IPasswordFinder - { - private readonly char[] password; - - public Password( - char[] word) - { - this.password = (char[]) word.Clone(); - } - - public char[] GetPassword() - { - return (char[]) password.Clone(); - } - } - - public override string Name - { - get { return "PEMReaderTest"; } - } - - public override void PerformTest() - { - IPasswordFinder pGet = new Password("secret".ToCharArray()); - PemReader pemRd = OpenPemResource("test.pem", pGet); - AsymmetricCipherKeyPair pair; - - object o; - while ((o = pemRd.ReadObject()) != null) - { + /** + * basic class for reading test.pem - the password is "secret" + */ + [TestFixture] + public class ReaderTest + : SimpleTest + { + private class Password + : IPasswordFinder + { + private readonly char[] password; + + public Password( + char[] word) + { + this.password = (char[]) word.Clone(); + } + + public char[] GetPassword() + { + return (char[]) password.Clone(); + } + } + + public override string Name + { + get { return "PEMReaderTest"; } + } + + public override void PerformTest() + { + IPasswordFinder pGet = new Password("secret".ToCharArray()); + PemReader pemRd = OpenPemResource("test.pem", pGet); + AsymmetricCipherKeyPair pair; + + object o; + while ((o = pemRd.ReadObject()) != null) + { // if (o is AsymmetricCipherKeyPair) // { // ackp = (AsymmetricCipherKeyPair)o; @@ -62,51 +62,51 @@ namespace Org.BouncyCastle.OpenSsl.Tests // { // Console.WriteLine(o.ToString()); // } - } - - // - // pkcs 7 data - // - pemRd = OpenPemResource("pkcs7.pem", null); - - ContentInfo d = (ContentInfo)pemRd.ReadObject(); - - if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) - { - Fail("failed envelopedData check"); - } - - /* - { - // - // ECKey - // - pemRd = OpenPemResource("eckey.pem", null); - - // TODO Resolve return type issue with EC keys and fix PemReader to return parameters + } + + // + // pkcs 7 data + // + pemRd = OpenPemResource("pkcs7.pem", null); + + ContentInfo d = (ContentInfo)pemRd.ReadObject(); + + if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) + { + Fail("failed envelopedData check"); + } + + /* + { + // + // ECKey + // + pemRd = OpenPemResource("eckey.pem", null); + + // TODO Resolve return type issue with EC keys and fix PemReader to return parameters // ECNamedCurveParameterSpec spec = (ECNamedCurveParameterSpec)pemRd.ReadObject(); - - pair = (AsymmetricCipherKeyPair)pemRd.ReadObject(); - ISigner sgr = SignerUtilities.GetSigner("ECDSA"); - - sgr.Init(true, pair.Private); - - byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; - - sgr.BlockUpdate(message, 0, message.Length); - - byte[] sigBytes = sgr.GenerateSignature(); - - sgr.Init(false, pair.Public); - - sgr.BlockUpdate(message, 0, message.Length); - - if (!sgr.VerifySignature(sigBytes)) - { - Fail("EC verification failed"); - } - - // TODO Resolve this issue with the algorithm name, study Java version + + pair = (AsymmetricCipherKeyPair)pemRd.ReadObject(); + ISigner sgr = SignerUtilities.GetSigner("ECDSA"); + + sgr.Init(true, pair.Private); + + byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; + + sgr.BlockUpdate(message, 0, message.Length); + + byte[] sigBytes = sgr.GenerateSignature(); + + sgr.Init(false, pair.Public); + + sgr.BlockUpdate(message, 0, message.Length); + + if (!sgr.VerifySignature(sigBytes)) + { + Fail("EC verification failed"); + } + + // TODO Resolve this issue with the algorithm name, study Java version // if (!((ECPublicKeyParameters) pair.Public).AlgorithmName.Equals("ECDSA")) // { // Fail("wrong algorithm name on public got: " + ((ECPublicKeyParameters) pair.Public).AlgorithmName); @@ -116,265 +116,264 @@ namespace Org.BouncyCastle.OpenSsl.Tests // { // Fail("wrong algorithm name on private got: " + ((ECPrivateKeyParameters) pair.Private).AlgorithmName); // } - } - */ + } + */ - // - // writer/parser test - // - IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); - kpGen.Init( - new RsaKeyGenerationParameters( - BigInteger.ValueOf(0x10001), - new SecureRandom(), - 768, - 25)); + // + // writer/parser test + // + IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); + kpGen.Init( + new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), + new SecureRandom(), + 768, + 25)); - pair = kpGen.GenerateKeyPair(); + pair = kpGen.GenerateKeyPair(); - keyPairTest("RSA", pair); + keyPairTest("RSA", pair); // kpGen = KeyPairGenerator.getInstance("DSA"); // kpGen.initialize(512, new SecureRandom()); - DsaParametersGenerator pGen = new DsaParametersGenerator(); - pGen.Init(512, 80, new SecureRandom()); - - kpGen = GeneratorUtilities.GetKeyPairGenerator("DSA"); - kpGen.Init( - new DsaKeyGenerationParameters( - new SecureRandom(), - pGen.GenerateParameters())); - - pair = kpGen.GenerateKeyPair(); - - keyPairTest("DSA", pair); - - // - // PKCS7 - // - MemoryStream bOut = new MemoryStream(); - PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); - - pWrt.WriteObject(d); - pWrt.Writer.Close(); - - pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); - d = (ContentInfo)pemRd.ReadObject(); - - if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) - { - Fail("failed envelopedData recode check"); - } - - - // OpenSSL test cases (as embedded resources) - doOpenSslDsaTest("unencrypted"); - doOpenSslRsaTest("unencrypted"); - - doOpenSslTests("aes128"); - doOpenSslTests("aes192"); - doOpenSslTests("aes256"); - doOpenSslTests("blowfish"); - doOpenSslTests("des1"); - doOpenSslTests("des2"); - doOpenSslTests("des3"); - doOpenSslTests("rc2_128"); - - doOpenSslDsaTest("rc2_40_cbc"); - doOpenSslRsaTest("rc2_40_cbc"); - doOpenSslDsaTest("rc2_64_cbc"); - doOpenSslRsaTest("rc2_64_cbc"); - - // TODO Figure out why exceptions differ for commented out cases - doDudPasswordTest("7fd98", 0, "Corrupted stream - out of bounds length found"); - doDudPasswordTest("ef677", 1, "Corrupted stream - out of bounds length found"); -// doDudPasswordTest("800ce", 2, "cannot recognise object in stream"); - doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); - doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); - doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); - doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); - doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); - doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); - doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); - doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); - doDudPasswordTest("41af75", 11, "malformed sequence in DSA private key"); - doDudPasswordTest("1704a5", 12, "corrupted stream detected"); -// doDudPasswordTest("1c5822", 13, "corrupted stream detected"); -// doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); - doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); - doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); - doDudPasswordTest("aaf9c4d",17, "Corrupted stream - out of bounds length found"); - - // encrypted private key test - pGet = new Password("password".ToCharArray()); - pemRd = OpenPemResource("enckey.pem", pGet); - - RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject(); - - if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) - { - Fail("decryption of private key data check failed"); - } - - // general PKCS8 test - pGet = new Password("password".ToCharArray()); - pemRd = OpenPemResource("pkcs8test.pem", pGet); - - while ((privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject()) != null) - { - if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) - { - Fail("decryption of private key data check failed"); - } - } - } - - private void keyPairTest( - string name, - AsymmetricCipherKeyPair pair) - { - MemoryStream bOut = new MemoryStream(); - PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); - - pWrt.WriteObject(pair.Public); - pWrt.Writer.Close(); - - PemReader pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); - - AsymmetricKeyParameter pubK = (AsymmetricKeyParameter) pemRd.ReadObject(); - if (!pubK.Equals(pair.Public)) - { - Fail("Failed public key read: " + name); - } - - bOut = new MemoryStream(); - pWrt = new PemWriter(new StreamWriter(bOut)); - - pWrt.WriteObject(pair.Private); - pWrt.Writer.Close(); - - pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); - - AsymmetricCipherKeyPair kPair = (AsymmetricCipherKeyPair) pemRd.ReadObject(); - if (!kPair.Private.Equals(pair.Private)) - { - Fail("Failed private key read: " + name); - } - - if (!kPair.Public.Equals(pair.Public)) - { - Fail("Failed private key public read: " + name); - } - } - - private void doOpenSslTests( - string baseName) - { - doOpenSslDsaModesTest(baseName); - doOpenSslRsaModesTest(baseName); - } - - private void doOpenSslDsaModesTest( - string baseName) - { - doOpenSslDsaTest(baseName + "_cbc"); - doOpenSslDsaTest(baseName + "_cfb"); - doOpenSslDsaTest(baseName + "_ecb"); - doOpenSslDsaTest(baseName + "_ofb"); - } - - private void doOpenSslRsaModesTest( - string baseName) - { - doOpenSslRsaTest(baseName + "_cbc"); - doOpenSslRsaTest(baseName + "_cfb"); - doOpenSslRsaTest(baseName + "_ecb"); - doOpenSslRsaTest(baseName + "_ofb"); - } - - private void doOpenSslDsaTest( - string name) - { - string fileName = "dsa.openssl_dsa_" + name + ".pem"; - - doOpenSslTestFile(fileName, typeof(DsaPrivateKeyParameters)); - } - - private void doOpenSslRsaTest( - string name) - { - string fileName = "rsa.openssl_rsa_" + name + ".pem"; - - doOpenSslTestFile(fileName, typeof(RsaPrivateCrtKeyParameters)); - } - - private void doOpenSslTestFile( - string fileName, - Type expectedPrivKeyType) - { - PemReader pr = OpenPemResource(fileName, new Password("changeit".ToCharArray())); - AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair; - pr.Reader.Close(); - - if (kp == null) - { - Fail("Didn't find OpenSSL key"); - } - - if (!expectedPrivKeyType.IsInstanceOfType(kp.Private)) - { - Fail("Returned key not of correct type"); - } - } - - private void doDudPasswordTest(string password, int index, string message) - { - // illegal state exception check - in this case the wrong password will - // cause an underlying class cast exception. - try - { - IPasswordFinder pGet = new Password(password.ToCharArray()); - PemReader pemRd = OpenPemResource("test.pem", pGet); - - Object o; - while ((o = pemRd.ReadObject()) != null) - { - } - - Fail("issue not detected: " + index); - } - catch (IOException e) - { - if (e.Message.IndexOf(message) < 0) - { - Console.Error.WriteLine(message); - Console.Error.WriteLine(e.Message); - Fail("issue " + index + " exception thrown, but wrong message"); - } - } - } - - private static PemReader OpenPemResource( - string fileName, - IPasswordFinder pGet) - { - Stream data = GetTestDataAsStream("openssl." + fileName); - TextReader tr = new StreamReader(data); - return new PemReader(tr, pGet); - } - - public static void Main( - string[] args) - { - RunTest(new ReaderTest()); - } - - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); - - Assert.AreEqual(Name + ": Okay", resultText); - } - } + DsaParametersGenerator pGen = new DsaParametersGenerator(); + pGen.Init(512, 80, new SecureRandom()); + + kpGen = GeneratorUtilities.GetKeyPairGenerator("DSA"); + kpGen.Init( + new DsaKeyGenerationParameters( + new SecureRandom(), + pGen.GenerateParameters())); + + pair = kpGen.GenerateKeyPair(); + + keyPairTest("DSA", pair); + + // + // PKCS7 + // + MemoryStream bOut = new MemoryStream(); + PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); + + pWrt.WriteObject(d); + pWrt.Writer.Close(); + + pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); + d = (ContentInfo)pemRd.ReadObject(); + + if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) + { + Fail("failed envelopedData recode check"); + } + + + // OpenSSL test cases (as embedded resources) + doOpenSslDsaTest("unencrypted"); + doOpenSslRsaTest("unencrypted"); + + doOpenSslTests("aes128"); + doOpenSslTests("aes192"); + doOpenSslTests("aes256"); + doOpenSslTests("blowfish"); + doOpenSslTests("des1"); + doOpenSslTests("des2"); + doOpenSslTests("des3"); + doOpenSslTests("rc2_128"); + + doOpenSslDsaTest("rc2_40_cbc"); + doOpenSslRsaTest("rc2_40_cbc"); + doOpenSslDsaTest("rc2_64_cbc"); + doOpenSslRsaTest("rc2_64_cbc"); + + doDudPasswordTest("7fd98", 0, "Corrupted stream - out of bounds length found"); + doDudPasswordTest("ef677", 1, "Corrupted stream - out of bounds length found"); + doDudPasswordTest("800ce", 2, "unknown tag 26 encountered"); + doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); + doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); + doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); + doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); + doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); + doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); + doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); + doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); + doDudPasswordTest("41af75", 11, "unknown tag 16 encountered"); + doDudPasswordTest("1704a5", 12, "corrupted stream detected"); + doDudPasswordTest("1c5822", 13, "Unknown object in GetInstance: Org.BouncyCastle.Asn1.DerUtf8String"); + doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); + doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); + doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); + doDudPasswordTest("aaf9c4d",17, "Corrupted stream - out of bounds length found"); + + // encrypted private key test + pGet = new Password("password".ToCharArray()); + pemRd = OpenPemResource("enckey.pem", pGet); + + RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject(); + + if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) + { + Fail("decryption of private key data check failed"); + } + + // general PKCS8 test + pGet = new Password("password".ToCharArray()); + pemRd = OpenPemResource("pkcs8test.pem", pGet); + + while ((privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject()) != null) + { + if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) + { + Fail("decryption of private key data check failed"); + } + } + } + + private void keyPairTest( + string name, + AsymmetricCipherKeyPair pair) + { + MemoryStream bOut = new MemoryStream(); + PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); + + pWrt.WriteObject(pair.Public); + pWrt.Writer.Close(); + + PemReader pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); + + AsymmetricKeyParameter pubK = (AsymmetricKeyParameter) pemRd.ReadObject(); + if (!pubK.Equals(pair.Public)) + { + Fail("Failed public key read: " + name); + } + + bOut = new MemoryStream(); + pWrt = new PemWriter(new StreamWriter(bOut)); + + pWrt.WriteObject(pair.Private); + pWrt.Writer.Close(); + + pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); + + AsymmetricCipherKeyPair kPair = (AsymmetricCipherKeyPair) pemRd.ReadObject(); + if (!kPair.Private.Equals(pair.Private)) + { + Fail("Failed private key read: " + name); + } + + if (!kPair.Public.Equals(pair.Public)) + { + Fail("Failed private key public read: " + name); + } + } + + private void doOpenSslTests( + string baseName) + { + doOpenSslDsaModesTest(baseName); + doOpenSslRsaModesTest(baseName); + } + + private void doOpenSslDsaModesTest( + string baseName) + { + doOpenSslDsaTest(baseName + "_cbc"); + doOpenSslDsaTest(baseName + "_cfb"); + doOpenSslDsaTest(baseName + "_ecb"); + doOpenSslDsaTest(baseName + "_ofb"); + } + + private void doOpenSslRsaModesTest( + string baseName) + { + doOpenSslRsaTest(baseName + "_cbc"); + doOpenSslRsaTest(baseName + "_cfb"); + doOpenSslRsaTest(baseName + "_ecb"); + doOpenSslRsaTest(baseName + "_ofb"); + } + + private void doOpenSslDsaTest( + string name) + { + string fileName = "dsa.openssl_dsa_" + name + ".pem"; + + doOpenSslTestFile(fileName, typeof(DsaPrivateKeyParameters)); + } + + private void doOpenSslRsaTest( + string name) + { + string fileName = "rsa.openssl_rsa_" + name + ".pem"; + + doOpenSslTestFile(fileName, typeof(RsaPrivateCrtKeyParameters)); + } + + private void doOpenSslTestFile( + string fileName, + Type expectedPrivKeyType) + { + PemReader pr = OpenPemResource(fileName, new Password("changeit".ToCharArray())); + AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair; + pr.Reader.Close(); + + if (kp == null) + { + Fail("Didn't find OpenSSL key"); + } + + if (!expectedPrivKeyType.IsInstanceOfType(kp.Private)) + { + Fail("Returned key not of correct type"); + } + } + + private void doDudPasswordTest(string password, int index, string message) + { + // illegal state exception check - in this case the wrong password will + // cause an underlying class cast exception. + try + { + IPasswordFinder pGet = new Password(password.ToCharArray()); + PemReader pemRd = OpenPemResource("test.pem", pGet); + + Object o; + while ((o = pemRd.ReadObject()) != null) + { + } + + Fail("issue not detected: " + index); + } + catch (IOException e) + { + if (e.Message.IndexOf(message) < 0) + { + Console.Error.WriteLine(message); + Console.Error.WriteLine(e.Message); + Fail("issue " + index + " exception thrown, but wrong message"); + } + } + } + + private static PemReader OpenPemResource( + string fileName, + IPasswordFinder pGet) + { + Stream data = GetTestDataAsStream("openssl." + fileName); + TextReader tr = new StreamReader(data); + return new PemReader(tr, pGet); + } + + public static void Main( + string[] args) + { + RunTest(new ReaderTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } } |