Exemple #1
0
            private byte[] ExportKeyBlob(bool includePrivateParameters)
            {
                string blobType = includePrivateParameters ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_RSAFULLPRIVATE_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_RSAPUBLIC_KEY_BLOB;

                using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
                {
                    return(CngKeyLite.ExportKeyBlob(keyHandle, blobType));
                }
            }
Exemple #2
0
        private static Pkcs8Response ImportPkcs8(ReadOnlySpan <byte> keyBlob)
        {
            SafeNCryptKeyHandle handle = CngKeyLite.ImportKeyBlob(
                Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
                keyBlob);

            return(new Pkcs8Response
            {
                KeyHandle = handle,
            });
        }
Exemple #3
0
            private void ImportKeyBlob(byte[] dsaBlob, bool includePrivate)
            {
                // Use generic blob type for multiple version support
                string blobType = includePrivate ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_PRIVATE_KEY_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_PUBLIC_KEY_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, dsaBlob);

                SetKeyHandle(keyHandle);
            }
Exemple #4
0
            private void ImportKeyBlob(byte[] rsaBlob, bool includePrivate)
            {
                ThrowIfDisposed();

                string blobType = includePrivate
                    ? Interop.BCrypt.KeyBlobType.BCRYPT_RSAPRIVATE_BLOB
                    : Interop.BCrypt.KeyBlobType.BCRYPT_RSAPUBLIC_KEY_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, rsaBlob);

                SetKeyHandle(keyHandle);
            }
Exemple #5
0
            private byte[] ExportKeyBlob(bool includePrivateParameters)
            {
                // Use generic blob type for multiple version support
                string blobType = includePrivateParameters ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_PRIVATE_KEY_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_PUBLIC_KEY_BLOB;

                using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
                {
                    return(CngKeyLite.ExportKeyBlob(keyHandle, blobType));
                }
            }
            private void AcceptImport(CngPkcs8.Pkcs8Response response)
            {
                SafeNCryptKeyHandle keyHandle = response.KeyHandle;

                _key.SetHandle(
                    keyHandle,
                    CngKeyLite.GetPropertyAsString(
                        keyHandle,
                        CngKeyLite.KeyPropertyName.Algorithm,
                        CngPropertyOptions.None));

                ForceSetKeySize(_key.KeySize);
            }
            private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
            {
                string blobType = includePrivateParameters ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPRIVATE_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPUBLIC_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecfullKeyBlob);

                Debug.Assert(!keyHandle.IsInvalid);

                _key.SetHandle(keyHandle, AlgorithmName.ECDH);
                ForceSetKeySize(_key.KeySize);
            }
            private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters)
            {
                string blobType = includePrivateParameters ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName);

                Debug.Assert(!keyHandle.IsInvalid);

                _key.SetHandle(keyHandle, ECCng.EcdhCurveNameToAlgorithm(curveName));
                ForceSetKeySize(_key.KeySize);
            }
            internal string GetCurveName()
            {
                using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) // Ensure key\handle is created
                {
                    string algorithm = _lastAlgorithm;
                    if (IsECNamedCurve(algorithm))
                    {
                        return(CngKeyLite.GetCurveName(keyHandle));
                    }

                    // Use hard-coded values (for use with pre-Win10 APIs)
                    return(SpecialNistAlgorithmToCurveName(algorithm));
                }
            }
Exemple #10
0
            private void ImportKeyBlob(byte[] rsaBlob, bool includePrivate)
            {
                string blobType = includePrivate ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_RSAPRIVATE_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_PUBLIC_KEY_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, rsaBlob);

                Debug.Assert(!keyHandle.IsInvalid);

                _keyHandle = keyHandle;
                int newKeySize = CngKeyLite.GetKeyLength(keyHandle);

                KeySize = _lastKeySize = newKeySize;
            }
Exemple #11
0
        internal string GetCurveName(int callerKeySizeProperty)
        {
            // Ensure key\handle is created
            using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle(callerKeySizeProperty))
            {
                string algorithm = _lastAlgorithm;

                if (ECCng.IsECNamedCurve(algorithm))
                {
                    return(CngKeyLite.GetCurveName(keyHandle));
                }

                // Use hard-coded values (for use with pre-Win10 APIs)
                return(ECCng.SpecialNistAlgorithmToCurveName(algorithm));
            }
        }
 private bool TryExportEncryptedPkcs8(
     ReadOnlySpan <char> pkcs8Password,
     int kdfCount,
     Span <byte> destination,
     out int bytesWritten)
 {
     using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
     {
         return(CngKeyLite.TryExportPkcs8KeyBlob(
                    keyHandle,
                    pkcs8Password,
                    kdfCount,
                    destination,
                    out bytesWritten));
     }
 }
