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)
 
Algorithm_Factory & algorithm_factory() const
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
void decode(BER_Decoder &source, Key_Constraints &key_usage)
Library_State & global_state()
std::string lookup(const OID &oid)