aboutsummaryrefslogtreecommitdiffstats
path: root/misc/cms/cms_dalg.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 20:58:26 +0000
committerlloyd <[email protected]>2008-09-28 20:58:26 +0000
commit3948d38e2bef3f42169f96a17cc5daa6e03fb575 (patch)
tree1fe40baedc9e49a5d734b100790f79ac70839513 /misc/cms/cms_dalg.cpp
parentf5ebea8d593d2f6d5b536ddb978f44d80d4e873f (diff)
Move CMS code into main src tree, though it currently doesn't compile (needs further updating)
Diffstat (limited to 'misc/cms/cms_dalg.cpp')
-rw-r--r--misc/cms/cms_dalg.cpp270
1 files changed, 0 insertions, 270 deletions
diff --git a/misc/cms/cms_dalg.cpp b/misc/cms/cms_dalg.cpp
deleted file mode 100644
index 92e620fc4..000000000
--- a/misc/cms/cms_dalg.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*************************************************
-* CMS Decoding Operations Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
-
-#include <botan/cms_dec.h>
-#include <botan/ber_dec.h>
-#include <botan/oids.h>
-#include <botan/lookup.h>
-#include <botan/look_pk.h>
-#include <botan/bigint.h>
-#include <memory>
-
-namespace Botan {
-
-namespace {
-
-/*************************************************
-* Compute the hash of some content *
-*************************************************/
-SecureVector<byte> hash_of(const SecureVector<byte>& content,
- const AlgorithmIdentifier& hash_algo,
- std::string& hash_name)
- {
- hash_name = OIDS::lookup(hash_algo.oid);
- std::auto_ptr<HashFunction> hash_fn(get_hash(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& store)
- {
- BER_Object id = signer_info.get_next_object();
-
- std::vector<X509_Certificate> found;
-
- 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 = X509_Store_Search::by_iands(store, issuer,
- BigInt::encode(serial));
- }
- else if(id.type_tag == 0 && id.class_tag == CONSTRUCTED)
- found = X509_Store_Search::by_SKID(store, id.value);
- else
- throw Decoding_Error("CMS: Unknown tag for cert identifier");
-
- // 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 *
-*************************************************/
-SecureVector<byte> decode_attributes(BER_Decoder& ber, const OID& type,
- bool& bad_attributes)
- {
- BER_Object obj = ber.get_next_object();
- SecureVector<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"))
- {
- u32bit version;
- AlgorithmIdentifier hash_algo;
- SecureVector<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 Exception("FIXME: not implemented");
-#else
- u32bit 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;
- SecureVector<byte> signature, digest;
- u32bit 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 Exception("FIXME: not implemented");
- }
- else if(type == OIDS::lookup("CMS.AuthenticatedData"))
- {
- throw Exception("FIXME: not implemented");
- }
- else
- throw Decoding_Error("CMS: Unknown content ID " + type.as_string());
- }
- catch(std::exception)
- {
- status = FAILURE;
- }
- }
-
-}