Exemple #13
0
            private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters)
            {
                string blobType = includePrivateParameters ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName);

                Debug.Assert(!keyHandle.IsInvalid);

                _keyHandle     = keyHandle;
                _lastAlgorithm = ECCng.EcdsaCurveNameToAlgorithm(curveName);

                int newKeySize = CngKeyLite.GetKeyLength(keyHandle);

                ForceSetKeySize(newKeySize);
                _lastKeySize = newKeySize;
            }
Exemple #14
0
            private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
            {
                string blobType = includePrivateParameters ?
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPRIVATE_BLOB :
                                  Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPUBLIC_BLOB;

                SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecfullKeyBlob);

                Debug.Assert(!keyHandle.IsInvalid);

                _keyHandle     = keyHandle;
                _lastAlgorithm = AlgorithmName.ECDsa;

                int newKeySize = CngKeyLite.GetKeyLength(keyHandle);

                ForceSetKeySize(newKeySize);
                _lastKeySize = newKeySize;
            }
Exemple #15
0
            private SafeNCryptKeyHandle GetKeyHandle()
            {
                int keySize = KeySize;

                if (_lastKeySize != keySize)
                {
                    if (_keyHandle != null)
                    {
                        _keyHandle.Dispose();
                    }

                    const string BCRYPT_RSA_ALGORITHM = "RSA";

                    _keyHandle   = CngKeyLite.GenerateNewExportableKey(BCRYPT_RSA_ALGORITHM, keySize);
                    _lastKeySize = keySize;
                }

                return(_keyHandle);
            }
Exemple #16
0
            private void SetKeyHandle(SafeNCryptKeyHandle keyHandle)
            {
                Debug.Assert(!keyHandle.IsInvalid);

                _keyHandle = keyHandle;

                int newKeySize = CngKeyLite.GetKeyLength(keyHandle);

                // Our LegalKeySizes value stores the values that we encoded as being the correct
                // legal key size limitations for this algorithm, as documented on MSDN.
                //
                // But on a new OS version we might not question if our limit is accurate, or MSDN
                // could have been inaccurate to start with.
                //
                // Since the key is already loaded, we know that Windows thought it to be valid;
                // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
                // check.
                ForceSetKeySize(newKeySize);
                _lastKeySize = newKeySize;
            }
Exemple #17
0
            private SafeNCryptKeyHandle GetDuplicatedKeyHandle()
            {
                ThrowIfDisposed();

                int keySize = KeySize;

                if (_lastKeySize != keySize)
                {
                    if (_keyHandle != null)
                    {
                        _keyHandle.Dispose();
                    }

                    const string BCRYPT_DSA_ALGORITHM = "DSA";

                    _keyHandle   = CngKeyLite.GenerateNewExportableKey(BCRYPT_DSA_ALGORITHM, keySize);
                    _lastKeySize = keySize;
                }

                return(new DuplicateSafeNCryptKeyHandle(_keyHandle !));
            }
            private SafeNCryptKeyHandle GetDuplicatedKeyHandle()
            {
                if (IsECNamedCurve(_lastAlgorithm))
                {
                    // Curve was previously created, so use that
                    return(new DuplicateSafeNCryptKeyHandle(_keyHandle));
                }
                else
                {
                    string algorithm = null;

                    int keySize = KeySize;
                    if (_lastKeySize != keySize)
                    {
                        // Map the current key size to a CNG algorithm name
                        switch (keySize)
                        {
                        case 256: algorithm = AlgorithmName.ECDsaP256; break;

                        case 384: algorithm = AlgorithmName.ECDsaP384; break;

                        case 521: algorithm = AlgorithmName.ECDsaP521; break;

                        default:
                            Debug.Fail("Should not have invalid key size");
                            throw new ArgumentException(SR.Cryptography_InvalidKeySize);
                        }
                        if (_keyHandle != null)
                        {
                            DisposeKey();
                        }
                        _keyHandle     = CngKeyLite.GenerateNewExportableKey(algorithm, keySize);
                        _lastKeySize   = keySize;
                        _lastAlgorithm = algorithm;
                        ForceSetKeySize(keySize);
                    }
                    return(new DuplicateSafeNCryptKeyHandle(_keyHandle));
                }
            }
            public override void GenerateKey(ECCurve curve)
            {
                curve.Validate();

                if (_keyHandle != null)
                {
                    DisposeKey();
                }

                string algorithm = null;
                int    keySize   = 0;

                if (curve.IsNamed)
                {
                    if (string.IsNullOrEmpty(curve.Oid.FriendlyName))
                    {
                        throw new PlatformNotSupportedException(string.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value));
                    }

                    // Map curve name to algorithm to support pre-Win10 curves
                    algorithm = ECCng.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName);
                    if (IsECNamedCurve(algorithm))
                    {
                        try
                        {
                            _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, curve.Oid.FriendlyName);
                            keySize    = CngKeyLite.GetKeyLength(_keyHandle);
                        }
                        catch (CryptographicException e)
                        {
                            // Map to PlatformNotSupportedException if appropriate
                            ErrorCode errorCode = (ErrorCode)e.HResult;

                            if (curve.IsNamed &&
                                errorCode == ErrorCode.NTE_INVALID_PARAMETER || errorCode == ErrorCode.NTE_NOT_SUPPORTED)
                            {
                                throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Oid.FriendlyName), e);
                            }
                            throw;
                        }
                    }
                    else
                    {
                        // Get the proper KeySize from algorithm name
                        if (algorithm == AlgorithmName.ECDsaP256)
                        {
                            keySize = 256;
                        }
                        else if (algorithm == AlgorithmName.ECDsaP384)
                        {
                            keySize = 384;
                        }
                        else if (algorithm == AlgorithmName.ECDsaP521)
                        {
                            keySize = 521;
                        }
                        else
                        {
                            Debug.Fail(string.Format("Unknown algorithm {0}", algorithm.ToString()));
                            throw new ArgumentException(SR.Cryptography_InvalidKeySize);
                        }
                        _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, keySize);
                    }
                }
                else if (curve.IsExplicit)
                {
                    algorithm  = AlgorithmName.ECDsa;
                    _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, ref curve);
                    keySize    = CngKeyLite.GetKeyLength(_keyHandle);
                }
                else
                {
                    throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString()));
                }

                _lastAlgorithm = algorithm;
                _lastKeySize   = keySize;
                ForceSetKeySize(keySize);
            }
