8#include <botan/cms_dec.h>
9#include <botan/ber_dec.h>
10#include <botan/oids.h>
11#include <botan/hash.h>
12#include <botan/bigint.h>
13#include <botan/libstate.h>
25 std::string& hash_name)
31 std::auto_ptr<HashFunction> hash_fn(af.make_hash_function(hash_name));
32 return hash_fn->process(content);
38std::vector<X509_Certificate> get_cert(
BER_Decoder& signer_info,
43 std::vector<X509_Certificate> found;
54 found = store.get_certs(IandS_Match(issuer,
BigInt::encode(serial)));
56 else if(
id.type_tag == 0 &&
id.class_tag ==
CONSTRUCTED)
57 found = store.get_certs(SKID_Match(
id.value));
66 throw Internal_Error(
"CMS: Found more than one match in get_cert");
77 if(next.type_tag == 0 &&
81 while(!certs.end_of_data())
88 next = info.get_next_object();
90 if(next.type_tag == 1 &&
94 while(!crls.end_of_data())
100 next = info.get_next_object();
102 info.push_back(next);
109 bool& bad_attributes)
114 bool got_digest =
false;
115 bool got_content_type =
false;
117 if(obj.type_tag == 0 &&
123 while(attributes.more_items())
126 attributes.decode(attr);
136 got_content_type =
true;
138 attr_value.decode(inner_type);
139 if(inner_type != type)
140 bad_attributes =
true;
147 if(!got_digest || !got_content_type)
148 bad_attributes =
true;
159void CMS_Decoder::decode_layer()
173 BER_Decoder decoder(data);
179 AlgorithmIdentifier hash_algo;
180 SecureVector<byte> digest;
182 BER_Decoder hash_info = decoder.start_cons(
SEQUENCE);
184 hash_info.decode(version);
185 if(version != 0 && version != 2)
188 hash_info.decode(hash_algo);
189 read_econtent(hash_info);
191 hash_info.end_cons();
193 if(digest != hash_of(data, hash_algo, info))
203 BER_Decoder sig_info = BER::get_subsequence(decoder);
205 if(version != 1 && version != 3)
207 BER::get_subset(sig_info);
208 read_econtent(sig_info);
209 read_orig_info(sig_info, store);
211 BER_Decoder signer_infos = BER::get_subset(sig_info);
212 while(signer_infos.more_items())
214 AlgorithmIdentifier sig_algo, hash_algo;
215 SecureVector<byte> signature, digest;
218 BER_Decoder signer_info = BER::get_subsequence(signer_infos);
220 if(version != 1 && version != 3)
223 std::vector<X509_Certificate> certs = get_cert(signer_info, store);
224 if(certs.size() == 0) { status =
NO_KEY;
continue; }
227 bool bad_attr =
false;
228 digest = decode_attributes(signer_info, next_type, bad_attr);
229 if(bad_attr) { status =
BAD;
continue; }
233 signer_info.verify_end();
235 if(digest.has_items())
238 if(digest != hash_of(data, hash_algo, hash))
243 status = check_sig(signed_attr, sig_algo, signature, certs[0]);
246 status = check_sig(data, sig_algo, signature, certs[0]);
254 info =
"CN=" + cert.subject_info(
"CommonName") +
255 ",O=" + cert.subject_info(
"Organization") +
256 ",OU=" + cert.subject_info(
"Organizational Unit");
269 throw Decoding_Error(
"CMS: Unknown content ID " + type.as_string());
271 catch(std::exception)
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Algorithm_Factory & algorithm_factory() const
void decode(BER_Decoder &source, Key_Constraints &key_usage)
std::string lookup(const OID &oid)
Library_State & global_state()
Decoding_Error(const std::string &name)
Internal_Error(const std::string &err)
Invalid_State(const std::string &err)