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>
23 SecureVector<byte> hash_of(
const SecureVector<byte>& content,
24 const AlgorithmIdentifier& hash_algo,
25 std::string& hash_name)
31 std::auto_ptr<HashFunction> hash_fn(af.make_hash_function(hash_name));
32 return hash_fn->process(content);
38 std::vector<X509_Certificate> get_cert(BER_Decoder& signer_info,
41 BER_Object
id = signer_info.get_next_object();
43 std::vector<X509_Certificate> found;
50 BER_Decoder iands(
id.value);
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));
59 throw Decoding_Error(
"CMS: Unknown tag for cert identifier");
61 throw Internal_Error(
"Not implemented");
66 throw Internal_Error(
"CMS: Found more than one match in get_cert");
73 void read_orig_info(BER_Decoder& info, X509_Store& store)
75 BER_Object next = info.get_next_object();
77 if(next.type_tag == 0 &&
80 DataSource_Memory certs(next.value);
81 while(!certs.end_of_data())
85 X509_Certificate cert(certs);
88 next = info.get_next_object();
90 if(next.type_tag == 1 &&
93 DataSource_Memory crls(next.value);
94 while(!crls.end_of_data())
100 next = info.get_next_object();
102 info.push_back(next);
108 SecureVector<byte> decode_attributes(BER_Decoder& ber,
const OID& type,
109 bool& bad_attributes)
111 BER_Object obj = ber.get_next_object();
112 SecureVector<byte> digest;
114 bool got_digest =
false;
115 bool got_content_type =
false;
117 if(obj.type_tag == 0 &&
122 BER_Decoder attributes(obj.value);
123 while(attributes.more_items())
126 attributes.decode(attr);
127 BER_Decoder attr_value(attr.parameters);
136 got_content_type =
true;
138 attr_value.decode(inner_type);
139 if(inner_type != type)
140 bad_attributes =
true;
143 throw Decoding_Error(
"Unknown/unhandled CMS attribute found: " +
147 if(!got_digest || !got_content_type)
148 bad_attributes =
true;
159 void CMS_Decoder::decode_layer()
163 throw Invalid_State(
"CMS: Decoder is in FAILURE state");
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)
186 throw Decoding_Error(
"CMS: Unknown version for DigestedData");
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))
199 throw Internal_Error(
"FIXME: not implemented");
203 BER_Decoder sig_info = BER::get_subsequence(decoder);
205 if(version != 1 && version != 3)
206 throw Decoding_Error(
"CMS: Unknown version for SignedData");
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)
221 throw Decoding_Error(
"CMS: Unknown version for SignerInfo");
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");
262 throw Internal_Error(
"FIXME: not implemented");
266 throw Internal_Error(
"FIXME: not implemented");
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)
Library_State & global_state()
std::string lookup(const OID &oid)