36f44f2014-01-28Henrik Grubbström (Grubba) //! ECDSA operations. #pike __REAL_VERSION__ #pragma strict_types
e1fb092014-02-14Martin Nilsson #require constant(Crypto.ECC)
36f44f2014-01-28Henrik Grubbström (Grubba)  import Standards.ASN1.Types; //! Lookup from ASN.1 DER encoded ECC named curve identifier to //! the corresponding @[Crypto.ECC.Curve]. protected mapping(string:Crypto.ECC.Curve) curve_lookup = ([]); protected void create() { // Initialize the curve_lookup table. foreach(values(Crypto.ECC), mixed c) {
321d4a2014-01-29Henrik Grubbström (Grubba)  if (!objectp(c) || !functionp(([object]c)->pkcs_named_curve_id)) continue; object(Crypto.ECC.Curve) curve = [object(Crypto.ECC.Curve)]c; curve_lookup[curve->pkcs_named_curve_id()->get_der()] = curve;
36f44f2014-01-28Henrik Grubbström (Grubba)  } } //! Get the ECC curve corresponding to an ASN.1 DER encoded //! named curve identifier. //! //! @returns //! Returns @[UNDEFINED] if the curve is unsupported. Crypto.ECC.Curve parse_ec_parameters(string ec_parameters) { return curve_lookup[ec_parameters]; } //! Create a DER-coded ECPrivateKey structure //! @param ecdsa //! @[Crypto.ECC.Curve()->ECDSA] object. //! @returns
0c4ea52015-08-22Martin Nilsson //! ASN.1 coded ECPrivateKey structure as specified in //! @rfc{5915:3@}.
36f44f2014-01-28Henrik Grubbström (Grubba) string(8bit) private_key(Crypto.ECC.SECP_521R1.ECDSA ecdsa) { // ECPrivateKey ::= SEQUENCE { return Sequence(({ // version INTEGER, 1, // privateKey OCTET STRING, OctetString(sprintf("%*c",
321d4a2014-01-29Henrik Grubbström (Grubba)  [int(0..)]((ecdsa->size() + 7)>>3),
36f44f2014-01-28Henrik Grubbström (Grubba)  ecdsa->get_private_key())), // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
f4ca2a2015-01-25Martin Nilsson  TaggedType0(ecdsa->get_curve()->pkcs_ec_parameters()),
36f44f2014-01-28Henrik Grubbström (Grubba)  // publicKey [1] BIT STRING OPTIONAL
321d4a2014-01-29Henrik Grubbström (Grubba)  TaggedType1(BitString(ecdsa->get_public_key())), }))->get_der();
36f44f2014-01-28Henrik Grubbström (Grubba)  // } } //! Get an initialized ECDSA object from an ECC curve and
5ece3a2014-05-13Henrik Grubbström (Grubba) //! an ASN.1 ec private key sequence.
36f44f2014-01-28Henrik Grubbström (Grubba) //!
0c4ea52015-08-22Martin Nilsson //! As specified in @rfc{5915:3@}.
5ece3a2014-05-13Henrik Grubbström (Grubba) Crypto.ECC.SECP_521R1.ECDSA parse_private_key(Sequence a,
321d4a2014-01-29Henrik Grubbström (Grubba)  Crypto.ECC.Curve|void c)
36f44f2014-01-28Henrik Grubbström (Grubba) {
321d4a2014-01-29Henrik Grubbström (Grubba)  if ((sizeof(a->elements) < 2) ||
36f44f2014-01-28Henrik Grubbström (Grubba)  (a->elements[0]->type_name != "INTEGER") || (a->elements[0]->value != 1) || (a->elements[1]->type_name != "OCTET STRING")) { return UNDEFINED; }
321d4a2014-01-29Henrik Grubbström (Grubba)  if ((sizeof(a->elements) > 2) && (a->elements[2]->type_name == "EXPLICIT") && !a->elements[2]->get_tag()) { Sequence b = [object(Sequence)]a->elements[2]; if ((sizeof(b->elements) == 1)) { c = parse_ec_parameters([string(8bit)]b->elements[0]->get_der()); } } if (!c) return UNDEFINED;
36f44f2014-01-28Henrik Grubbström (Grubba)  Crypto.ECC.SECP_521R1.ECDSA res = c->ECDSA();
321d4a2014-01-29Henrik Grubbström (Grubba)  res->set_private_key(Gmp.mpz([string(8bit)]a->elements[1]->value, 256));
36f44f2014-01-28Henrik Grubbström (Grubba)  return res; }
5ece3a2014-05-13Henrik Grubbström (Grubba)  //! Get an initialized ECDSA object from an ECC curve and //! an ASN.1 DER encoded ec private key. //!
0c4ea52015-08-22Martin Nilsson //! As specified in @rfc{5915:3@}.
5ece3a2014-05-13Henrik Grubbström (Grubba) variant Crypto.ECC.SECP_521R1.ECDSA parse_private_key(string(8bit) ec_private_key, Crypto.ECC.Curve|void c) { Object o = Standards.ASN1.Decode.simple_der_decode(ec_private_key); if (!o || o->type_name != "SEQUENCE") return UNDEFINED; return parse_private_key([object(Sequence)]o, c); }