diff options
Diffstat (limited to 'src/cms')
-rw-r--r-- | src/cms/cms_algo.cpp | 167 | ||||
-rw-r--r-- | src/cms/cms_comp.cpp | 107 | ||||
-rw-r--r-- | src/cms/cms_dalg.cpp | 278 | ||||
-rw-r--r-- | src/cms/cms_dec.cpp | 129 | ||||
-rw-r--r-- | src/cms/cms_dec.h | 62 | ||||
-rw-r--r-- | src/cms/cms_ealg.cpp | 394 | ||||
-rw-r--r-- | src/cms/cms_enc.cpp | 87 | ||||
-rw-r--r-- | src/cms/cms_enc.h | 91 | ||||
-rw-r--r-- | src/cms/info.txt | 22 |
9 files changed, 0 insertions, 1337 deletions
diff --git a/src/cms/cms_algo.cpp b/src/cms/cms_algo.cpp deleted file mode 100644 index 6d768306b..000000000 --- a/src/cms/cms_algo.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* -* CMS Algorithm Specific Code -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cms_enc.h> -#include <botan/der_enc.h> -#include <botan/sha160.h> -#include <botan/cbc.h> -#include <botan/filters.h> -#include <botan/libstate.h> - -#if defined(BOTAN_HAS_RC2) - #include <botan/rc2.h> -#endif - -namespace Botan { - -namespace { - -/* -* Wrap a key as specified in RFC 3217 -*/ -secure_vector<byte> do_rfc3217_wrap(RandomNumberGenerator& rng, - const std::string& cipher_name, - const SymmetricKey& kek, - const secure_vector<byte>& input) - { - class Flip_Bytes : public Filter - { - public: - std::string name() const { return "Fip_Bytes"; } - - void write(const byte data[], size_t length) - { - buf += std::make_pair(data, length); - } - void end_msg() - { - for(size_t j = 0; j != buf.size(); j++) - send(buf[buf.size()-j-1]); - buf.clear(); - } - - Flip_Bytes(const secure_vector<byte>& prefix) : buf(prefix) {} - private: - secure_vector<byte> buf; - }; - - Algorithm_Factory& af = global_state().algorithm_factory(); - - const BlockCipher* cipher = af.prototype_block_cipher(cipher_name); - - if(!cipher || cipher->block_size() != 8) - throw Encoding_Error("do_rfc3217_wrap: Bad cipher: " + cipher_name); - - Pipe icv(new Hash_Filter(new SHA_160, 8)); - icv.process_msg(input); - - InitializationVector iv(rng, 8); - InitializationVector fixed("4ADDA22C79E82105"); - - Pipe pipe(new CBC_Encryption(cipher->clone(), new Null_Padding, kek, iv), - new Flip_Bytes(iv.bits_of()), - new CBC_Encryption(cipher->clone(), new Null_Padding, kek, iv)); - - pipe.start_msg(); - pipe.write(input); - pipe.write(icv.read_all()); - pipe.end_msg(); - return pipe.read_all(); - } - -} - -/* -* Wrap a CEK with a KEK -*/ -secure_vector<byte> CMS_Encoder::wrap_key(RandomNumberGenerator& rng, - const std::string& cipher, - const SymmetricKey& cek, - const SymmetricKey& kek) - { -#if defined(BOTAN_HAS_DES) - if(cipher == "TripleDES") - { - SymmetricKey cek_parity = cek; - cek_parity.set_odd_parity(); - return do_rfc3217_wrap(rng, cipher, kek, cek_parity.bits_of()); - } -#endif - -#if defined(BOTAN_HAS_RC2) || defined(BOTAN_HAS_CAST) - if(cipher == "RC2" || cipher == "CAST-128") - { - if(kek.length() != 16) - throw Encoding_Error("CMS: 128-bit KEKs must be used with " + cipher); - - secure_vector<byte> lcekpad; - lcekpad.push_back(static_cast<byte>(cek.length())); - lcekpad += cek.bits_of(); - while(lcekpad.size() % 8) - lcekpad.push_back(rng.next_byte()); - return do_rfc3217_wrap(rng, cipher, kek, lcekpad); - } -#endif - - throw Invalid_Argument("CMS_Encoder::wrap: Unknown cipher " + cipher); - } - -/* -* Encode the parameters for an encryption algo -*/ -secure_vector<byte> CMS_Encoder::encode_params(const std::string& cipher, - const SymmetricKey& key, - const InitializationVector& iv) - { - DER_Encoder encoder; - -#if defined(BOTAN_HAS_RC2) - if(cipher == "RC2") - { - encoder.start_cons(SEQUENCE). - encode(static_cast<size_t>(RC2::EKB_code(8*key.length()))). - encode(iv.bits_of(), OCTET_STRING). - end_cons(); - return encoder.get_contents(); - } -#endif - - if(cipher == "CAST-128") - { - encoder.start_cons(SEQUENCE). - encode(iv.bits_of(), OCTET_STRING). - encode(8*key.length()). - end_cons(); - } - else - encoder.encode(iv.bits_of(), OCTET_STRING); - - return encoder.get_contents(); - } - -/* -* Generate a CEK or KEK for the cipher -*/ -SymmetricKey CMS_Encoder::setup_key(RandomNumberGenerator& rng, - const std::string& cipher) - { - size_t keysize = 0; - - if(cipher == "TripleDES") keysize = 24; - if(cipher == "RC2") keysize = 16; - if(cipher == "CAST-128") keysize = 16; - - if(keysize == 0) - throw Invalid_Argument("CMS: Cannot encrypt with cipher " + cipher); - - SymmetricKey key(rng, keysize); - if(cipher == "DES" || cipher == "TripleDES") - key.set_odd_parity(); - return key; - } - -} diff --git a/src/cms/cms_comp.cpp b/src/cms/cms_comp.cpp deleted file mode 100644 index 8ff46acea..000000000 --- a/src/cms/cms_comp.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -* CMS Compression -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cms_enc.h> -#include <botan/cms_dec.h> -#include <botan/der_enc.h> -#include <botan/ber_dec.h> -#include <botan/oids.h> -#include <botan/pipe.h> - -#if defined(BOTAN_HAS_COMPRESSOR_ZLIB) - #include <botan/zlib.h> -#endif - -namespace Botan { - -/* -* Compress a message -*/ -void CMS_Encoder::compress(const std::string& algo) - { - if(!CMS_Encoder::can_compress_with(algo)) - throw Invalid_Argument("CMS_Encoder: Cannot compress with " + algo); - - Filter* compressor = 0; - -#if defined(BOTAN_HAS_COMPRESSOR_ZLIB) - if(algo == "Zlib") compressor = new Zlib_Compression; -#endif - - if(compressor == 0) - throw Internal_Error("CMS: Couldn't get ahold of a compressor"); - - Pipe pipe(compressor); - pipe.process_msg(data); - secure_vector<byte> compressed = pipe.read_all(); - - DER_Encoder encoder; - encoder.start_cons(SEQUENCE). - encode(static_cast<size_t>(0)). - encode(AlgorithmIdentifier("Compression." + algo, - std::vector<byte>())). - raw_bytes(make_econtent(compressed, type)). - end_cons(); - - add_layer("CMS.CompressedData", encoder); - } - -/* -* See if the named compression algo is available -*/ -bool CMS_Encoder::can_compress_with(const std::string& algo) - { - if(algo == "") - throw Invalid_Algorithm_Name("Empty string to can_compress_with"); - -#if defined(BOTAN_HAS_COMPRESSOR_ZLIB) - if(algo == "Zlib") - return true; -#endif - - return false; - } - -/* -* Decompress a message -*/ -void CMS_Decoder::decompress(BER_Decoder& decoder) - { - size_t version; - AlgorithmIdentifier comp_algo; - - BER_Decoder comp_info = decoder.start_cons(SEQUENCE); - - comp_info.decode(version); - if(version != 0) - throw Decoding_Error("CMS: Unknown version for CompressedData"); - - comp_info.decode(comp_algo); - read_econtent(comp_info); - comp_info.end_cons(); - - Filter* decompressor = 0; - - info = comp_algo.oid.as_string(); - -#if defined(BOTAN_HAS_COMPRESSOR_ZLIB) - if(comp_algo.oid == OIDS::lookup("Compression.Zlib")) - { - decompressor = new Zlib_Decompression; - info = "Zlib"; - } -#endif - - if(!decompressor) - status = FAILURE; - - Pipe pipe(decompressor); - pipe.process_msg(data); - data = pipe.read_all(); - } - -} diff --git a/src/cms/cms_dalg.cpp b/src/cms/cms_dalg.cpp deleted file mode 100644 index 96bdd5be3..000000000 --- a/src/cms/cms_dalg.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* -* CMS Decoding Operations -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cms_dec.h> -#include <botan/ber_dec.h> -#include <botan/oids.h> -#include <botan/hash.h> -#include <botan/bigint.h> -#include <botan/libstate.h> -#include <memory> - -namespace Botan { - -namespace { - -/* -* Compute the hash of some content -*/ -secure_vector<byte> hash_of(const secure_vector<byte>& content, - const AlgorithmIdentifier& hash_algo, - std::string& hash_name) - { - hash_name = OIDS::lookup(hash_algo.oid); - - Algorithm_Factory& af = global_state().algorithm_factory(); - - std::unique_ptr<HashFunction> hash_fn(af.make_hash_function(hash_name)); - return hash_fn->process(content); - } - -/* -* Find a cert based on SignerIdentifier -*/ -std::vector<X509_Certificate> get_cert(BER_Decoder& signer_info, - X509_Store&) - { - BER_Object id = signer_info.get_next_object(); - - std::vector<X509_Certificate> found; - -#if 0 - if(id.type_tag == SEQUENCE && id.class_tag == CONSTRUCTED) - { - X509_DN issuer; - BigInt serial; - BER_Decoder iands(id.value); - iands.decode(issuer); - iands.decode(serial); - - found = store.get_certs( - X509_Store_Search::by_issuer_and_serial(issuer, serial)); - } - else if(id.type_tag == 0 && id.class_tag == CONSTRUCTED) - found = store.get_certs(X509_Store_Search::by_skid(id.value)); - else - throw Decoding_Error("CMS: Unknown tag for cert identifier"); -#endif - throw Internal_Error("Not implemented"); - - // verify cert if found - - if(found.size() > 1) - throw Internal_Error("CMS: Found more than one match in get_cert"); - return found; - } - -/* -* Read OriginatorInfo -*/ -void read_orig_info(BER_Decoder& info, X509_Store& store) - { - BER_Object next = info.get_next_object(); - - if(next.type_tag == 0 && - next.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - { - DataSource_Memory certs(next.value); - while(!certs.end_of_data()) - { - // FIXME: can be attribute certs too - // FIXME: DoS? - X509_Certificate cert(certs); - store.add_cert(cert); - } - next = info.get_next_object(); - } - if(next.type_tag == 1 && - next.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - { - DataSource_Memory crls(next.value); - while(!crls.end_of_data()) - { - // FIXME: DoS? - X509_CRL crl(crls); - store.add_crl(crl); - } - next = info.get_next_object(); - } - info.push_back(next); - } - -/* -* Decode any Attributes, and check type -*/ -secure_vector<byte> decode_attributes(BER_Decoder& ber, const OID& type, - bool& bad_attributes) - { - BER_Object obj = ber.get_next_object(); - secure_vector<byte> digest; - - bool got_digest = false; - bool got_content_type = false; - - if(obj.type_tag == 0 && - obj.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - ber.push_back(obj); - else - { - BER_Decoder attributes(obj.value); - while(attributes.more_items()) - { - Attribute attr; - attributes.decode(attr); - BER_Decoder attr_value(attr.parameters); - - if(attr.oid == OIDS::lookup("PKCS9.MessageDigest")) - { - got_digest = true; - attr_value.decode(digest, OCTET_STRING); - } - else if(attr.oid == OIDS::lookup("PKCS9.ContentType")) - { - got_content_type = true; - OID inner_type; - attr_value.decode(inner_type); - if(inner_type != type) - bad_attributes = true; - } - else - throw Decoding_Error("Unknown/unhandled CMS attribute found: " + - OIDS::lookup(attr.oid)); - } - - if(!got_digest || !got_content_type) - bad_attributes = true; - } - - return digest; - } - -} - -/* -* Decode this layer of CMS encoding -*/ -void CMS_Decoder::decode_layer() - { - try { - if(status == FAILURE) - throw Invalid_State("CMS: Decoder is in FAILURE state"); - - status = GOOD; - info = ""; - - type = next_type; - - if(type == OIDS::lookup("CMS.DataContent")) - return; - - BER_Decoder decoder(data); - if(type == OIDS::lookup("CMS.CompressedData")) - decompress(decoder); - else if(type == OIDS::lookup("CMS.DigestedData")) - { - size_t version; - AlgorithmIdentifier hash_algo; - secure_vector<byte> digest; - - BER_Decoder hash_info = decoder.start_cons(SEQUENCE); - - hash_info.decode(version); - if(version != 0 && version != 2) - throw Decoding_Error("CMS: Unknown version for DigestedData"); - - hash_info.decode(hash_algo); - read_econtent(hash_info); - hash_info.decode(digest, OCTET_STRING); - hash_info.end_cons(); - - if(digest != hash_of(data, hash_algo, info)) - status = BAD; - } - else if(type == OIDS::lookup("CMS.SignedData")) - { -#if 1 - throw Internal_Error("FIXME: not implemented"); -#else - size_t version; - - BER_Decoder sig_info = BER::get_subsequence(decoder); - BER::decode(sig_info, version); - if(version != 1 && version != 3) - throw Decoding_Error("CMS: Unknown version for SignedData"); - BER::get_subset(sig_info); // hash algos (do something with these?) - read_econtent(sig_info); - read_orig_info(sig_info, store); - - BER_Decoder signer_infos = BER::get_subset(sig_info); - while(signer_infos.more_items()) - { - AlgorithmIdentifier sig_algo, hash_algo; - secure_vector<byte> signature, digest; - size_t version; - - BER_Decoder signer_info = BER::get_subsequence(signer_infos); - BER::decode(signer_info, version); - if(version != 1 && version != 3) - throw Decoding_Error("CMS: Unknown version for SignerInfo"); - - std::vector<X509_Certificate> certs = get_cert(signer_info, store); - if(certs.size() == 0) { status = NO_KEY; continue; } - - BER::decode(signer_info, hash_algo); - bool bad_attr = false; - digest = decode_attributes(signer_info, next_type, bad_attr); - if(bad_attr) { status = BAD; continue; } - BER::decode(signer_info, sig_algo); - BER::decode(signer_info, signature, OCTET_STRING); - // unsigned attributes - signer_info.verify_end(); - - if(digest.has_items()) - { - std::string hash; - if(digest != hash_of(data, hash_algo, hash)) - { - status = BAD; - continue; - } - status = check_sig(signed_attr, sig_algo, signature, certs[0]); - } - else - status = check_sig(data, sig_algo, signature, certs[0]); - - if(status == BAD) - continue; - - // fix this (gets only last signer, for one thing) - // maybe some way for the user to get all certs that signed the - // message? that would be useful - info = "CN=" + cert.subject_info("CommonName") + - ",O=" + cert.subject_info("Organization") + - ",OU=" + cert.subject_info("Organizational Unit"); - } -#endif - } - else if(type == OIDS::lookup("CMS.EnvelopedData")) - { - throw Internal_Error("FIXME: not implemented"); - } - else if(type == OIDS::lookup("CMS.AuthenticatedData")) - { - throw Internal_Error("FIXME: not implemented"); - } - else - throw Decoding_Error("CMS: Unknown content ID " + type.as_string()); - } - catch(std::exception) - { - status = FAILURE; - } - } - -} diff --git a/src/cms/cms_dec.cpp b/src/cms/cms_dec.cpp deleted file mode 100644 index 744ff4d63..000000000 --- a/src/cms/cms_dec.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -* CMS Decoding -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cms_dec.h> -#include <botan/ber_dec.h> -#include <botan/asn1_obj.h> -#include <botan/oids.h> -#include <botan/pem.h> - -namespace Botan { - -/* -* CMS_Decoder Constructor -*/ -CMS_Decoder::CMS_Decoder(DataSource& in, const X509_Store& x509store, - Private_Key* key) : - store(x509store) - { - status = GOOD; - - add_key(key); - - if(ASN1::maybe_BER(in) && !PEM_Code::matches(in)) - initial_read(in); - else - { - DataSource_Memory ber(PEM_Code::decode_check_label(in, "PKCS7")); - initial_read(ber); - } - } - -/* -* Read the outermost ContentInfo -*/ -void CMS_Decoder::initial_read(DataSource&) - { - // FIXME... - - /* - BER_Decoder decoder(in); - BER_Decoder content_info = decoder.start_cons(SEQUENCE); - - content_info.decode(next_type); - - - BER_Decoder content_type = BER::get_subsequence(content_info, ASN1_Tag(0)); - data = content_type.get_remaining(); - */ - - decode_layer(); - } - -/* -* Add another private key to use -*/ -void CMS_Decoder::add_key(Private_Key* key) - { - if(!key) - return; - -#if 0 - for(u32bit j = 0; j != keys.size(); j++) - if(keys[j]->key_id() == key->key_id()) - return; -#endif - - keys.push_back(key); - } - -/* -* Return the status information -*/ -CMS_Decoder::Status CMS_Decoder::layer_status() const - { - return status; - } - -/* -* Return the final data content -*/ -std::string CMS_Decoder::get_data() const - { - if(layer_type() != DATA) - throw Invalid_State("CMS: Cannot retrieve data from non-DATA layer"); - - return std::string(reinterpret_cast<const char*>(&data[0]), - data.size()); - } - -/* -* Return the content type of this layer -*/ -CMS_Decoder::Content_Type CMS_Decoder::layer_type() const - { - if(type == OIDS::lookup("CMS.DataContent")) return DATA; - if(type == OIDS::lookup("CMS.EnvelopedData")) return ENVELOPED; - if(type == OIDS::lookup("CMS.CompressedData")) return COMPRESSED; - if(type == OIDS::lookup("CMS.SignedData")) return SIGNED; - if(type == OIDS::lookup("CMS.AuthenticatedData")) return AUTHENTICATED; - if(type == OIDS::lookup("CMS.DigestedData")) return DIGESTED; - return UNKNOWN; - } - -/* -* Return some information about this layer -*/ -std::string CMS_Decoder::layer_info() const - { - return info; - } - -/* -* Return some information about this layer -*/ -void CMS_Decoder::read_econtent(BER_Decoder& decoder) - { - BER_Decoder econtent_info = decoder.start_cons(SEQUENCE); - econtent_info.decode(next_type); - - // FIXME - //BER_Decoder econtent = BER::get_subsequence(econtent_info, ASN1_Tag(0)); - //econtent.decode(data, OCTET_STRING); - } - -} diff --git a/src/cms/cms_dec.h b/src/cms/cms_dec.h deleted file mode 100644 index 96a5d7c8e..000000000 --- a/src/cms/cms_dec.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* CMS Decoding -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_CMS_DECODER_H__ -#define BOTAN_CMS_DECODER_H__ - -#include <botan/x509cert.h> -#include <botan/x509_crl.h> -#include <botan/pkcs8.h> -#include <botan/ber_dec.h> - -namespace Botan { - -/** -* CMS Decoding Operation -*/ -class BOTAN_DLL CMS_Decoder - { - public: - enum Status { GOOD, BAD, NO_KEY, FAILURE }; - - enum Content_Type { DATA, UNKNOWN, COMPRESSED, ENVELOPED, SIGNED, - AUTHENTICATED, DIGESTED }; - - Status layer_status() const; - Content_Type layer_type() const; - std::string layer_info() const; - std::string layer_algo() const; - std::string get_data() const; - std::vector<X509_Certificate> get_certs() const; - std::vector<X509_CRL> get_crls() const; - - void next_layer() { decode_layer(); } - - void add_key(Private_Key*); - - CMS_Decoder(DataSource&, const X509_Store&, - Private_Key* = 0); - private: - std::string get_passphrase(const std::string&); - void read_econtent(BER_Decoder&); - void initial_read(DataSource&); - void decode_layer(); - void decompress(BER_Decoder&); - - X509_Store store; - std::vector<std::string> passphrases; - std::vector<Private_Key*> keys; - - OID type, next_type; - secure_vector<byte> data; - Status status; - std::string info; - }; - -} - -#endif diff --git a/src/cms/cms_ealg.cpp b/src/cms/cms_ealg.cpp deleted file mode 100644 index 4c3fd98fc..000000000 --- a/src/cms/cms_ealg.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* -* CMS Encoding Operations -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cms_enc.h> -#include <botan/bigint.h> -#include <botan/cbc.h> -#include <botan/der_enc.h> -#include <botan/hash.h> -#include <botan/libstate.h> -#include <botan/oids.h> -#include <botan/pipe.h> -#include <botan/pubkey.h> -#include <memory> - -namespace Botan { - -namespace { - -/* -* Choose an algorithm -*/ -std::string choose_algo(const std::string& user_algo, - const std::string& default_algo) - { - if(user_algo == "") - return global_state().deref_alias(default_algo); - return global_state().deref_alias(user_algo); - } - -/* -* Encode a SignerIdentifier/RecipientIdentifier -*/ -DER_Encoder& encode_si(DER_Encoder& der, const X509_Certificate& cert, - bool use_skid_encoding = false) - { - if(cert.subject_key_id().size() && use_skid_encoding) - der.encode(cert.subject_key_id(), OCTET_STRING, ASN1_Tag(0)); - else - { - der.start_cons(SEQUENCE). - encode(cert.issuer_dn()). - encode(BigInt::decode(cert.serial_number())). - end_cons(); - } - - return der; - } - -/* -* Compute the hash of some content -*/ -secure_vector<byte> hash_of(const secure_vector<byte>& content, - const std::string& hash_name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - std::unique_ptr<HashFunction> hash_fn(af.make_hash_function(hash_name)); - return hash_fn->process(content); - } - -/* -* Encode Attributes containing info on content -*/ -secure_vector<byte> encode_attr(const secure_vector<byte>& data, - const std::string& type, - const std::string& hash) - { - secure_vector<byte> digest = hash_of(data, hash); - - DER_Encoder encoder; - encoder.encode(OIDS::lookup(type)); - Attribute content_type("PKCS9.ContentType", encoder.get_contents()); - - encoder.encode(digest, OCTET_STRING); - Attribute message_digest("PKCS9.MessageDigest", encoder.get_contents()); - - encoder.start_cons(SET) - .encode(content_type) - .encode(message_digest) - .end_cons(); - - return encoder.get_contents(); - } - -} - -/* -* Encrypt a message -*/ -void CMS_Encoder::encrypt(RandomNumberGenerator& rng, - const X509_Certificate& to, - const std::string user_cipher) - { - const std::string cipher = choose_algo(user_cipher, "TripleDES"); - - std::unique_ptr<Public_Key> key(to.subject_public_key()); - const std::string algo = key->algo_name(); - - Key_Constraints constraints = to.constraints(); - - if(algo == "RSA") - { - if(constraints != NO_CONSTRAINTS && !(constraints & KEY_ENCIPHERMENT)) - throw Invalid_Argument("CMS: Constraints not set for encryption"); - - encrypt_ktri(rng, to, key.get(), cipher); - } - else if(algo == "DH") - { - if(constraints != NO_CONSTRAINTS && !(constraints & KEY_AGREEMENT)) - throw Invalid_Argument("CMS: Constraints not set for key agreement"); - - encrypt_kari(rng, to, key.get(), cipher); - } - else - throw Invalid_Argument("Unknown CMS PK encryption algorithm " + algo); - } - -/* -* Encrypt a message with a key transport algo -*/ -void CMS_Encoder::encrypt_ktri(RandomNumberGenerator& rng, - const X509_Certificate& to, - Public_Key* pub_key, - const std::string& cipher) - { - const std::string padding = "EME-PKCS1-v1_5"; - const std::string pk_algo = pub_key->algo_name(); - - PK_Encryptor_EME encryptor(*pub_key, padding); - - 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) - .encode(static_cast<size_t>(0)) - .start_cons(SET) - .start_cons(SEQUENCE) - .encode(static_cast<size_t>(0)); - encode_si(encoder, to) - .encode(alg_id) - .encode(encryptor.encrypt(cek.bits_of(), rng), OCTET_STRING) - .end_cons() - .end_cons() - .raw_bytes(do_encrypt(rng, cek, cipher)) - .end_cons(); - - add_layer("CMS.EnvelopedData", encoder); - } - -/* -* Encrypt a message with a key agreement algo -*/ -void CMS_Encoder::encrypt_kari(RandomNumberGenerator&, - const X509_Certificate&, - Public_Key*, - const std::string&) - { - throw Internal_Error("FIXME: unimplemented"); - -#if 0 - SymmetricKey cek = setup_key(rng, cipher); - - DER_Encoder encoder; - encoder.start_cons(SEQUENCE); - encoder.encode(2); - encoder.start_cons(SET); - encoder.start_sequence(ASN1_Tag(1)); - encoder.encode(3); - encode_si(encoder, to); - encoder.encode(AlgorithmIdentifier(pk_algo + "/" + padding)); - encoder.encode(encrypted_cek, OCTET_STRING); - encoder.end_cons(); - encoder.end_cons(); - encoder.raw_bytes(do_encrypt(rng, cek, cipher)); - encoder.end_cons(); - - add_layer("CMS.EnvelopedData", encoder); -#endif - } - -/* -* Encrypt a message with a shared key -*/ -void CMS_Encoder::encrypt(RandomNumberGenerator& rng, - const SymmetricKey& kek, - const std::string& user_cipher) - { - throw Internal_Error("FIXME: untested"); - - const std::string cipher = choose_algo(user_cipher, "TripleDES"); - SymmetricKey cek = setup_key(rng, cipher); - - secure_vector<byte> kek_id; // FIXME: ? - - DER_Encoder encoder; - - encoder.start_cons(SEQUENCE) - .encode(static_cast<size_t>(2)) - .start_explicit(ASN1_Tag(2)) - .encode(static_cast<size_t>(4)) - .start_cons(SEQUENCE) - .encode(kek_id, OCTET_STRING) - .end_cons() - .encode(AlgorithmIdentifier(OIDS::lookup("KeyWrap." + cipher), - AlgorithmIdentifier::USE_NULL_PARAM)) - .encode(wrap_key(rng, cipher, cek, kek), OCTET_STRING) - .end_cons() - .raw_bytes(do_encrypt(rng, cek, cipher)) - .end_cons(); - - add_layer("CMS.EnvelopedData", encoder); - } - -/* -* Encrypt a message with a passphrase -*/ -void CMS_Encoder::encrypt(RandomNumberGenerator&, - const std::string&, - const std::string& user_cipher) - { - const std::string cipher = choose_algo(user_cipher, "TripleDES"); - throw Internal_Error("FIXME: unimplemented"); - /* - SymmetricKey cek = setup_key(key); - - DER_Encoder encoder; - encoder.start_cons(SEQUENCE); - encoder.encode(0); - encoder.raw_bytes(do_encrypt(rng, cek, cipher)); - encoder.end_cons(); - - add_layer("CMS.EnvelopedData", encoder); - */ - } - -/* -* Encrypt the content with the chosen key/cipher -*/ -secure_vector<byte> CMS_Encoder::do_encrypt(RandomNumberGenerator& rng, - const SymmetricKey& key, - const std::string& cipher_name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - const BlockCipher* cipher = af.prototype_block_cipher(cipher_name); - - if(!cipher) - throw Invalid_Argument("CMS: Can't encrypt with non-existent cipher " + cipher_name); - - if(!OIDS::have_oid(cipher->name() + "/CBC")) - throw Encoding_Error("CMS: No OID assigned for " + cipher_name + "/CBC"); - - InitializationVector iv(rng, cipher->block_size()); - - AlgorithmIdentifier content_cipher; - content_cipher.oid = OIDS::lookup(cipher->name() + "/CBC"); - content_cipher.parameters = encode_params(cipher->name(), key, iv); - - Pipe pipe(new CBC_Encryption(cipher->clone(), new PKCS7_Padding, key, iv)); - - pipe.process_msg(data); - - DER_Encoder encoder; - encoder.start_cons(SEQUENCE); - encoder.encode(OIDS::lookup(type)); - encoder.encode(content_cipher); - encoder.encode(pipe.read_all(), OCTET_STRING, ASN1_Tag(0)); - encoder.end_cons(); - - return encoder.get_contents(); - } - -/* -* Sign a message -*/ -void CMS_Encoder::sign(const X509_Certificate& cert, - const Private_Key& key, - RandomNumberGenerator& rng, - const std::vector<X509_Certificate>& chain, - const std::string& hash, - const std::string& pad_algo) - { - std::string padding = pad_algo + "(" + hash + ")"; - - Signature_Format format = IEEE_1363; - - PK_Signer signer(key, padding, format); - - AlgorithmIdentifier sig_algo(OIDS::lookup(key.algo_name() + "/" + padding), - AlgorithmIdentifier::USE_NULL_PARAM); - - secure_vector<byte> signed_attr = encode_attr(data, type, hash); - signer.update(signed_attr); - secure_vector<byte> signature = signer.signature(rng); - signed_attr[0] = 0xA0; - - const size_t SI_VERSION = cert.subject_key_id().size() ? 3 : 1; - const size_t CMS_VERSION = (type != "CMS.DataContent") ? 3 : SI_VERSION; - - DER_Encoder encoder; - - encoder.start_cons(SEQUENCE) - .encode(CMS_VERSION) - .start_cons(SET) - .encode(AlgorithmIdentifier(OIDS::lookup(hash), - AlgorithmIdentifier::USE_NULL_PARAM)) - .end_cons() - .raw_bytes(make_econtent(data, type)); - - encoder.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC); - for(size_t j = 0; j != chain.size(); j++) - encoder.raw_bytes(chain[j].BER_encode()); - encoder.raw_bytes(cert.BER_encode()).end_cons(); - - encoder.start_cons(SET) - .start_cons(SEQUENCE) - .encode(SI_VERSION); - encode_si(encoder, cert, ((SI_VERSION == 3) ? true : false)) - .encode( - AlgorithmIdentifier(OIDS::lookup(hash), - AlgorithmIdentifier::USE_NULL_PARAM) - ) - .raw_bytes(signed_attr) - .encode(sig_algo) - .encode(signature, OCTET_STRING) - .end_cons() - .end_cons() - .end_cons(); - - add_layer("CMS.SignedData", encoder); - } - -/* -* Digest a message -*/ -void CMS_Encoder::digest(const std::string& user_hash) - { - const std::string hash = choose_algo(user_hash, "SHA-1"); - if(!OIDS::have_oid(hash)) - throw Encoding_Error("CMS: No OID assigned for " + hash); - - const size_t VERSION = (type != "CMS.DataContent") ? 2 : 0; - - DER_Encoder encoder; - encoder.start_cons(SEQUENCE) - .encode(VERSION) - .encode(AlgorithmIdentifier(OIDS::lookup(hash), - AlgorithmIdentifier::USE_NULL_PARAM)) - .raw_bytes(make_econtent(data, type)) - .encode(hash_of(data, hash), OCTET_STRING) - .end_cons(); - - add_layer("CMS.DigestedData", encoder); - } - -/* -* MAC a message with an encrypted key -*/ -void CMS_Encoder::authenticate(const X509_Certificate&, - const std::string& mac_algo) - { - const std::string mac = choose_algo(mac_algo, "HMAC(SHA-1)"); - throw Internal_Error("FIXME: unimplemented"); - } - -/* -* MAC a message with a shared key -*/ -void CMS_Encoder::authenticate(const SymmetricKey&, - const std::string& mac_algo) - { - const std::string mac = choose_algo(mac_algo, "HMAC(SHA-1)"); - throw Internal_Error("FIXME: unimplemented"); - } - -/* -* MAC a message with a passphrase -*/ -void CMS_Encoder::authenticate(const std::string&, - const std::string& mac_algo) - { - const std::string mac = choose_algo(mac_algo, "HMAC(SHA-1)"); - throw Internal_Error("FIXME: unimplemented"); - } - -} diff --git a/src/cms/cms_enc.cpp b/src/cms/cms_enc.cpp deleted file mode 100644 index 58d7cabb6..000000000 --- a/src/cms/cms_enc.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* -* CMS Encoding Base -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cms_enc.h> -#include <botan/der_enc.h> -#include <botan/oids.h> -#include <botan/pem.h> - -namespace Botan { - -/* -* Setup the intitial layer of CMS data -*/ -void CMS_Encoder::set_data(const byte buf[], size_t length) - { - if(!data.empty()) - throw Invalid_State("Cannot call CMS_Encoder::set_data here"); - - data.resize(length); - copy_mem(&data[0], buf, length); - type = "CMS.DataContent"; - } - -/* -* Setup the intitial layer of CMS data -*/ -void CMS_Encoder::set_data(const std::string& str) - { - set_data(reinterpret_cast<const byte*>(str.c_str()), str.length()); - } - -/* -* Finalize and return the CMS encoded data -*/ -secure_vector<byte> CMS_Encoder::get_contents() - { - DER_Encoder encoder; - - encoder.start_cons(SEQUENCE). - encode(OIDS::lookup(type)). - start_explicit(0). - raw_bytes(data). - end_explicit(). - end_cons(); - - data.clear(); - - return encoder.get_contents(); - } - -/* -* Add a new layer of encapsulation -*/ -void CMS_Encoder::add_layer(const std::string& oid, DER_Encoder& new_layer) - { - data = new_layer.get_contents(); - type = oid; - } - -/* -* Return the PEM-encoded data -*/ -std::string CMS_Encoder::PEM_contents() - { - return PEM_Code::encode(get_contents(), "PKCS7"); - } - -/* -* Make an EncapsulatedContentInfo -*/ -secure_vector<byte> CMS_Encoder::make_econtent(const secure_vector<byte>& data, - const std::string& type) - { - return DER_Encoder().start_cons(SEQUENCE). - encode(OIDS::lookup(type)). - start_explicit(0). - encode(data, OCTET_STRING). - end_explicit(). - end_cons(). - get_contents(); - } - -} diff --git a/src/cms/cms_enc.h b/src/cms/cms_enc.h deleted file mode 100644 index fc501c691..000000000 --- a/src/cms/cms_enc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -* CMS Encoding -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_CMS_ENCODER_H__ -#define BOTAN_CMS_ENCODER_H__ - -#include <botan/x509cert.h> -#include <botan/pkcs8.h> -#include <botan/symkey.h> - -namespace Botan { - -/** -* CMS Encoding Operation -*/ -class BOTAN_DLL CMS_Encoder - { - public: - - 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(const X509_Certificate& cert, - const Private_Key& key, - RandomNumberGenerator& rng, - const std::vector<X509_Certificate>& cert_chain, - const std::string& hash, - const std::string& padding); - - void digest(const std::string& = ""); - - void compress(const std::string&); - static bool can_compress_with(const std::string&); - - secure_vector<byte> get_contents(); - std::string PEM_contents(); - - void set_data(const std::string&); - void set_data(const byte[], size_t); - - CMS_Encoder(const std::string& str) { set_data(str); } - CMS_Encoder(const byte buf[], size_t length) { set_data(buf, length); } - private: - void add_layer(const std::string&, DER_Encoder&); - - void encrypt_ktri(RandomNumberGenerator&, - const X509_Certificate&, Public_Key*, - const std::string&); - void encrypt_kari(RandomNumberGenerator&, - const X509_Certificate&, Public_Key*, - const std::string&); - - secure_vector<byte> do_encrypt(RandomNumberGenerator& rng, - const SymmetricKey&, const std::string&); - - static secure_vector<byte> make_econtent(const secure_vector<byte>&, - const std::string&); - - static SymmetricKey setup_key(RandomNumberGenerator& rng, - const std::string&); - - static secure_vector<byte> wrap_key(RandomNumberGenerator& rng, - const std::string&, - const SymmetricKey&, - const SymmetricKey&); - - static secure_vector<byte> encode_params(const std::string&, - const SymmetricKey&, - const InitializationVector&); - - secure_vector<byte> data; - std::string type; - }; - -} - -#endif diff --git a/src/cms/info.txt b/src/cms/info.txt deleted file mode 100644 index 4d50d7112..000000000 --- a/src/cms/info.txt +++ /dev/null @@ -1,22 +0,0 @@ -define CMS - -load_on never - -<warning> -Currently broken, needs much love and updating before useful -</warning> - -<requires> -asn1 -bigint -cbc -filters -hash -libstate -oid_lookup -pem -pubkey -sha1 -algo_base -x509 -</requires> |