Beispiel #1
0
        public override bool TryExportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <char> password,
            PbeParameters pbeParameters,
            Span <byte> destination,
            out int bytesWritten)
        {
            if (pbeParameters == null)
            {
                throw new ArgumentNullException(nameof(pbeParameters));
            }

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                password,
                ReadOnlySpan <byte> .Empty);

            if (CngPkcs8.IsPlatformScheme(pbeParameters))
            {
                return(TryExportEncryptedPkcs8(
                           password,
                           pbeParameters.IterationCount,
                           destination,
                           out bytesWritten));
            }

            return(CngPkcs8.TryExportEncryptedPkcs8PrivateKey(
                       this,
                       password,
                       pbeParameters,
                       destination,
                       out bytesWritten));
        }
Beispiel #2
0
        internal static byte[] ExportEncryptedPkcs8PrivateKey(
            AsymmetricAlgorithm key,
            ReadOnlySpan <byte> passwordBytes,
            PbeParameters pbeParameters)
        {
            if (pbeParameters == null)
            {
                throw new ArgumentNullException(nameof(pbeParameters));
            }

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                ReadOnlySpan <char> .Empty,
                passwordBytes);

            if (passwordBytes.Length == 0)
            {
                // Switch to character-based, since that's the native input format.
                return(key.ExportEncryptedPkcs8PrivateKey(ReadOnlySpan <char> .Empty, pbeParameters));
            }

            using (AsnWriter writer = RewriteEncryptedPkcs8PrivateKey(key, passwordBytes, pbeParameters))
            {
                return(writer.Encode());
            }
        }
Beispiel #3
0
        /// <summary>
        /// Attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo
        /// format into a provided buffer, using a char-based password.
        /// </summary>
        /// <param name="password">
        /// The password to use when encrypting the key material.
        /// </param>
        /// <param name="pbeParameters">
        /// The password-based encryption (PBE) parameters to use when encrypting
        /// the key material.
        /// </param>
        /// <param name="destination">
        /// The byte span to receive the PKCS#8 EncryptedPrivateKeyInfo data.
        /// </param>
        /// <param name="bytesWritten">
        /// When this method returns, contains a value that indicates the number
        /// of bytes written to <paramref name="destination" />. This parameter
        /// is treated as uninitialized.
        /// </param>
        /// <returns>
        /// <see langword="true" /> if <paramref name="destination" /> is big enough
        /// to receive the output; otherwise, <see langword="false" />.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="pbeParameters" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// A derived class has not provided an implementation for <see cref="ExportParameters" />.
        /// </exception>
        /// <exception cref="CryptographicException">
        /// The key could not be exported.
        /// </exception>
        /// <remarks>
        /// When <paramref name="pbeParameters" /> indicates an algorithm that uses PBKDF2
        /// (Password-Based Key Derivation Function 2), the password is converted
        /// to bytes via the UTF-8 encoding.
        /// </remarks>
        public override unsafe bool TryExportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <char> password,
            PbeParameters pbeParameters,
            Span <byte> destination,
            out int bytesWritten)
        {
            ArgumentNullException.ThrowIfNull(pbeParameters);

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                password,
                ReadOnlySpan <byte> .Empty);

            ECParameters ecParameters = ExportParameters(true);

            fixed(byte *privPtr = ecParameters.D)
            {
                try
                {
                    AsnWriter pkcs8PrivateKey = EccKeyFormatHelper.WritePkcs8PrivateKey(ecParameters);

                    AsnWriter writer = KeyFormatHelper.WriteEncryptedPkcs8(
                        password,
                        pkcs8PrivateKey,
                        pbeParameters);

                    return(writer.TryEncode(destination, out bytesWritten));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(ecParameters.D);
                }
            }
        }
