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; }
public unsafe static void Main(string[] args) { var thumb = "48026c976caaf7f3a72d38c17d16ce69d04a6053".ToUpper(); var cert = LoadCertificateFromStore(thumb, false, StoreLocation.CurrentUser, StoreName.My); var privKey = cert.GetECDsaPrivateKey(); var curve = privKey.ExportParameters(true); List <byte> currentSection = null; var lines = ecdsaKeyPEM.Split('\n'); for (int i = 0; i < lines.Length; i++) { if (lines[i].StartsWith("-----BEGIN")) { //Starting a block string blockName = lines[i].Substring("-----BEGIN ".Length, lines[i].LastIndexOf("-----") - "-----BEGIN ".Length); currentSection = new List <byte>(); _sections.Add(blockName, currentSection); continue; } else if (lines[i].StartsWith("-----END")) { //ending block currentSection = null; } currentSection?.AddRange(Convert.FromBase64String(lines[i].Trim())); } IntPtr prov, key; var res = NCryptOpenStorageProvider(out prov, "Microsoft Software Key Storage Provider", 0); //ECDSA_P521 var size = sizeof(BCRYPT_ECCKEY_BLOB); var blobHeader = new BCRYPT_ECCKEY_BLOB() { Magic = KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC, cbKey = _sections["EC PRIVATE KEY"].Count }; var desc = new BCryptBufferDesc() { cBuffers = 1 }; var buff = new BCryptBuffer() { BufferType = NCryptBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME, cbBuffer = "ECDSA_P521\0".Length * 2, pvBuffer = Marshal.StringToHGlobalUni("ECDSA_P521\0") }; var buffPtr = Marshal.AllocHGlobal(sizeof(BCryptBuffer)); Marshal.StructureToPtr(buff, buffPtr, true); desc.pBuffers = buffPtr; var descPtr = Marshal.AllocHGlobal(sizeof(BCryptBufferDesc)); Marshal.StructureToPtr(desc, descPtr, true); var bytes = new byte[size + blobHeader.cbKey]; _sections["EC PRIVATE KEY"].ToArray().CopyTo(bytes, size); fixed(void *blobPtr = bytes) { Unsafe.Copy(blobPtr, ref blobHeader); res = NCryptImportKey(prov, IntPtr.Zero, "ECCPRIVATEBLOB", descPtr, out key, (IntPtr)blobPtr, (uint)bytes.Length, 0); } }