diff options
-rw-r--r-- | src/cms/cms_algo.cpp | 6 | ||||
-rw-r--r-- | src/cms/cms_ealg.cpp | 85 | ||||
-rw-r--r-- | src/cms/cms_enc.h | 24 |
3 files changed, 72 insertions, 43 deletions
diff --git a/src/cms/cms_algo.cpp b/src/cms/cms_algo.cpp index efd016514..fadc68da5 100644 --- a/src/cms/cms_algo.cpp +++ b/src/cms/cms_algo.cpp @@ -49,9 +49,11 @@ SecureVector<byte> do_rfc3217_wrap(RandomNumberGenerator& rng, InitializationVector iv(rng, 8); InitializationVector fixed("4ADDA22C79E82105"); - Pipe pipe(get_cipher(cipher + "/CBC/NoPadding", kek, iv, ENCRYPTION), + Pipe pipe(get_cipher(global_state(), + cipher + "/CBC/NoPadding", kek, iv, ENCRYPTION), new Flip_Bytes(iv.bits_of()), - get_cipher(cipher + "/CBC/NoPadding", kek, fixed, ENCRYPTION)); + get_cipher(global_state(), + cipher + "/CBC/NoPadding", kek, fixed, ENCRYPTION)); pipe.start_msg(); pipe.write(input); pipe.write(icv.read_all()); diff --git a/src/cms/cms_ealg.cpp b/src/cms/cms_ealg.cpp index 7749200d2..becf24000 100644 --- a/src/cms/cms_ealg.cpp +++ b/src/cms/cms_ealg.cpp @@ -5,6 +5,8 @@ #include <botan/cms_enc.h> #include <botan/der_enc.h> +#include <botan/x509find.h> +#include <botan/x509_ca.h> #include <botan/bigint.h> #include <botan/oids.h> #include <botan/lookup.h> @@ -84,7 +86,8 @@ SecureVector<byte> encode_attr(const SecureVector<byte>& data, /************************************************* * Encrypt a message * *************************************************/ -void CMS_Encoder::encrypt(const X509_Certificate& to, +void CMS_Encoder::encrypt(RandomNumberGenerator& rng, + const X509_Certificate& to, const std::string user_cipher) { const std::string cipher = choose_algo(user_cipher, "TripleDES"); @@ -104,14 +107,14 @@ void CMS_Encoder::encrypt(const X509_Certificate& to, throw Internal_Error("CMS_Encoder::encrypt: " + algo + " can't encrypt"); - encrypt_ktri(to, enc_key, cipher); + encrypt_ktri(rng, to, enc_key, cipher); } else if(algo == "DH") { if(constraints != NO_CONSTRAINTS && !(constraints & KEY_AGREEMENT)) throw Invalid_Argument("CMS: Constraints not set for key agreement"); - encrypt_kari(to, key.get(), cipher); + encrypt_kari(rng, to, key.get(), cipher); } else throw Invalid_Argument("Unknown CMS PK encryption algorithm " + algo); @@ -120,7 +123,8 @@ void CMS_Encoder::encrypt(const X509_Certificate& to, /************************************************* * Encrypt a message with a key transport algo * *************************************************/ -void CMS_Encoder::encrypt_ktri(const X509_Certificate& to, +void CMS_Encoder::encrypt_ktri(RandomNumberGenerator& rng, + const X509_Certificate& to, PK_Encrypting_Key* pub_key, const std::string& cipher) { @@ -130,6 +134,9 @@ void CMS_Encoder::encrypt_ktri(const X509_Certificate& to, SymmetricKey cek = setup_key(rng, cipher); + AlgorithmIdentifier alg_id(OIDS::lookup(pk_algo + '/' + padding), + AlgorithmIdentifier::USE_NULL_PARAM); + DER_Encoder encoder; encoder.start_cons(SEQUENCE); encoder.encode((u32bit)0); @@ -137,11 +144,11 @@ void CMS_Encoder::encrypt_ktri(const X509_Certificate& to, encoder.start_cons(SEQUENCE); encoder.encode((u32bit)0); encode_si(encoder, to); - encoder.encode(AlgorithmIdentifier(pk_algo + "/" + padding)); - encoder.encode(enc->encrypt(cek.bits_of()), OCTET_STRING); + encoder.encode(alg_id); + encoder.encode(enc->encrypt(cek.bits_of(), rng), OCTET_STRING); encoder.end_cons(); encoder.end_cons(); - encoder.raw_bytes(do_encrypt(cek, cipher)); + encoder.raw_bytes(do_encrypt(rng, cek, cipher)); encoder.end_cons(); add_layer("CMS.EnvelopedData", encoder); @@ -150,7 +157,8 @@ void CMS_Encoder::encrypt_ktri(const X509_Certificate& to, /************************************************* * Encrypt a message with a key agreement algo * *************************************************/ -void CMS_Encoder::encrypt_kari(const X509_Certificate&, +void CMS_Encoder::encrypt_kari(RandomNumberGenerator&, + const X509_Certificate&, X509_PublicKey*, const std::string&) { @@ -169,7 +177,7 @@ void CMS_Encoder::encrypt_kari(const X509_Certificate&, encoder.encode(encrypted_cek, OCTET_STRING); encoder.end_cons(); encoder.end_cons(); - encoder.raw_bytes(do_encrypt(cek, cipher)); + encoder.raw_bytes(do_encrypt(rng, cek, cipher)); encoder.end_cons(); add_layer("CMS.EnvelopedData", encoder); @@ -179,7 +187,8 @@ void CMS_Encoder::encrypt_kari(const X509_Certificate&, /************************************************* * Encrypt a message with a shared key * *************************************************/ -void CMS_Encoder::encrypt(const SymmetricKey& kek, +void CMS_Encoder::encrypt(RandomNumberGenerator& rng, + const SymmetricKey& kek, const std::string& user_cipher) { throw Exception("FIXME: untested"); @@ -192,15 +201,16 @@ void CMS_Encoder::encrypt(const SymmetricKey& kek, DER_Encoder encoder; encoder.start_cons(SEQUENCE); encoder.encode((u32bit)2); - encoder.start_sequence(ASN1_Tag(2)); + encoder.start_explicit(ASN1_Tag(2)); encoder.encode((u32bit)4); encoder.start_cons(SEQUENCE); encoder.encode(kek_id, OCTET_STRING); encoder.end_cons(); - encoder.encode(AlgorithmIdentifier("KeyWrap." + cipher, true)); - encoder.encode(wrap_key(cipher, cek, kek), OCTET_STRING); + encoder.encode(AlgorithmIdentifier(OIDS::lookup("KeyWrap." + cipher), + AlgorithmIdentifier::USE_NULL_PARAM)); + encoder.encode(wrap_key(rng, cipher, cek, kek), OCTET_STRING); encoder.end_cons(); - encoder.raw_bytes(do_encrypt(cek, cipher)); + encoder.raw_bytes(do_encrypt(rng, cek, cipher)); encoder.end_cons(); add_layer("CMS.EnvelopedData", encoder); @@ -209,7 +219,8 @@ void CMS_Encoder::encrypt(const SymmetricKey& kek, /************************************************* * Encrypt a message with a passphrase * *************************************************/ -void CMS_Encoder::encrypt(const std::string&, +void CMS_Encoder::encrypt(RandomNumberGenerator& rng, + const std::string&, const std::string& user_cipher) { const std::string cipher = choose_algo(user_cipher, "TripleDES"); @@ -220,7 +231,7 @@ void CMS_Encoder::encrypt(const std::string&, DER_Encoder encoder; encoder.start_cons(SEQUENCE); encoder.encode(0); - encoder.raw_bytes(do_encrypt(cek, cipher)); + encoder.raw_bytes(do_encrypt(rng, cek, cipher)); encoder.end_cons(); add_layer("CMS.EnvelopedData", encoder); @@ -230,7 +241,8 @@ void CMS_Encoder::encrypt(const std::string&, /************************************************* * Encrypt the content with the chosen key/cipher * *************************************************/ -SecureVector<byte> CMS_Encoder::do_encrypt(const SymmetricKey& key, +SecureVector<byte> CMS_Encoder::do_encrypt(RandomNumberGenerator& rng, + const SymmetricKey& key, const std::string& cipher) { if(!have_block_cipher(cipher)) @@ -239,13 +251,14 @@ SecureVector<byte> CMS_Encoder::do_encrypt(const SymmetricKey& key, if(!OIDS::have_oid(cipher + "/CBC")) throw Encoding_Error("CMS: No OID assigned for " + cipher + "/CBC"); - InitializationVector iv(block_size_of(cipher)); + InitializationVector iv(rng, block_size_of(cipher)); AlgorithmIdentifier content_cipher; content_cipher.oid = OIDS::lookup(cipher + "/CBC"); content_cipher.parameters = encode_params(cipher, key, iv); - Pipe pipe(get_cipher(cipher + "/CBC/PKCS7", key, iv, ENCRYPTION)); + Pipe pipe(get_cipher(global_state(), + cipher + "/CBC/PKCS7", key, iv, ENCRYPTION)); pipe.process_msg(data); DER_Encoder encoder; @@ -261,10 +274,12 @@ SecureVector<byte> CMS_Encoder::do_encrypt(const SymmetricKey& key, /************************************************* * Sign a message * *************************************************/ -void CMS_Encoder::sign(X509_Store& store, const PKCS8_PrivateKey& key) +void CMS_Encoder::sign(X509_Store& store, const PKCS8_PrivateKey& key, + RandomNumberGenerator& rng) { std::vector<X509_Certificate> matching = - X509_Store_Search::by_keyid(store, key.key_id()); + store.get_certs(SKID_Match(key.key_id())); + if(matching.size() == 0) throw Encoding_Error("CMS::sign: Cannot find cert matching given key"); @@ -272,16 +287,12 @@ void CMS_Encoder::sign(X509_Store& store, const PKCS8_PrivateKey& key) std::vector<X509_Certificate> chain = store.get_cert_chain(cert); - std::string padding, hash; - Signature_Format format; - choose_sig_format(key.algo_name(), padding, hash, format); - const std::string sig_algo = key.algo_name() + "/" + padding; + AlgorithmIdentifier sig_algo; + std::auto_ptr<PK_Signer> signer(choose_sig_format(key, sig_algo)); SecureVector<byte> signed_attr = encode_attr(data, type, hash); - const PK_Signing_Key& sig_key = dynamic_cast<const PK_Signing_Key&>(key); - std::auto_ptr<PK_Signer> signer(get_pk_signer(sig_key, padding, format)); signer->update(signed_attr); - SecureVector<byte> signature = signer->signature(); + SecureVector<byte> signature = signer->signature(rng); signed_attr[0] = 0xA0; const u32bit SI_VERSION = cert.subject_key_id().size() ? 3 : 1; @@ -291,23 +302,28 @@ void CMS_Encoder::sign(X509_Store& store, const PKCS8_PrivateKey& key) encoder.start_cons(SEQUENCE); encoder.encode(CMS_VERSION); encoder.start_cons(SET); - encoder.encode(AlgorithmIdentifier(hash, true)); + encoder.encode(AlgorithmIdentifier(OIDS::lookup(hash), + AlgorithmIdentifier::USE_NULL_PARAM)); encoder.end_cons(); encoder.raw_bytes(make_econtent(data, type)); - encoder.start_set(ASN1_Tag(0)); + encoder.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC); for(u32bit j = 0; j != chain.size(); j++) encoder.raw_bytes(chain[j].BER_encode()); encoder.raw_bytes(cert.BER_encode()); - encoder.end_cons(ASN1_Tag(0)); + encoder.end_cons(); encoder.start_cons(SET); encoder.start_cons(SEQUENCE); encoder.encode(SI_VERSION); encode_si(encoder, cert, ((SI_VERSION == 3) ? true : false)); - encoder.encode(AlgorithmIdentifier(hash, true)); + encoder.encode( + AlgorithmIdentifier(OIDS::lookup(hash), + AlgorithmIdentifier::USE_NULL_PARAM) + ); + encoder.raw_bytes(signed_attr); - encoder.encode(AlgorithmIdentifier(sig_algo, true)); + encoder.encode(sig_algo); encoder.encode(signature, OCTET_STRING); encoder.end_cons(); encoder.end_cons(); @@ -330,7 +346,8 @@ void CMS_Encoder::digest(const std::string& user_hash) DER_Encoder encoder; encoder.start_cons(SEQUENCE); encoder.encode(VERSION); - encoder.encode(AlgorithmIdentifier(hash, true)); + encoder.encode(AlgorithmIdentifier(OIDS::lookup(hash), + AlgorithmIdentifier::USE_NULL_PARAM)); encoder.raw_bytes(make_econtent(data, type)); encoder.encode(hash_of(data, hash), OCTET_STRING); encoder.end_cons(); diff --git a/src/cms/cms_enc.h b/src/cms/cms_enc.h index 6bdde8813..c1c49b2e4 100644 --- a/src/cms/cms_enc.h +++ b/src/cms/cms_enc.h @@ -18,15 +18,22 @@ namespace Botan { class CMS_Encoder { public: - void encrypt(const X509_Certificate&, const std::string = ""); - void encrypt(const std::string&, const std::string& = ""); - void encrypt(const SymmetricKey&, const std::string& = ""); + + void encrypt(RandomNumberGenerator&, + const X509_Certificate&, const std::string = ""); + + void encrypt(RandomNumberGenerator& rng, + const std::string&, const std::string& = ""); + + void encrypt(RandomNumberGenerator& rng, + const SymmetricKey&, const std::string& = ""); void authenticate(const X509_Certificate&, const std::string& = ""); void authenticate(const std::string&, const std::string& = ""); void authenticate(const SymmetricKey&, const std::string& = ""); - void sign(X509_Store&, const PKCS8_PrivateKey&); + void sign(X509_Store&, const PKCS8_PrivateKey&, + RandomNumberGenerator& rng); void digest(const std::string& = ""); void compress(const std::string&); @@ -43,12 +50,15 @@ class CMS_Encoder private: void add_layer(const std::string&, DER_Encoder&); - void encrypt_ktri(const X509_Certificate&, PK_Encrypting_Key*, + void encrypt_ktri(RandomNumberGenerator&, + const X509_Certificate&, PK_Encrypting_Key*, const std::string&); - void encrypt_kari(const X509_Certificate&, X509_PublicKey*, + void encrypt_kari(RandomNumberGenerator&, + const X509_Certificate&, X509_PublicKey*, const std::string&); - SecureVector<byte> do_encrypt(const SymmetricKey&, const std::string&); + SecureVector<byte> do_encrypt(RandomNumberGenerator& rng, + const SymmetricKey&, const std::string&); static SecureVector<byte> make_econtent(const SecureVector<byte>&, const std::string&); |