private static BigInteger ExtractPrivateKeyFromAsn1(byte[] asn1PrivKey)
{
// To understand this code, see the definition of the ASN.1 format for EC private keys in the OpenSSL source
// code in ec_asn1.c:
//
// ASN1_SEQUENCE(EC_PRIVATEKEY) = {
// ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
// ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
// ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
// ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
// } ASN1_SEQUENCE_END(EC_PRIVATEKEY)
//
DerOctetString key;
using (var decoder = new Asn1InputStream(asn1PrivKey))
{
var seq = (DerSequence) decoder.ReadObject();
Debug.Assert(seq.Count == 4, "Input does not appear to be an ASN.1 OpenSSL EC private key");
Debug.Assert(((DerInteger) seq[0]).Value.Equals(BigInteger.One), "Input is of wrong version");
key = (DerOctetString) seq[1];
}
return new BigInteger(1, key.GetOctets());
}