# # patch "keys.cc" # from [e2791265d875cd65ad911cf2fbe7642238040fd3] # to [9c50dc0d669ffb6ad2328c46485bf3ae65dad4b5] # # patch "keys.hh" # from [f10aaea8dbaf4005a55ec388f278d1bb81d664af] # to [ec2da9cbde80341456204b6e0e0b4f727388ed8b] # # patch "vocab_terms.hh" # from [c12dd87ed775d3e2d8713a393cc055ce68e5ae16] # to [37273b9af033700b030b6831c12a3ad6aacd27c7] # --- keys.cc +++ keys.cc @@ -391,6 +391,75 @@ return vf->GetLastResult(); } +void encrypt_rsa(lua_hooks & lua, + rsa_keypair_id const & id, + base64 & pub_encoded, + std::string const & plaintext, + rsa_oaep_sha_data & ciphertext) +{ + AutoSeededRandomPool rng(blocking_rng(lua)); + + rsa_pub_key pub; + decode_base64(pub_encoded, pub); + SecByteBlock pub_block; + pub_block.Assign(reinterpret_cast(pub().data()), pub().size()); + StringSource keysource(pub_block.data(), pub_block.size(), true); + + shared_ptr encryptor; + encryptor = shared_ptr + (new RSAES_OAEP_SHA_Encryptor(keysource)); + + string ciphertext_string; + StringSource tmp(plaintext, true, + encryptor->CreateEncryptionFilter + (rng, new StringSink(ciphertext_string))); + + ciphertext = rsa_oaep_sha_data(ciphertext_string); +} + +void decrypt_rsa(lua_hooks & lua, + rsa_keypair_id const & id, + base64< arc4 > const & priv, + rsa_oaep_sha_data const & ciphertext, + std::string & plaintext) +{ + AutoSeededRandomPool rng(blocking_rng(lua)); + arc4 decoded_key; + SecByteBlock decrypted_key; + SecByteBlock phrase; + shared_ptr decryptor; + + for (int i = 0; i < 3; i++) + { + bool force = false; + decode_base64(priv, decoded_key); + decrypted_key.Assign(reinterpret_cast(decoded_key().data()), + decoded_key().size()); + get_passphrase(lua, id, phrase, false, force); + + try + { + do_arc4(phrase, decrypted_key); + StringSource keysource(decrypted_key.data(), decrypted_key.size(), true); + decryptor = shared_ptr + (new RSAES_OAEP_SHA_Decryptor(keysource)); + } + catch (...) + { + if (i >= 2) + throw informative_failure("failed to decrypt private RSA key, " + "probably incorrect passphrase"); + // don't use the cache bad one next time + force = true; + continue; + } + } + + StringSource tmp(ciphertext(), true, + decryptor->CreateDecryptionFilter + (rng, new StringSink(plaintext))); +} + void read_pubkey(string const & in, rsa_keypair_id & id, --- keys.hh +++ keys.hh @@ -42,6 +42,18 @@ void require_password(rsa_keypair_id const & id, app_state & app); +void encrypt_rsa(lua_hooks & lua, + rsa_keypair_id const & id, + base64 & pub, + std::string const & plaintext, + rsa_oaep_sha_data & ciphertext); + +void decrypt_rsa(lua_hooks & lua, + rsa_keypair_id const & id, + base64< arc4 > const & priv, + rsa_oaep_sha_data const & ciphertext, + std::string & plaintext); + // netsync stuff void read_pubkey(std::string const & in, --- vocab_terms.hh +++ vocab_terms.hh @@ -34,6 +34,7 @@ ATOMIC_NOVERIFY(rsa_pub_key); // some nice numbers ATOMIC_NOVERIFY(rsa_priv_key); // some nice numbers ATOMIC_NOVERIFY(rsa_sha1_signature); // some other nice numbers +ATOMIC_NOVERIFY(rsa_oaep_sha_data); DECORATE(revision); // thing associated with a revision DECORATE(manifest); // thing associated with a manifest