summary refs log tree commit diff
path: root/crypto/src/security/DotNetUtilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/security/DotNetUtilities.cs')
-rw-r--r--crypto/src/security/DotNetUtilities.cs118
1 files changed, 86 insertions, 32 deletions
diff --git a/crypto/src/security/DotNetUtilities.cs b/crypto/src/security/DotNetUtilities.cs
index 3a7c5f0cb..08853e45e 100644
--- a/crypto/src/security/DotNetUtilities.cs
+++ b/crypto/src/security/DotNetUtilities.cs
@@ -5,9 +5,12 @@ using System.Runtime.Versioning;
 using System.Security.Cryptography;
 using SystemX509 = System.Security.Cryptography.X509Certificates;
 
+using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Utilities;
@@ -50,23 +53,11 @@ namespace Org.BouncyCastle.Security
 
         public static AsymmetricCipherKeyPair GetDsaKeyPair(DSAParameters dp)
         {
-            DsaValidationParameters validationParameters = (dp.Seed != null)
-                ? new DsaValidationParameters(dp.Seed, dp.Counter)
-                : null;
-
-            DsaParameters parameters = new DsaParameters(
-                new BigInteger(1, dp.P),
-                new BigInteger(1, dp.Q),
-                new BigInteger(1, dp.G),
-                validationParameters);
-
-            DsaPublicKeyParameters pubKey = new DsaPublicKeyParameters(
-                new BigInteger(1, dp.Y),
-                parameters);
+            DsaPublicKeyParameters pubKey = GetDsaPublicKey(dp);
 
             DsaPrivateKeyParameters privKey = new DsaPrivateKeyParameters(
                 new BigInteger(1, dp.X),
-                parameters);
+                pubKey.Parameters);
 
             return new AsymmetricCipherKeyPair(pubKey, privKey);
         }
@@ -93,6 +84,62 @@ namespace Org.BouncyCastle.Security
                 parameters);
         }
 
+#if NETCOREAPP1_0_OR_GREATER || NET47_OR_GREATER || NETSTANDARD1_6_OR_GREATER
+        public static AsymmetricCipherKeyPair GetECDsaKeyPair(ECDsa ecDsa)
+        {
+            return GetECKeyPair("ECDSA", ecDsa.ExportParameters(true));
+        }
+
+        public static ECPublicKeyParameters GetECDsaPublicKey(ECDsa ecDsa)
+        {
+            return GetECPublicKey("ECDSA", ecDsa.ExportParameters(false));
+        }
+
+        public static AsymmetricCipherKeyPair GetECKeyPair(string algorithm, ECParameters ec)
+        {
+            ECPublicKeyParameters pubKey = GetECPublicKey(algorithm, ec);
+
+            ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(
+                pubKey.AlgorithmName,
+                new BigInteger(1, ec.D),
+                pubKey.Parameters);
+
+            return new AsymmetricCipherKeyPair(pubKey, privKey);
+        }
+
+        public static ECPublicKeyParameters GetECPublicKey(string algorithm, ECParameters ec)
+        {
+            X9ECParameters x9 = GetX9ECParameters(ec.Curve);
+            if (x9 == null)
+                throw new NotSupportedException("Unrecognized curve");
+
+            return new ECPublicKeyParameters(
+                algorithm,
+                GetECPoint(x9.Curve, ec.Q),
+                new ECDomainParameters(x9));
+        }
+
+        private static Math.EC.ECPoint GetECPoint(Math.EC.ECCurve curve, ECPoint point)
+        {
+            return curve.CreatePoint(new BigInteger(1, point.X), new BigInteger(1, point.Y));
+        }
+
+        private static X9ECParameters GetX9ECParameters(ECCurve curve)
+        {
+            if (!curve.IsNamed)
+                throw new NotSupportedException("Only named curves are supported");
+
+            Oid oid = curve.Oid;
+            if (oid != null)
+            {
+                string oidValue = oid.Value;
+                if (oidValue != null)
+                    return ECKeyPairGenerator.FindECCurveByOid(new DerObjectIdentifier(oidValue));
+            }
+            return null;
+        }
+#endif
+
         public static AsymmetricCipherKeyPair GetRsaKeyPair(RSA rsa)
         {
             return GetRsaKeyPair(rsa.ExportParameters(true));
@@ -100,17 +147,11 @@ namespace Org.BouncyCastle.Security
 
         public static AsymmetricCipherKeyPair GetRsaKeyPair(RSAParameters rp)
         {
-            BigInteger modulus = new BigInteger(1, rp.Modulus);
-            BigInteger pubExp = new BigInteger(1, rp.Exponent);
-
-            RsaKeyParameters pubKey = new RsaKeyParameters(
-                false,
-                modulus,
-                pubExp);
+            RsaKeyParameters pubKey = GetRsaPublicKey(rp);
 
             RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
-                modulus,
-                pubExp,
+                pubKey.Modulus,
+                pubKey.Exponent,
                 new BigInteger(1, rp.D),
                 new BigInteger(1, rp.P),
                 new BigInteger(1, rp.Q),
@@ -137,17 +178,18 @@ namespace Org.BouncyCastle.Security
 
         public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey)
         {
-            if (privateKey is DSA)
-            {
-                return GetDsaKeyPair((DSA)privateKey);
-            }
+            if (privateKey is DSA dsa)
+                return GetDsaKeyPair(dsa);
 
-            if (privateKey is RSA)
-            {
-                return GetRsaKeyPair((RSA)privateKey);
-            }
+#if NETCOREAPP1_0_OR_GREATER || NET47_OR_GREATER || NETSTANDARD1_6_OR_GREATER
+            if (privateKey is ECDsa ecDsa)
+                return GetECDsaKeyPair(ecDsa);
+#endif
 
-            throw new ArgumentException("Unsupported algorithm specified", "privateKey");
+            if (privateKey is RSA rsa)
+                return GetRsaKeyPair(rsa);
+
+            throw new ArgumentException("Unsupported algorithm specified", nameof(privateKey));
         }
 
 #if NET5_0_OR_GREATER
@@ -244,6 +286,18 @@ namespace Org.BouncyCastle.Security
             return BigIntegers.AsUnsignedByteArray(size, n);
         }
 
+        // TODO Why do we use CspParameters instead of just RSA.Create in methods below?
+//        private static RSA CreateRSA(RSAParameters rp)
+//        {
+//#if NETCOREAPP2_0_OR_GREATER || NET472_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+//            return RSA.Create(rp);
+//#else
+//            var rsa = RSA.Create();
+//            rsa.ImportParameters(rp);
+//            return rsa;
+//#endif
+//        }
+
 #if NET5_0_OR_GREATER
         [SupportedOSPlatform("windows")]
 #endif