private static void ReadGenericBlob(BinaryReader reader, int expectedSize, ECParameters dest, bool includePrivateParameters) { /* struct BCRYPT_ECCFULLKEY_BLOB * { * ULONG dwMagic; // BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC or BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC * BCRYPT_ECC_PARAMETER_HEADER curveParameters; * BYTE Qx[cbFieldLength] // X-coordinate of the public point. * BYTE Qy[cbFieldLength] // Y-coordinate of the public point. * BYTE d[cbSubgroupOrder] // Private key. Zero if only public key is required. * } */ // The magic was read before. var curve = new BCRYPT_ECC_PARAMETER_HEADER(); curve.ReadFrom(reader); if (!curve.Equals(Secp256k1)) { throw new NotSupportedException($"Unsupported curve: {curve}"); } dest.Curve = JsonWebKeyCurveName.P256K; var cbFieldLength = curve.Prime.Length; dest.X = ValidateSize(reader.ReadBytes(cbFieldLength), expectedSize, nameof(dest.X)); dest.Y = ValidateSize(reader.ReadBytes(cbFieldLength), expectedSize, nameof(dest.Y)); if (includePrivateParameters) { dest.D = ValidateSize(reader.ReadBytes(cbFieldLength), expectedSize, nameof(dest.D)); } }
private ECDsaCng ToGenericCurveEcdsa(int dwMagic, BCRYPT_ECC_PARAMETER_HEADER curveParameters, bool includePrivateParameters) { var sizeInBytes = curveParameters.KeySizeInBytes; var keyBlob = new byte[curveParameters.KeyBlobSize]; using (var writer = new BinaryWriter(new MemoryStream(keyBlob))) { writer.Write(dwMagic); curveParameters.WriteTo(writer); AlignAndWrite(writer, X, sizeInBytes, nameof(X)); AlignAndWrite(writer, Y, sizeInBytes, nameof(Y)); if (includePrivateParameters) { AlignAndWrite(writer, D, sizeInBytes, nameof(D)); } } var key = CngKey.Import(keyBlob, includePrivateParameters ? CngKeyBlobFormat_EccFullPrivateBlob : CngKeyBlobFormat_EccFullPublicBlob); return(new ECDsaCng(key)); }