8 #include <botan/cms_enc.h>
9 #include <botan/bigint.h>
10 #include <botan/cbc.h>
11 #include <botan/der_enc.h>
12 #include <botan/hash.h>
13 #include <botan/libstate.h>
14 #include <botan/oids.h>
15 #include <botan/pipe.h>
16 #include <botan/pubkey.h>
26 std::string choose_algo(
const std::string& user_algo,
27 const std::string& default_algo)
37 DER_Encoder& encode_si(DER_Encoder& der,
const X509_Certificate& cert,
38 bool use_skid_encoding =
false)
40 if(cert.subject_key_id().size() && use_skid_encoding)
56 SecureVector<byte> hash_of(
const SecureVector<byte>& content,
57 const std::string& hash_name)
60 std::auto_ptr<HashFunction> hash_fn(af.make_hash_function(hash_name));
61 return hash_fn->process(content);
67 SecureVector<byte> encode_attr(
const SecureVector<byte>& data,
68 const std::string& type,
69 const std::string& hash)
71 SecureVector<byte> digest = hash_of(data, hash);
75 Attribute content_type(
"PKCS9.ContentType", encoder.get_contents());
78 Attribute message_digest(
"PKCS9.MessageDigest", encoder.get_contents());
80 encoder.start_cons(
SET)
82 .encode(message_digest)
85 return encoder.get_contents();
95 const std::string user_cipher)
97 const std::string cipher = choose_algo(user_cipher,
"TripleDES");
100 const std::string algo = key->algo_name();
109 encrypt_ktri(rng, to, key.get(), cipher);
111 else if(algo ==
"DH")
116 encrypt_kari(rng, to, key.get(), cipher);
128 const std::string& cipher)
130 const std::string padding =
"EME-PKCS1-v1_5";
131 const std::string pk_algo = pub_key->
algo_name();
143 .
encode(static_cast<size_t>(0))
146 .
encode(static_cast<size_t>(0));
147 encode_si(encoder, to)
155 add_layer(
"CMS.EnvelopedData", encoder);
161 void CMS_Encoder::encrypt_kari(RandomNumberGenerator&,
162 const X509_Certificate&,
166 throw Internal_Error(
"FIXME: unimplemented");
175 encoder.start_sequence(
ASN1_Tag(1));
177 encode_si(encoder, to);
178 encoder.encode(AlgorithmIdentifier(pk_algo +
"/" + padding));
182 encoder.raw_bytes(do_encrypt(rng, cek, cipher));
185 add_layer(
"CMS.EnvelopedData", encoder);
194 const std::string& user_cipher)
198 const std::string cipher = choose_algo(user_cipher,
"TripleDES");
206 .
encode(static_cast<size_t>(2))
208 .
encode(static_cast<size_t>(4))
219 add_layer(
"CMS.EnvelopedData", encoder);
227 const std::string& user_cipher)
229 const std::string cipher = choose_algo(user_cipher,
"TripleDES");
256 throw Invalid_Argument(
"CMS: Can't encrypt with non-existent cipher " + cipher_name);
259 throw Encoding_Error(
"CMS: No OID assigned for " + cipher_name +
"/CBC");
265 content_cipher.parameters = encode_params(cipher->
name(), key, iv);
269 pipe.process_msg(data);
274 encoder.
encode(content_cipher);
287 const std::vector<X509_Certificate>& chain,
288 const std::string& hash,
289 const std::string& pad_algo)
291 std::string padding = pad_algo +
"(" + hash +
")";
301 signer.
update(signed_attr);
303 signed_attr[0] = 0xA0;
306 const size_t CMS_VERSION = (type !=
"CMS.DataContent") ? 3 : SI_VERSION;
319 for(
size_t j = 0; j != chain.size(); j++)
320 encoder.
raw_bytes(chain[j].BER_encode());
326 encode_si(encoder, cert, ((SI_VERSION == 3) ?
true :
false))
338 add_layer(
"CMS.SignedData", encoder);
346 const std::string hash = choose_algo(user_hash,
"SHA-1");
350 const size_t VERSION = (type !=
"CMS.DataContent") ? 2 : 0;
361 add_layer(
"CMS.DigestedData", encoder);
368 const std::string& mac_algo)
370 const std::string
mac = choose_algo(mac_algo,
"HMAC(SHA-1)");
378 const std::string& mac_algo)
380 const std::string
mac = choose_algo(mac_algo,
"HMAC(SHA-1)");
388 const std::string& mac_algo)
390 const std::string
mac = choose_algo(mac_algo,
"HMAC(SHA-1)");
SecureVector< byte > get_contents()
DER_Encoder & raw_bytes(const byte val[], size_t len)
SecureVector< byte > signature(RandomNumberGenerator &rng)
virtual BlockCipher * clone() const =0
const BlockCipher * prototype_block_cipher(const std::string &algo_spec, const std::string &provider="")
Key_Constraints constraints() const
virtual std::string algo_name() const =0
void digest(const std::string &="")
std::invalid_argument Invalid_Argument
DER_Encoder & start_explicit(u16bit type_tag)
void encrypt(RandomNumberGenerator &, const X509_Certificate &, const std::string="")
Algorithm_Factory & algorithm_factory() const
SecureVector< byte > bits_of() const
DER_Encoder & encode(bool b)
RandomNumberGenerator * rng
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)
MessageAuthenticationCode * mac
Library_State & global_state()
std::string lookup(const OID &oid)
std::string deref_alias(const std::string &alias) const
virtual std::string name() const =0
MemoryVector< byte > subject_key_id() const
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
MemoryVector< byte > BER_encode() const
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Public_Key * subject_public_key() const
bool have_oid(const std::string &name)
void authenticate(const X509_Certificate &, const std::string &="")
virtual size_t block_size() const =0