Exemple #1
0
        public unsafe void SetPeerKey(ReadableBuffer peerKey)
        {
            if (peerKey.Length != _keyExchangeSize)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.illegal_parameter, $"The client key didn't match the expected length");
            }
            int cbKey;

            peerKey = peerKey.Slice(1);
            cbKey   = peerKey.Length / 2;
            GenerateKeys();
            int keyLength = peerKey.Length;
            //Now we have the point and can load the key
            var keyBuffer  = stackalloc byte[keyLength + 8];
            var blobHeader = new BCRYPT_ECCKEY_BLOB();

            blobHeader.Magic = KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC;
            blobHeader.cbKey = cbKey;
            Marshal.StructureToPtr(blobHeader, (IntPtr)keyBuffer, false);
            peerKey.CopyTo(new Span <byte>(keyBuffer + 8, keyLength));
            SafeBCryptKeyHandle keyHandle;

            ExceptionHelper.CheckReturnCode(BCryptImportKeyPair(_algo, IntPtr.Zero, KeyBlobType.BCRYPT_ECCPUBLIC_BLOB, out keyHandle, (IntPtr)keyBuffer, keyLength + 8, 0));
            _peerKey    = keyHandle;
            _hasPeerKey = true;
        }
Exemple #2
0
 internal static unsafe partial NTSTATUS BCryptKeyDerivation(
     SafeBCryptKeyHandle hKey,
     BCryptBufferDesc *pParameterList,
     byte *pbDerivedKey,
     int cbDerivedKey,
     out uint pcbResult,
     int dwFlags);
        /// <summary>
        /// Method take BCrypt handle as input and returns the CNGKey
        /// </summary>
        /// <param name="bcryptKeyHandle">Accepts BCrypt Handle</param>
        /// <returns>Returns CNG key with NCrypt Handle</returns>
        private static CngKey LegacyBCryptHandleToNCryptHandle(SafeBCryptKeyHandle bcryptKeyHandle)
        {
            byte[] keyBlob = BCryptNative.ExportBCryptKey(bcryptKeyHandle, BCryptNative.BCRYPT_ECCPUBLIC_BLOB);
            //Now Import the key blob as NCRYPT_KEY_HANDLE
            CngKey Key = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob);

            return(Key);
        }
 internal static extern int BCryptExportKey(
     [In] SafeBCryptKeyHandle hKey,
     [In] IntPtr hExportKey,
     [In, MarshalAs(UnmanagedType.LPWStr)] string pszBlobType,
     [Out] byte[] pbOutput,
     [In] uint cbOutput,
     [Out] out uint pcbResult,
     [In] uint dwFlags);
Exemple #5
0
 internal static unsafe partial NTSTATUS BCryptGenerateSymmetricKey(
     nuint hAlgorithm,
     out SafeBCryptKeyHandle phKey,
     IntPtr pbKeyObject,
     int cbKeyObject,
     byte *pbSecret,
     int cbSecret,
     uint dwFlags);
 private static bool HasProperty(SafeBCryptKeyHandle cryptHandle, string propertyName)
 {
     Debug.Assert(!cryptHandle.IsInvalid);
     unsafe
     {
         int numBytesNeeded;
         BCryptNative.ErrorCode errorCode = BCryptNative.UnsafeNativeMethods.BCryptGetProperty(cryptHandle, propertyName, null, 0, out numBytesNeeded, 0);
         return(errorCode == BCryptNative.ErrorCode.Success && numBytesNeeded > 0);
     }
 }
        public static ECDsa GetECDsaPublicKey(this X509Certificate2 certificate)
        {
            if (LocalAppContextSwitches.UseLegacyPublicKeyBehavior)
            {
                return(LegacyGetECDsaPublicKey(certificate));
            }

            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            if (!IsECDsa(certificate))
            {
                return(null);
            }

            using (SafeCertContextHandle safeCertContext = X509Native.GetCertificateContext(certificate))
                using (SafeBCryptKeyHandle bcryptKeyHandle = ImportPublicKeyInfo(safeCertContext))
                {
                    if (bcryptKeyHandle.IsInvalid)
                    {
                        throw new CryptographicException("SR.GetString(SR.Cryptography_OpenInvalidHandle)");
                    }

                    string curveName = GetCurveName(bcryptKeyHandle);

                    if (curveName == null)
                    {
                        CngKeyBlobFormat blobFormat = HasExplicitParameters(bcryptKeyHandle) ?
                                                      CngKeyBlobFormat.EccFullPublicBlob : CngKeyBlobFormat.EccPublicBlob;

                        byte[] keyBlob = BCryptNative.ExportBCryptKey(bcryptKeyHandle, blobFormat.Format);
                        using (CngKey key = CngKey.Import(keyBlob, blobFormat))
                        {
                            return(new ECDsaCng(key));
                        }
                    }
                    else
                    {
                        CngKeyBlobFormat blobFormat = CngKeyBlobFormat.EccPublicBlob;
                        byte[]           keyBlob    = BCryptNative.ExportBCryptKey(bcryptKeyHandle, blobFormat.Format);
                        ECParameters     ecparams   = new ECParameters();
                        ExportNamedCurveParameters(ref ecparams, keyBlob, false);
                        ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
                        ECDsaCng ecdsa = new ECDsaCng();
                        ecdsa.ImportParameters(ecparams);

                        return(ecdsa);
                    }
                }
        }
        public BasicSymmetricCipherBCrypt(SafeBCryptAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, byte[] iv, bool encrypting)
            : base(cipherMode.GetCipherIv(iv), blockSizeInBytes)
        {
            Debug.Assert(algorithm != null);

            _encrypting = encrypting;

            if (IV != null)
            {
                _currentIv = new byte[IV.Length];
            }

            _hKey = BCryptNative.BCryptImportKey(algorithm, key);

            Reset();
        }
        private static string GetPropertyAsString(SafeBCryptKeyHandle cryptHandle, string propertyName)
        {
            Debug.Assert(!cryptHandle.IsInvalid);
            byte[] value = GetProperty(cryptHandle, propertyName);
            if (value == null || value.Length == 0)
            {
                return(null);
            }

            unsafe
            {
                fixed(byte *pValue = &value[0])
                {
                    string valueAsString = Marshal.PtrToStringUni((IntPtr)pValue);

                    return(valueAsString);
                }
            }
        }
