summary refs log tree commit diff
path: root/crypto/src/security/PrivateKeyFactory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/security/PrivateKeyFactory.cs')
-rw-r--r--crypto/src/security/PrivateKeyFactory.cs96
1 files changed, 83 insertions, 13 deletions
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index c4fabae2d..e66224a67 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -130,29 +130,99 @@ namespace Org.BouncyCastle.Security
                 ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
                 return new ECPrivateKeyParameters(d, dParams);
             }
-            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
+            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001) ||
+                     algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
+                     algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
             {
-                Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(
-                    algID.Parameters.ToAsn1Object());
+                Asn1Object p = algID.Parameters.ToAsn1Object();
+                Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(p);
 
-                X9ECParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
+                ECGost3410Parameters ecSpec;
+                BigInteger d;
 
-                if (ecP == null)
-                    throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
+                if (p is Asn1Sequence seq && (seq.Count == 2 || seq.Count == 3))
+                {
+                    X9ECParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
+                    if (ecP == null)
+                        throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
 
-                Asn1Object privKey = keyInfo.ParsePrivateKey();
-                ECPrivateKeyStructure ec;
+                    ecSpec = new ECGost3410Parameters(
+                        new ECNamedDomainParameters(gostParams.PublicKeyParamSet, ecP),
+                        gostParams.PublicKeyParamSet,
+                        gostParams.DigestParamSet,
+                        gostParams.EncryptionParamSet);
 
-                if (privKey is DerInteger)
-                {
-                    ec = new ECPrivateKeyStructure(ecP.N.BitLength, ((DerInteger)privKey).PositiveValue);
+                    Asn1OctetString privEnc = keyInfo.PrivateKeyData;
+                    if (privEnc.GetOctets().Length == 32 || privEnc.GetOctets().Length == 64)
+                    {
+                        d = new BigInteger(1, Arrays.Reverse(privEnc.GetOctets()));
+                    }
+                    else
+                    {
+                        Asn1Object privKey = keyInfo.ParsePrivateKey();
+                        if (privKey is DerInteger derInteger)
+                        {
+                            d = derInteger.PositiveValue;
+                        }
+                        else
+                        {
+                            byte[] dVal = Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets());
+                            d = new BigInteger(1, dVal);
+                        }
+                    }
                 }
                 else
                 {
-                    ec = ECPrivateKeyStructure.GetInstance(privKey);
+                    X962Parameters x962Parameters = X962Parameters.GetInstance(p);
+
+                    if (x962Parameters.IsNamedCurve)
+                    {
+                        DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(x962Parameters.Parameters);
+                        X9ECParameters ecP = ECNamedCurveTable.GetByOid(oid);
+                        if (ecP == null)
+                            throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
+
+                        ecSpec = new ECGost3410Parameters(
+                            new ECNamedDomainParameters(oid, ecP),
+                            gostParams.PublicKeyParamSet,
+                            gostParams.DigestParamSet,
+                            gostParams.EncryptionParamSet);
+                    }
+                    else if (x962Parameters.IsImplicitlyCA)
+                    {
+                        ecSpec = null;
+                    }
+                    else
+                    {
+                        X9ECParameters ecP = X9ECParameters.GetInstance(x962Parameters.Parameters);
+
+                        ecSpec = new ECGost3410Parameters(
+                            new ECNamedDomainParameters(algOid, ecP),
+                            gostParams.PublicKeyParamSet,
+                            gostParams.DigestParamSet,
+                            gostParams.EncryptionParamSet);
+                    }
+
+                    Asn1Object privKey = keyInfo.ParsePrivateKey();
+                    if (privKey is DerInteger derD)
+                    {
+                        d = derD.Value;
+                    }
+                    else
+                    {
+                        ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(privKey);
+
+                        d = ec.GetKey();
+                    }
                 }
 
-                return new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet);
+                return new ECPrivateKeyParameters(
+                    d,
+                    new ECGost3410Parameters(
+                        ecSpec,
+                        gostParams.PublicKeyParamSet,
+                        gostParams.DigestParamSet,
+                        gostParams.EncryptionParamSet));
             }
             else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
             {