Exemple #1
0
        internal static void ReadPkcs8Blob(this DerSequenceReader reader, ref DSAParameters parameters)
        {
            // Since the PKCS#8 blob for DSS/DSA does not include the public key (Y) this
            // structure is only read after filling the public half.
            Debug.Assert(parameters.P != null);
            Debug.Assert(parameters.Q != null);
            Debug.Assert(parameters.G != null);
            Debug.Assert(parameters.Y != null);

            // OneAsymmetricKey ::= SEQUENCE {
            //   version                   Version,
            //   privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
            //   privateKey                PrivateKey,
            //   attributes            [0] Attributes OPTIONAL,
            //   ...,
            //   [[2: publicKey        [1] PublicKey OPTIONAL ]],
            //   ...
            // }
            //
            // PrivateKeyInfo ::= OneAsymmetricKey
            //
            // PrivateKey ::= OCTET STRING

            int version = reader.ReadInteger();

            // We understand both version 0 and 1 formats,
            // which are now known as v1 and v2, respectively.
            if (version > 1)
            {
                throw new CryptographicException();
            }

            {
                // Ensure we're reading DSA, extract the parameters
                DerSequenceReader algorithm = reader.ReadSequence();

                string algorithmOid = algorithm.ReadOidAsString();

                if (algorithmOid != s_idDsa.Value)
                {
                    throw new CryptographicException();
                }

                // The Dss-Params SEQUENCE is present here, but not needed since
                // we got it from the public key already.
            }

            byte[]            privateKeyBlob   = reader.ReadOctetString();
            DerSequenceReader privateKeyReader = DerSequenceReader.CreateForPayload(privateKeyBlob);

            parameters.X = privateKeyReader.ReadIntegerBytes();
        }
