private AsymmetricCipherKeyPair ReadECPrivateKey(
            string endMarker)
        {
            try
            {
                byte[] bytes = ReadBytes(endMarker);
                ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(
                    (Asn1Sequence)Asn1Object.FromByteArray(bytes));
                AlgorithmIdentifier algId = new AlgorithmIdentifier(
                    X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters());

                PrivateKeyInfo       privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object());
                SubjectPublicKeyInfo pubInfo  = new SubjectPublicKeyInfo(algId, pKey.GetPublicKey().GetBytes());

                // TODO Are the keys returned here ECDSA, as Java version forces?
                return(new AsymmetricCipherKeyPair(
                           PublicKeyFactory.CreateKey(pubInfo),
                           PrivateKeyFactory.CreateKey(privInfo)));
            }
            catch (InvalidCastException e)
            {
                throw new IOException("wrong ASN.1 object found in stream.", e);
            }
            catch (Exception e)
            {
                throw new PemException("problem parsing EC private key.", e);
            }
        }
Exemplo n.º 2
0
        private object ReadPrivateKey(PemObject pemObject)
        {
            string text = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();

            byte[]      array      = pemObject.Content;
            IDictionary dictionary = Platform.CreateHashtable();

            foreach (PemHeader pemHeader in pemObject.Headers)
            {
                dictionary[pemHeader.Name] = pemHeader.Value;
            }
            string a = (string)dictionary["Proc-Type"];

            if (a == "4,ENCRYPTED")
            {
                if (this.pFinder == null)
                {
                    throw new PasswordException("No password finder specified, but a password is required");
                }
                char[] password = this.pFinder.GetPassword();
                if (password == null)
                {
                    throw new PasswordException("Password is null, but a password is required");
                }
                string   text2  = (string)dictionary["DEK-Info"];
                string[] array2 = text2.Split(new char[]
                {
                    ','
                });
                string dekAlgName = array2[0].Trim();
                byte[] iv         = Hex.Decode(array2[1].Trim());
                array = PemUtilities.Crypt(false, array, password, dekAlgName, iv);
            }
            object result;

            try
            {
                Asn1Sequence instance = Asn1Sequence.GetInstance(array);
                string       a2;
                if ((a2 = text) != null)
                {
                    AsymmetricKeyParameter asymmetricKeyParameter;
                    AsymmetricKeyParameter publicParameter;
                    if (!(a2 == "RSA"))
                    {
                        if (!(a2 == "DSA"))
                        {
                            if (!(a2 == "EC"))
                            {
                                if (!(a2 == "ENCRYPTED"))
                                {
                                    if (!(a2 == ""))
                                    {
                                        goto IL_356;
                                    }
                                    result = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(instance));
                                    return(result);
                                }
                                else
                                {
                                    char[] password2 = this.pFinder.GetPassword();
                                    if (password2 == null)
                                    {
                                        throw new PasswordException("Password is null, but a password is required");
                                    }
                                    result = PrivateKeyFactory.DecryptKey(password2, EncryptedPrivateKeyInfo.GetInstance(instance));
                                    return(result);
                                }
                            }
                            else
                            {
                                ECPrivateKeyStructure eCPrivateKeyStructure = new ECPrivateKeyStructure(instance);
                                AlgorithmIdentifier   algID   = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, eCPrivateKeyStructure.GetParameters());
                                PrivateKeyInfo        keyInfo = new PrivateKeyInfo(algID, eCPrivateKeyStructure.ToAsn1Object());
                                asymmetricKeyParameter = PrivateKeyFactory.CreateKey(keyInfo);
                                DerBitString publicKey = eCPrivateKeyStructure.GetPublicKey();
                                if (publicKey != null)
                                {
                                    SubjectPublicKeyInfo keyInfo2 = new SubjectPublicKeyInfo(algID, publicKey.GetBytes());
                                    publicParameter = PublicKeyFactory.CreateKey(keyInfo2);
                                }
                                else
                                {
                                    publicParameter = ECKeyPairGenerator.GetCorrespondingPublicKey((ECPrivateKeyParameters)asymmetricKeyParameter);
                                }
                            }
                        }
                        else
                        {
                            if (instance.Count != 6)
                            {
                                throw new PemException("malformed sequence in DSA private key");
                            }
                            DerInteger    derInteger  = (DerInteger)instance[1];
                            DerInteger    derInteger2 = (DerInteger)instance[2];
                            DerInteger    derInteger3 = (DerInteger)instance[3];
                            DerInteger    derInteger4 = (DerInteger)instance[4];
                            DerInteger    derInteger5 = (DerInteger)instance[5];
                            DsaParameters parameters  = new DsaParameters(derInteger.Value, derInteger2.Value, derInteger3.Value);
                            asymmetricKeyParameter = new DsaPrivateKeyParameters(derInteger5.Value, parameters);
                            publicParameter        = new DsaPublicKeyParameters(derInteger4.Value, parameters);
                        }
                    }
                    else
                    {
                        if (instance.Count != 9)
                        {
                            throw new PemException("malformed sequence in RSA private key");
                        }
                        RsaPrivateKeyStructure instance2 = RsaPrivateKeyStructure.GetInstance(instance);
                        publicParameter        = new RsaKeyParameters(false, instance2.Modulus, instance2.PublicExponent);
                        asymmetricKeyParameter = new RsaPrivateCrtKeyParameters(instance2.Modulus, instance2.PublicExponent, instance2.PrivateExponent, instance2.Prime1, instance2.Prime2, instance2.Exponent1, instance2.Exponent2, instance2.Coefficient);
                    }
                    result = new AsymmetricCipherKeyPair(publicParameter, asymmetricKeyParameter);
                    return(result);
                }
IL_356:
                throw new ArgumentException("Unknown key type: " + text, "type");
            }
            catch (IOException ex)
            {
                throw ex;
            }
            catch (Exception ex2)
            {
                throw new PemException("problem creating " + text + " private key: " + ex2.ToString());
            }
            return(result);
        }
Exemplo n.º 3
0
        /**
         * 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());
            }
        }
        /**
         * Read a Key Pair
         */
        private AsymmetricCipherKeyPair ReadKeyPair(
            string type,
            string endMarker)
        {
            //
            // extract the key
            //
            IDictionary fields = new Hashtable();

            byte[] keyBytes = ReadBytesAndFields(endMarker, fields);

            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":
                {
                    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":
                {
                    // 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());
                    DerBitString   pubKey   = pKey.GetPublicKey();
                    //Console.WriteLine(pubKey == null);
                    SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes());

                    // TODO Are the keys returned here ECDSA, as Java version forces?
                    privSpec = PrivateKeyFactory.CreateKey(privInfo);
                    pubSpec  = PublicKeyFactory.CreateKey(pubInfo);

                    break;
                }

                default:
                    throw new ArgumentException("Unknown key type: " + type, "type");
                }

                return(new AsymmetricCipherKeyPair(pubSpec, privSpec));
            }
            catch (Exception e)
            {
                throw new PemException(
                          "problem creating " + type + " private key: " + e.ToString());
            }
        }