aboutsummaryrefslogtreecommitdiffstats
path: root/src/cms/cms_ealg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cms/cms_ealg.cpp')
-rw-r--r--src/cms/cms_ealg.cpp85
1 files changed, 51 insertions, 34 deletions
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();