private static SscECParameters ConvertToECParameters(KVECParameters inputParameters) { var curve = inputParameters.Curve switch { "P-256" => ECCurve.NamedCurves.nistP256, "P-384" => ECCurve.NamedCurves.nistP384, "P521" => ECCurve.NamedCurves.nistP521, _ => throw new NotSupportedException(), }; return(new SscECParameters { Curve = curve, D = inputParameters.D, Q = new ECPoint { X = inputParameters.X, Y = inputParameters.Y } }); }
internal static ECParameters FromEcdsa(ECDsaCng ecdsa, bool includePrivateParameters) { if (ecdsa == null) { throw new ArgumentNullException(nameof(ecdsa)); } var keyBlobFormat = includePrivateParameters ? CngKeyBlobFormat.EccPrivateBlob : CngKeyBlobFormat.EccPublicBlob; var keyBlob = ecdsa.Key.Export(keyBlobFormat); // If curve is generic, we need to export again to get the full blob. var dwMagic = BitConverter.ToInt32(keyBlob, 0); switch (dwMagic) { case BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC: keyBlob = ecdsa.Key.Export(CngKeyBlobFormat_EccFullPublicBlob); break; case BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC: keyBlob = ecdsa.Key.Export(CngKeyBlobFormat_EccFullPrivateBlob); break; } var result = new ECParameters(); using (var reader = new BinaryReader(new MemoryStream(keyBlob))) { dwMagic = reader.ReadInt32(); switch (dwMagic) { case BCRYPT_ECDSA_PUBLIC_P256_MAGIC: ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_P256_MAGIC, dwMagic); ReadNistBlob(reader, 32, result, false); result.Curve = JsonWebKeyCurveName.P256; break; case BCRYPT_ECDSA_PRIVATE_P256_MAGIC: ReadNistBlob(reader, 32, result, true); result.Curve = JsonWebKeyCurveName.P256; break; case BCRYPT_ECDSA_PUBLIC_P384_MAGIC: ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_P384_MAGIC, dwMagic); ReadNistBlob(reader, 48, result, false); result.Curve = JsonWebKeyCurveName.P384; break; case BCRYPT_ECDSA_PRIVATE_P384_MAGIC: ReadNistBlob(reader, 48, result, true); result.Curve = JsonWebKeyCurveName.P384; break; case BCRYPT_ECDSA_PUBLIC_P521_MAGIC: ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_P521_MAGIC, dwMagic); ReadNistBlob(reader, 66, result, false); result.Curve = JsonWebKeyCurveName.P521; break; case BCRYPT_ECDSA_PRIVATE_P521_MAGIC: ReadNistBlob(reader, 66, result, true); result.Curve = JsonWebKeyCurveName.P521; break; case BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC: ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC, dwMagic); ReadGenericBlob(reader, 32, result, false); break; case BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC: ReadGenericBlob(reader, 32, result, true); break; default: throw new NotSupportedException($"Unexpected CNG key blob type. Magic number: 0x{dwMagic:X}."); } } return(result); }
/// <summary> /// Exports EC parameters from a CNG object. /// </summary> /// <param name="ecdsa">The CNG object initialized with desired key</param> /// <param name="includePrivateParameters">Determines whether the private key part is to be exported.</param> /// <returns></returns> public static ECParameters ExportParameters(this ECDsa ecdsa, bool includePrivateParameters) { var ecdsaCng = GetEcdsaCng(ecdsa); return(ECParameters.FromEcdsa(ecdsaCng, includePrivateParameters)); }