ade34c2002-11-27Martin Nilsson  //! RSA operations and types as described in PKCS-1.
204d6f1997-11-30Niels Möller 
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
f49ea82003-01-27Martin Nilsson // #pragma strict_types
a20af62000-09-26Fredrik Hübinette (Hubbe) 
a75eb42013-10-29Martin Nilsson #if constant(Crypto.RSA)
92dbd31999-08-24Fredrik Hübinette (Hubbe) 
b6c4f11998-06-12H. William Welliver III import Standards.ASN1.Types;
60c4622013-11-18Martin Nilsson //! Returns the AlgorithmIdentifier as defined in RFC5280 section //! 4.1.1.2. Optionally the DSA parameters are included, if a DSA //! object is given as argument. Sequence algorithm_identifier() { return Sequence( ({ .Identifiers.rsa_id, Null() }) ); }
6250662002-11-27H. William Welliver III //! Create a DER-coded RSAPublicKey structure //! @param rsa
34adca2004-02-03Martin Nilsson //! @[Crypto.RSA] object
6250662002-11-27H. William Welliver III //! @returns //! ASN1 coded RSAPublicKey structure
34adca2004-02-03Martin Nilsson string public_key(Crypto.RSA rsa)
b6c4f11998-06-12H. William Welliver III {
597af62013-10-16Martin Nilsson  return Sequence(({ Integer(rsa->get_n()), Integer(rsa->get_e()) })) ->get_der();
b6c4f11998-06-12H. William Welliver III }
204d6f1997-11-30Niels Möller 
6250662002-11-27H. William Welliver III //! Create a DER-coded RSAPrivateKey structure //! @param rsa
34adca2004-02-03Martin Nilsson //! @[Crypto.RSA] object
6250662002-11-27H. William Welliver III //! @returns //! ASN1 coded RSAPrivateKey structure
34adca2004-02-03Martin Nilsson string private_key(Crypto.RSA rsa)
204d6f1997-11-30Niels Möller {
f49ea82003-01-27Martin Nilsson  Gmp.mpz n = rsa->get_n(); Gmp.mpz e = rsa->get_e(); Gmp.mpz d = rsa->get_d(); Gmp.mpz p = rsa->get_p(); Gmp.mpz q = rsa->get_q();
bc0a802000-06-13Henrik Grubbström (Grubba) 
f49ea82003-01-27Martin Nilsson  return Sequence(map(
bc0a802000-06-13Henrik Grubbström (Grubba)  ({ 0, n, e, d, p, q, d % (p - 1), d % (q - 1), q->invert(p) % p
204d6f1997-11-30Niels Möller  }),
f49ea82003-01-27Martin Nilsson  Integer))->get_der();
b6c4f11998-06-12H. William Welliver III }
6250662002-11-27H. William Welliver III //! Decode a DER-coded RSAPublicKey structure //! @param key
903f112013-11-19Martin Nilsson //! RSAPublicKey provided in ASN.1 DER-encoded format
6250662002-11-27H. William Welliver III //! @returns
34adca2004-02-03Martin Nilsson //! @[Crypto.RSA] object Crypto.RSA parse_public_key(string key)
b6c4f11998-06-12H. William Welliver III {
f49ea82003-01-27Martin Nilsson  Object a = Standards.ASN1.Decode.simple_der_decode(key);
b6c4f11998-06-12H. William Welliver III  if (!a || (a->type_name != "SEQUENCE") || (sizeof(a->elements) != 2) || (sizeof(a->elements->type_name - ({ "INTEGER" }))) ) return 0;
f49ea82003-01-27Martin Nilsson 
34adca2004-02-03Martin Nilsson  Crypto.RSA rsa = Crypto.RSA();
b6c4f11998-06-12H. William Welliver III  rsa->set_public_key(a->elements[0]->value, a->elements[1]->value); return rsa;
204d6f1997-11-30Niels Möller }
6250662002-11-27H. William Welliver III //! Decode a DER-coded RSAPrivateKey structure //! @param key
903f112013-11-19Martin Nilsson //! RSAPrivateKey provided in ASN.1 DER-encoded format
6250662002-11-27H. William Welliver III //! @returns
34adca2004-02-03Martin Nilsson //! @[Crypto.RSA] object Crypto.RSA parse_private_key(string key)
204d6f1997-11-30Niels Möller {
f49ea82003-01-27Martin Nilsson  Object a = Standards.ASN1.Decode.simple_der_decode(key);
b6c4f11998-06-12H. William Welliver III 
204d6f1997-11-30Niels Möller  if (!a
b6c4f11998-06-12H. William Welliver III  || (a->type_name != "SEQUENCE") || (sizeof(a->elements) != 9) || (sizeof(a->elements->type_name - ({ "INTEGER" }))) || a->elements[0]->value)
204d6f1997-11-30Niels Möller  return 0;
34adca2004-02-03Martin Nilsson  Crypto.RSA rsa = Crypto.RSA();
b6c4f11998-06-12H. William Welliver III  rsa->set_public_key(a->elements[1]->value, a->elements[2]->value); rsa->set_private_key(a->elements[3]->value, a->elements[4..]->value);
204d6f1997-11-30Niels Möller  return rsa; }
60c4622013-11-18Martin Nilsson //! Creates a SubjectPublicKeyInfo ASN.1 sequence for the given @[rsa] //! object. See RFC 5280 section 4.1.2.7.
1928692013-10-28Martin Nilsson Sequence build_public_key(Crypto.RSA rsa)
204d6f1997-11-30Niels Möller {
597af62013-10-16Martin Nilsson  return Sequence(({
60c4622013-11-18Martin Nilsson  algorithm_identifier(),
597af62013-10-16Martin Nilsson  BitString( public_key(rsa) ), }));
204d6f1997-11-30Niels Möller }
4043031999-03-03Niels Möller 
5a5c762013-10-28Martin Nilsson //! Returns the PKCS-1 algorithm identifier for RSA and the provided //! hash algorithm. One of @[MD2], @[MD5] or @[SHA1]. Sequence signature_algorithm_id(Crypto.Hash hash) {
b2ab992013-11-11Martin Nilsson  switch(hash->name())
5a5c762013-10-28Martin Nilsson  {
b2ab992013-11-11Martin Nilsson  case "md2":
5a5c762013-10-28Martin Nilsson  return Sequence( ({ .Identifiers.rsa_md2_id, Null() }) ); break;
b2ab992013-11-11Martin Nilsson  case "md5":
5a5c762013-10-28Martin Nilsson  return Sequence( ({ .Identifiers.rsa_md5_id, Null() }) ); break;
b2ab992013-11-11Martin Nilsson  case "sha1":
5a5c762013-10-28Martin Nilsson  return Sequence( ({ .Identifiers.rsa_sha1_id, Null() }) ); break;
fb9f5e2013-11-22Martin Nilsson  case "sha256": return Sequence( ({ .Identifiers.rsa_sha256_id, Null() }) ); break; case "sha384": return Sequence( ({ .Identifiers.rsa_sha384_id, Null() }) ); break; case "sha512": return Sequence( ({ .Identifiers.rsa_sha512_id, Null() }) ); break;
5a5c762013-10-28Martin Nilsson  } return 0; }
ffaf452004-04-14Martin Nilsson #else constant this_program_does_not_exist=1;
45458c1999-12-22Per Hedbor #endif