Exemple #10
0
        internal BCryptSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                byte[] key,
                                                byte[] iv,
                                                PaddingMode paddingMode,
                                                bool encrypting)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");
            Debug.Assert(key != null, "key != null");

            m_algorithm  = algorithm;
            m_encrypting = encrypting;

            m_paddingMode = BlockPaddingMethod.Create(paddingMode,
                                                      BCryptNative.GetInt32Property(algorithm, BCryptNative.ObjectPropertyName.BlockLength));
            m_iv = ProcessIV(iv, BCryptNative.GetInt32Property(algorithm,
                                                               BCryptNative.ObjectPropertyName.BlockLength),
                             BCryptNative.MapChainingMode(BCryptNative.GetStringProperty(algorithm, BCryptNative.ObjectPropertyName.ChainingMode)));
            m_key = BCryptNative.ImportSymmetricKey(algorithm, key);
        }
        private static SafeBCryptKeyHandle ImportPublicKeyInfo(SafeCertContextHandle certContext)
        {
            IntPtr certHandle = certContext.DangerousGetHandle();

            //Read the public key blob from the certificate
            X509Native.CERT_CONTEXT pCertContext = (X509Native.CERT_CONTEXT)Marshal.PtrToStructure(certHandle, typeof(X509Native.CERT_CONTEXT));

            IntPtr pSubjectPublicKeyInfo = new IntPtr((long)pCertContext.pCertInfo +
                                                      (long)Marshal.OffsetOf(typeof(X509Native.CERT_INFO), "SubjectPublicKeyInfo"));

            X509Native.CERT_PUBLIC_KEY_INFO certPublicKeyInfo =
                (X509Native.CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(pSubjectPublicKeyInfo, typeof(X509Native.CERT_PUBLIC_KEY_INFO));

            SafeBCryptKeyHandle publicKeyInfo = BCryptNative.ImportAsymmetricPublicKey(certPublicKeyInfo, 0);

            // certContext needs to be valid through the call to BCryptNative.ImportAsymmetricPublicKey
            // because certPublicKeyInfo structure contains pointers.
            GC.KeepAlive(certContext);
            return(publicKeyInfo);
        }
        internal BCryptSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                byte[] key,
                                                byte[] iv,
                                                PaddingMode paddingMode,
                                                bool encrypting)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");
            Debug.Assert(key != null, "key != null");

            m_algorithm = algorithm;
            m_encrypting = encrypting;

            m_paddingMode = BlockPaddingMethod.Create(paddingMode,
                                                      BCryptNative.GetInt32Property(algorithm, BCryptNative.ObjectPropertyName.BlockLength));
            m_iv = ProcessIV(iv, BCryptNative.GetInt32Property(algorithm,
                                                               BCryptNative.ObjectPropertyName.BlockLength),
                                                               BCryptNative.MapChainingMode(BCryptNative.GetStringProperty(algorithm, BCryptNative.ObjectPropertyName.ChainingMode)));
            m_key = BCryptNative.ImportSymmetricKey(algorithm, key);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                SafeBCryptKeyHandle hKey = _hKey;
                _hKey = null;
                if (hKey != null)
                {
                    hKey.Dispose();
                }

                byte[] currentIv = _currentIv;
                _currentIv = null;
                if (currentIv != null)
                {
                    Array.Clear(currentIv, 0, currentIv.Length);
                }
            }

            base.Dispose(disposing);
        }
        private static byte[] GetProperty(SafeBCryptKeyHandle cryptHandle, string propertyName)
        {
            Debug.Assert(!cryptHandle.IsInvalid);
            unsafe
            {
                int numBytesNeeded;
                BCryptNative.ErrorCode errorCode = BCryptNative.UnsafeNativeMethods.BCryptGetProperty(cryptHandle, propertyName, null, 0, out numBytesNeeded, 0);
                if (errorCode != BCryptNative.ErrorCode.Success)
                {
                    return(null);
                }

                byte[] propertyValue = new byte[numBytesNeeded];
                errorCode = BCryptNative.UnsafeNativeMethods.BCryptGetProperty(cryptHandle, propertyName, propertyValue, propertyValue.Length, out numBytesNeeded, 0);
                if (errorCode != BCryptNative.ErrorCode.Success)
                {
                    return(null);
                }

                Array.Resize(ref propertyValue, numBytesNeeded);
                return(propertyValue);
            }
        }
        private static ECDsa LegacyGetECDsaPublicKey(X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            if (!IsECDsa(certificate))
            {
                return(null);
            }

            SafeCertContextHandle safeCertContext = X509Native.GetCertificateContext(certificate);
            IntPtr certHandle = safeCertContext.DangerousGetHandle();

            //Read the public key blob from the certificate
            X509Native.CERT_CONTEXT pCertContext = (X509Native.CERT_CONTEXT)Marshal.PtrToStructure(certHandle, typeof(X509Native.CERT_CONTEXT));

            IntPtr pSubjectPublicKeyInfo = new IntPtr((long)pCertContext.pCertInfo +
                                                      (long)Marshal.OffsetOf(typeof(X509Native.CERT_INFO), "SubjectPublicKeyInfo"));

            X509Native.CERT_PUBLIC_KEY_INFO certPublicKeyInfo = (X509Native.CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(pSubjectPublicKeyInfo,
                                                                                                                        typeof(X509Native.CERT_PUBLIC_KEY_INFO));
            CngKey key;

            //Import the public key blob to BCRYPT_KEY_HANDLE
            using (SafeBCryptKeyHandle bcryptKeyHandle = BCryptNative.ImportAsymmetricPublicKey(certPublicKeyInfo, 0))
            {
                if (bcryptKeyHandle.IsInvalid)
                {
                    throw new CryptographicException("SR.GetString(SR.Cryptography_OpenInvalidHandle)");
                }
                key = LegacyBCryptHandleToNCryptHandle(bcryptKeyHandle);
            }
            GC.KeepAlive(safeCertContext);
            return(new ECDsaCng(key));
        }
 internal static extern NTSTATUS BCryptExportKey(SafeBCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, [Out] byte[] pbOutput, int cbOutput, out int pcbResult, int dwFlags);
Exemple #17
0
 internal static unsafe extern NTSTATUS BCryptSecretAgreement(SafeBCryptKeyHandle hPrivKey, SafeBCryptKeyHandle hPubKey, out SafeBCryptSecretHandle phSecret, int dwFlags);
 internal static unsafe partial bool CryptImportPublicKeyInfoEx2(
     CertEncodingType dwCertEncodingType,
     CERT_PUBLIC_KEY_INFO *pInfo,
     CryptImportPublicKeyInfoFlags dwFlags,
     void *pvAuxInfo,
     out SafeBCryptKeyHandle phKey);
Exemple #19
0
 public static extern NTStatus BCryptGenerateSymmetricKey(SafeBCryptAlgorithmHandle hAlgorithm, out SafeBCryptKeyHandle phKey, [Optional] IntPtr pbKeyObject, [Optional] int cbKeyObject, IntPtr pbSecret, int cbSecret, int dwFlags = 0);
Exemple #20
0
 public static extern NTStatus BCryptDecrypt(SafeBCryptKeyHandle hKey, IntPtr pbInput, int cbInput, IntPtr pPaddingInfo, IntPtr pbIV, int cbIV, [Optional] IntPtr pbOutput, [Optional] int cbOutput, out int pcbResult, int dwFlags);
Exemple #21
0
 public static extern unsafe bool CryptImportPublicKeyInfoEx2(CertEncodingType dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pInfo, int dwFlags, void *pvAuxInfo, out SafeBCryptKeyHandle phKey);
 internal static unsafe extern NTSTATUS BCryptFinalizeKeyPair(SafeBCryptKeyHandle hKey, int dwFlags);
 internal static unsafe extern NTSTATUS BCryptEncrypt(SafeBCryptKeyHandle hKey, void *pbInput, int cbInput, void *pPaddingInfo, void *pbIV, int cbIV, void *pbOutput, int cbOutput, out int pcbResult, int dwFlags);
 internal static extern bool CryptImportPublicKeyInfoEx2(
     [In] uint dwCertEncodingType,
     [In] SafeLocalAllocHandle pInfo,
     [In] uint dwFlags,
     [In] IntPtr pvAuxInfo,
     [Out] out SafeBCryptKeyHandle phKey);
Exemple #25
0
        internal BCryptAuthenticatedSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                             byte[] key,
                                                             byte[] nonce,
                                                             byte[] authenticatedData,
                                                             byte[] tag,
                                                             bool chainingSupported)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (tag == null)
            {
                throw new ArgumentNullException("tag");
            }

            bool initializationComplete = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                m_algorithm = algorithm;
                m_key       = BCryptNative.ImportSymmetricKey(algorithm, key);

                // Initialize the padding info structure.
                m_authInfo = new BCryptNative.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO();
                BCryptNative.InitializeAuthnenticatedCipherModeInfo(ref m_authInfo);

                if (nonce != null)
                {
                    m_authInfo.cbNonce = nonce.Length;
                    m_authInfo.pbNonce = Marshal.AllocCoTaskMem(m_authInfo.cbNonce);
                    Marshal.Copy(nonce, 0, m_authInfo.pbNonce, m_authInfo.cbNonce);
                }

                if (authenticatedData != null)
                {
                    m_authInfo.cbAuthData = authenticatedData.Length;
                    m_authInfo.pbAuthData = Marshal.AllocCoTaskMem(m_authInfo.cbAuthData);
                    Marshal.Copy(authenticatedData, 0, m_authInfo.pbAuthData, m_authInfo.cbAuthData);
                }

                if (chainingSupported)
                {
                    m_chainingSupported = chainingSupported;

                    m_authInfo.cbMacContext = tag.Length;
                    m_authInfo.pbMacContext = Marshal.AllocCoTaskMem(m_authInfo.cbMacContext);

                    BCryptNative.BCRYPT_KEY_LENGTHS_STRUCT tagLengths =
                        BCryptNative.GetValueTypeProperty <SafeBCryptAlgorithmHandle, BCryptNative.BCRYPT_KEY_LENGTHS_STRUCT>(
                            algorithm,
                            BCryptNative.ObjectPropertyName.AuthTagLength);

                    m_chainData = new byte[tagLengths.dwMaxLength];
                }
                else
                {
                    m_inputBuffer = new MemoryStream();
                }

                m_authInfo.cbTag = tag.Length;
                m_authInfo.pbTag = Marshal.AllocCoTaskMem(m_authInfo.cbTag);
                Marshal.Copy(tag, 0, m_authInfo.pbTag, m_authInfo.cbTag);

                // Set chaining mode if supported.
                if (CanChainBlocks)
                {
                    m_authInfo.dwFlags |= BCryptNative.AuthenticatedCipherModeInfoFlags.ChainCalls;
                }

                initializationComplete = true;
            }
            finally
            {
                // If we failed to complete initialization we may have already allocated some native
                // resources.  Clean those up before leaving the constructor.
                if (!initializationComplete)
                {
                    Dispose();
                }
            }
        }
 internal static extern NTSTATUS BCryptImportKey(SafeBCryptAlgorithmHandle hAlgorithm, IntPtr hImportKey, string pszBlobType, out SafeBCryptKeyHandle phKey, IntPtr pbKeyObject, int cbKeyObject, IntPtr pbInput, int cbInput, int dwFlags);
Exemple #27
0
 internal static extern NTSTATUS BCryptExportKey(SafeBCryptKeyHandle hKey, IntPtr encyrptKey, string blobType, IntPtr pbOutput, int cbOutput, out int pcbResult, int dwFlags);
Exemple #28
0
 internal static unsafe extern NTSTATUS BCryptGenerateKeyPair(SafeBCryptAlgorithmHandle hAlgorithm, out SafeBCryptKeyHandle phKey, int dwLength, int dwFlags);
        private static bool HasExplicitParameters(SafeBCryptKeyHandle bcryptHandle)
        {
            const string BCRYPT_ECC_PARAMETERS_PROPERTY = "ECCParameters";

            return(HasProperty(bcryptHandle, BCRYPT_ECC_PARAMETERS_PROPERTY));
        }
        private static string GetCurveName(SafeBCryptKeyHandle bcryptHandle)
        {
            const string BCRYPT_ECC_CURVE_NAME_PROPERTY = "ECCCurveName";

            return(GetPropertyAsString(bcryptHandle, BCRYPT_ECC_CURVE_NAME_PROPERTY));
        }