summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-03-20 16:58:53 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-03-20 16:58:53 +0700
commite60ae2f9014d3f39f24820266304ac765804d362 (patch)
tree39611383b1f9efa39a4a93d21c70d167a2ef1cf6
parentAdd suport of SubjectPublicKeyInfo in Org.BouncyCastle.OpenSsl.PemWriter (diff)
downloadBouncyCastle.NET-ed25519-e60ae2f9014d3f39f24820266304ac765804d362.tar.xz
Refactor MiscPemGenerator
-rw-r--r--crypto/src/openssl/MiscPemGenerator.cs116
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();
         }
     }
 }