diff options
-rw-r--r-- | crypto/src/openssl/MiscPemGenerator.cs | 116 |
1 files changed, 70 insertions, 46 deletions
diff --git a/crypto/src/openssl/MiscPemGenerator.cs b/crypto/src/openssl/MiscPemGenerator.cs index cafbdedbb..cfbb5e96d 100644 --- a/crypto/src/openssl/MiscPemGenerator.cs +++ b/crypto/src/openssl/MiscPemGenerator.cs @@ -4,11 +4,11 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; @@ -47,7 +47,7 @@ namespace Org.BouncyCastle.OpenSsl private static PemObject CreatePemObject(object obj) { if (obj == null) - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); if (obj is AsymmetricCipherKeyPair keyPair) return CreatePemObject(keyPair.Private); @@ -94,30 +94,41 @@ namespace Org.BouncyCastle.OpenSsl } else { - type = "PUBLIC KEY"; - - encoding = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp).GetDerEncoded(); + encoding = EncodePublicKey(akp, out type); } } + else if (obj is PrivateKeyInfo privateKeyInfo) + { + encoding = EncodePrivateKeyInfo(privateKeyInfo, out type); + } else if (obj is SubjectPublicKeyInfo subjectPublicKeyInfo) { - type = "PUBLIC KEY"; - encoding = subjectPublicKeyInfo.GetEncoded(); + encoding = EncodePublicKeyInfo(subjectPublicKeyInfo, out type); } else if (obj is X509V2AttributeCertificate attrCert) { type = "ATTRIBUTE CERTIFICATE"; encoding = attrCert.GetEncoded(); } + else if (obj is Pkcs8EncryptedPrivateKeyInfo pkcs8EncryptedPrivateKeyInfo) + { + type = "ENCRYPTED PRIVATE KEY"; + encoding = pkcs8EncryptedPrivateKeyInfo.GetEncoded(); + } else if (obj is Pkcs10CertificationRequest certReq) { type = "CERTIFICATE REQUEST"; encoding = certReq.GetEncoded(); } - else if (obj is Asn1.Cms.ContentInfo contentInfo) + else if (obj is Asn1.Cms.ContentInfo cmsContentInfo) + { + type = "PKCS7"; + encoding = cmsContentInfo.GetEncoded(); + } + else if (obj is Asn1.Pkcs.ContentInfo pkcsContentInfo) { type = "PKCS7"; - encoding = contentInfo.GetEncoded(); + encoding = pkcsContentInfo.GetEncoded(); } else { @@ -244,46 +255,63 @@ namespace Org.BouncyCastle.OpenSsl } #endif - private static byte[] EncodePrivateKey( - AsymmetricKeyParameter akp, - out string keyType) + public PemObject Generate() { - PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp); - AlgorithmIdentifier algID = info.PrivateKeyAlgorithm; - DerObjectIdentifier oid = algID.Algorithm; - - if (oid.Equals(X9ObjectIdentifiers.IdDsa)) + try { - keyType = "DSA PRIVATE KEY"; + if (algorithm != null) + return CreatePemObject(obj, algorithm, password, random); - DsaParameter p = DsaParameter.GetInstance(algID.Parameters); + return CreatePemObject(obj); + } + catch (IOException e) + { + throw new PemGenerationException("encoding exception", e); + } + } - BigInteger x = ((DsaPrivateKeyParameters)akp).X; - BigInteger y = p.G.ModPow(x, p.P); + private static byte[] EncodePrivateKey(AsymmetricKeyParameter akp, out string keyType) + { + PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp); + return EncodePrivateKeyInfo(info, out keyType); + } - // TODO Create an ASN1 object somewhere for this? - return new DerSequence( - new DerInteger(0), - new DerInteger(p.P), - new DerInteger(p.Q), - new DerInteger(p.G), - new DerInteger(y), - new DerInteger(x)).GetEncoded(); - } + private static byte[] EncodePrivateKeyInfo(PrivateKeyInfo info, out string keyType) + { + var algID = info.PrivateKeyAlgorithm; + var algOid = algID.Algorithm; - if (oid.Equals(PkcsObjectIdentifiers.RsaEncryption)) + if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption)) { keyType = "RSA PRIVATE KEY"; return info.ParsePrivateKey().GetEncoded(); } - else if (oid.Equals(CryptoProObjectIdentifiers.GostR3410x2001) - || oid.Equals(X9ObjectIdentifiers.IdECPublicKey)) + else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey) || + algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) { keyType = "EC PRIVATE KEY"; return info.ParsePrivateKey().GetEncoded(); } + else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) || + algOid.Equals(OiwObjectIdentifiers.DsaWithSha1)) + { + keyType = "DSA PRIVATE KEY"; + + DsaParameter p = DsaParameter.GetInstance(algID.Parameters); + BigInteger x = DerInteger.GetInstance(info.ParsePrivateKey()).Value; + BigInteger y = p.G.ModPow(x, p.P); + + var sequence = new DerSequence( + new DerInteger(0), + new DerInteger(p.P), + new DerInteger(p.Q), + new DerInteger(p.G), + new DerInteger(y), + new DerInteger(x)); + return sequence.GetEncoded(); + } else { keyType = "PRIVATE KEY"; @@ -292,21 +320,17 @@ namespace Org.BouncyCastle.OpenSsl } } - public PemObject Generate() + private static byte[] EncodePublicKey(AsymmetricKeyParameter akp, out string keyType) { - try - { - if (algorithm != null) - { - return CreatePemObject(obj, algorithm, password, random); - } + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp); + return EncodePublicKeyInfo(info, out keyType); + } - return CreatePemObject(obj); - } - catch (IOException e) - { - throw new PemGenerationException("encoding exception", e); - } + private static byte[] EncodePublicKeyInfo(SubjectPublicKeyInfo info, out string keyType) + { + keyType = "PUBLIC KEY"; + + return info.GetEncoded(); } } } |