Beispiel #4
0
        public override bool TryExportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <byte> passwordBytes,
            PbeParameters pbeParameters,
            Span <byte> destination,
            out int bytesWritten)
        {
            if (pbeParameters == null)
            {
                throw new ArgumentNullException(nameof(pbeParameters));
            }

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                ReadOnlySpan <char> .Empty,
                passwordBytes);

            AsnWriter pkcs8PrivateKey = WritePkcs8PrivateKey();

            AsnWriter writer = KeyFormatHelper.WriteEncryptedPkcs8(
                passwordBytes,
                pkcs8PrivateKey,
                pbeParameters);

            return(writer.TryEncode(destination, out bytesWritten));
        }
        private static void ReadEncryptedPkcs8 <TRet>(
            string[] validOids,
            ReadOnlyMemory <byte> source,
            ReadOnlySpan <char> password,
            ReadOnlySpan <byte> passwordBytes,
            KeyReader <TRet> keyReader,
            out int bytesRead,
            out TRet ret)
        {
            int read;
            EncryptedPrivateKeyInfoAsn epki;

            try
            {
                AsnValueReader reader = new AsnValueReader(source.Span, AsnEncodingRules.BER);
                read = reader.PeekEncodedValue().Length;
                EncryptedPrivateKeyInfoAsn.Decode(ref reader, source, out epki);
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }

            // No supported encryption algorithms produce more bytes of decryption output than there
            // were of decryption input.
            byte[]        decrypted       = CryptoPool.Rent(epki.EncryptedData.Length);
            Memory <byte> decryptedMemory = decrypted;

            try
            {
                int decryptedBytes = PasswordBasedEncryption.Decrypt(
                    epki.EncryptionAlgorithm,
                    password,
                    passwordBytes,
                    epki.EncryptedData.Span,
                    decrypted);

                decryptedMemory = decryptedMemory.Slice(0, decryptedBytes);

                ReadPkcs8(
                    validOids,
                    decryptedMemory,
                    keyReader,
                    out int innerRead,
                    out ret);

                if (innerRead != decryptedMemory.Length)
                {
                    ret = default !;
Beispiel #6
0
        public override bool TryExportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <byte> passwordBytes,
            PbeParameters pbeParameters,
            Span <byte> destination,
            out int bytesWritten)
        {
            ArgumentNullException.ThrowIfNull(pbeParameters);

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                ReadOnlySpan <char> .Empty,
                passwordBytes);

            return(CngPkcs8.TryExportEncryptedPkcs8PrivateKey(
                       this,
                       passwordBytes,
                       pbeParameters,
                       destination,
                       out bytesWritten));
        }
Beispiel #7
0
        public override byte[] ExportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <char> password,
            PbeParameters pbeParameters)
        {
            ArgumentNullException.ThrowIfNull(pbeParameters);

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                password,
                ReadOnlySpan <byte> .Empty);

            if (CngPkcs8.IsPlatformScheme(pbeParameters))
            {
                return(ExportEncryptedPkcs8(password, pbeParameters.IterationCount));
            }

            return(CngPkcs8.ExportEncryptedPkcs8PrivateKey(
                       this,
                       password,
                       pbeParameters));
        }
Beispiel #8
0
        public override unsafe bool TryExportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <byte> passwordBytes,
            PbeParameters pbeParameters,
            Span <byte> destination,
            out int bytesWritten)
        {
            if (pbeParameters == null)
            {
                throw new ArgumentNullException(nameof(pbeParameters));
            }

            PasswordBasedEncryption.ValidatePbeParameters(
                pbeParameters,
                ReadOnlySpan <char> .Empty,
                passwordBytes);

            ECParameters ecParameters = ExportParameters(true);

            fixed(byte *privPtr = ecParameters.D)
            {
                try
                {
                    using (AsnWriter pkcs8PrivateKey = ecParameters.WritePkcs8PrivateKey())
                        using (AsnWriter writer = KeyFormatHelper.WriteEncryptedPkcs8(
                                   passwordBytes,
                                   pkcs8PrivateKey,
                                   pbeParameters))
                        {
                            return(writer.TryEncode(destination, out bytesWritten));
                        }
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(ecParameters.D);
                }
            }
        }