Exemple #2
0
        internal static void ReadPkcs8Blob(this DerSequenceReader reader, ref RSAParameters parameters)
        {
            // OneAsymmetricKey ::= SEQUENCE {
            //   version                   Version,
            //   privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
            //   privateKey                PrivateKey,
            //   attributes            [0] Attributes OPTIONAL,
            //   ...,
            //   [[2: publicKey        [1] PublicKey OPTIONAL ]],
            //   ...
            // }
            //
            // PrivateKeyInfo ::= OneAsymmetricKey
            //
            // PrivateKey ::= OCTET STRING

            int version = reader.ReadInteger();

            // We understand both version 0 and 1 formats,
            // which are now known as v1 and v2, respectively.
            if (version > 1)
            {
                throw new CryptographicException();
            }

            {
                // Ensure we're reading RSA
                DerSequenceReader algorithm = reader.ReadSequence();

                string algorithmOid = algorithm.ReadOidAsString();

                if (algorithmOid != RsaOid)
                {
                    throw new CryptographicException();
                }
            }

            byte[] privateKeyBytes = reader.ReadOctetString();
            // Because this was an RSA private key, the key format is PKCS#1.
            ReadPkcs1PrivateBlob(privateKeyBytes, ref parameters);

            // We don't care about the rest of the blob here, but it's expected to not exist.
        }
        private static void ReadPkcs1PrivateBlob(byte[] privateKeyBytes, ref RSAParameters parameters)
        {
            // RSAPrivateKey::= SEQUENCE {
            //    version Version,
            //    modulus           INTEGER,  --n
            //    publicExponent INTEGER,  --e
            //    privateExponent INTEGER,  --d
            //    prime1 INTEGER,  --p
            //    prime2 INTEGER,  --q
            //    exponent1 INTEGER,  --d mod(p - 1)
            //    exponent2 INTEGER,  --d mod(q - 1)
            //    coefficient INTEGER,  --(inverse of q) mod p
            //    otherPrimeInfos OtherPrimeInfos OPTIONAL
            // }
            DerSequenceReader privateKey = new DerSequenceReader(privateKeyBytes);
            int version = privateKey.ReadInteger();

            if (version != 0)
            {
                throw new CryptographicException();
            }

            parameters.Modulus  = KeyBlobHelpers.TrimPaddingByte(privateKey.ReadIntegerBytes());
            parameters.Exponent = KeyBlobHelpers.TrimPaddingByte(privateKey.ReadIntegerBytes());

            int modulusLen = parameters.Modulus.Length;
            // Add one so that odd byte-length values (RSA 1032) get padded correctly.
            int halfModulus = (modulusLen + 1) / 2;

            parameters.D        = KeyBlobHelpers.PadOrTrim(privateKey.ReadIntegerBytes(), modulusLen);
            parameters.P        = KeyBlobHelpers.PadOrTrim(privateKey.ReadIntegerBytes(), halfModulus);
            parameters.Q        = KeyBlobHelpers.PadOrTrim(privateKey.ReadIntegerBytes(), halfModulus);
            parameters.DP       = KeyBlobHelpers.PadOrTrim(privateKey.ReadIntegerBytes(), halfModulus);
            parameters.DQ       = KeyBlobHelpers.PadOrTrim(privateKey.ReadIntegerBytes(), halfModulus);
            parameters.InverseQ = KeyBlobHelpers.PadOrTrim(privateKey.ReadIntegerBytes(), halfModulus);

            if (privateKey.HasData)
            {
                throw new CryptographicException();
            }
        }
        internal static void ReadPkcs8Blob(this DerSequenceReader reader, ref ECParameters parameters)
        {
            // OneAsymmetricKey ::= SEQUENCE {
            //   version                   Version,
            //   privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
            //   privateKey                PrivateKey,
            //   attributes            [0] Attributes OPTIONAL,
            //   ...,
            //   [[2: publicKey        [1] PublicKey OPTIONAL ]],
            //   ...
            // }
            //
            // PrivateKeyInfo ::= OneAsymmetricKey
            //
            // PrivateKey ::= OCTET STRING

            int version = reader.ReadInteger();

            // We understand both version 0 and 1 formats,
            // which are now known as v1 and v2, respectively.
            if (version > 1)
            {
                throw new CryptographicException();
            }

            {
                // Ensure we're reading EC Public Key (well, Private, but the OID says Public)
                DerSequenceReader algorithm = reader.ReadSequence();

                string algorithmOid = algorithm.ReadOidAsString();

                if (algorithmOid != s_idEcPublicKey.Value)
                {
                    throw new CryptographicException();
                }
            }

            byte[] privateKeyBlob = reader.ReadOctetString();

            try
            {
                // ECPrivateKey{CURVES:IOSet} ::= SEQUENCE {
                //   version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
                //   privateKey OCTET STRING,
                //   parameters [0] Parameters{{IOSet}} OPTIONAL,
                //   publicKey  [1] BIT STRING OPTIONAL
                // }
                DerSequenceReader keyReader = new DerSequenceReader(privateKeyBlob);
                version = keyReader.ReadInteger();

                // We understand the version 1 format
                if (version > 1)
                {
                    throw new CryptographicException();
                }

                parameters.D = keyReader.ReadOctetString();

                // Check for context specific 0
                const byte ConstructedContextSpecific =
                    DerSequenceReader.ContextSpecificTagFlag | DerSequenceReader.ConstructedFlag;

                const byte ConstructedContextSpecific0 = (ConstructedContextSpecific | 0);
                const byte ConstructedContextSpecific1 = (ConstructedContextSpecific | 1);

                if (keyReader.PeekTag() != ConstructedContextSpecific0)
                {
                    throw new CryptographicException();
                }

                // Parameters ::= CHOICE {
                //   ecParameters ECParameters,
                //   namedCurve CURVES.&id({ CurveNames}),
                //   implicitlyCA  NULL
                // }
                DerSequenceReader parametersReader = keyReader.ReadSequence();

                if (parametersReader.PeekTag() != (int)DerSequenceReader.DerTag.ObjectIdentifier)
                {
                    throw new PlatformNotSupportedException(SR.Cryptography_ECC_NamedCurvesOnly);
                }

                parameters.Curve = ECCurve.CreateFromValue(parametersReader.ReadOidAsString());

                // Check for context specific 1
                if (keyReader.PeekTag() != ConstructedContextSpecific1)
                {
                    throw new CryptographicException();
                }

                keyReader = keyReader.ReadSequence();
                byte[] encodedPoint = keyReader.ReadBitString();
                ReadEncodedPoint(encodedPoint, ref parameters);

                // We don't care about the rest of the blob here, but it's expected to not exist.
            }
            finally
            {
                Array.Clear(privateKeyBlob, 0, privateKeyBlob.Length);
            }
        }