Exemple #20
0
        internal void GenerateKey(ECCurve curve)
        {
            curve.Validate();
            ThrowIfDisposed();

            if (_keyHandle != null)
            {
                DisposeKey();
            }

            string algorithm;
            int    keySize = 0;

            if (curve.IsNamed)
            {
                if (string.IsNullOrEmpty(curve.Oid.FriendlyName))
                {
                    throw new PlatformNotSupportedException(
                              SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value));
                }

                // Map curve name to algorithm to support pre-Win10 curves
                if (_algorithmGroup == BCryptNative.AlgorithmName.ECDsa)
                {
                    algorithm = ECCng.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName);
                }
                else
                {
                    Debug.Assert(_algorithmGroup == BCryptNative.AlgorithmName.ECDH);
                    algorithm = ECCng.EcdhCurveNameToAlgorithm(curve.Oid.FriendlyName);
                }

                if (ECCng.IsECNamedCurve(algorithm))
                {
                    try
                    {
                        _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, curve.Oid.FriendlyName);
                        keySize    = CngKeyLite.GetKeyLength(_keyHandle);
                    }
                    catch (CryptographicException e)
                    {
                        // Map to PlatformNotSupportedException if appropriate
                        Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult;

                        if (curve.IsNamed && errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER ||
                            errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED)
                        {
                            throw new PlatformNotSupportedException(
                                      SR.Format(SR.Cryptography_CurveNotSupported, curve.Oid.FriendlyName), e);
                        }

                        throw;
                    }
                }
                else
                {
                    // Get the proper KeySize from algorithm name
                    switch (algorithm)
                    {
                    case BCryptNative.AlgorithmName.ECDsaP256:
                    case BCryptNative.AlgorithmName.ECDHP256:
                        keySize = 256;
                        break;

                    case BCryptNative.AlgorithmName.ECDsaP384:
                    case BCryptNative.AlgorithmName.ECDHP384:
                        keySize = 384;
                        break;

                    case BCryptNative.AlgorithmName.ECDsaP521:
                    case BCryptNative.AlgorithmName.ECDHP521:
                        keySize = 521;
                        break;

                    default:
                        Debug.Fail($"Unknown algorithm {algorithm}");
                        throw new ArgumentException(SR.Cryptography_InvalidKeySize);
                    }

                    _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, keySize);
                }
            }
            else if (curve.IsExplicit)
            {
                algorithm  = _algorithmGroup;
                _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, ref curve);
                keySize    = CngKeyLite.GetKeyLength(_keyHandle);
            }
            else
            {
                throw new PlatformNotSupportedException(
                          SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString()));
            }

            _lastAlgorithm = algorithm;
            _lastKeySize   = keySize;
            KeySize        = keySize;
        }