Botan  1.11.15
src/lib/cert/x509/ocsp_types.cpp
Go to the documentation of this file.
00001 /*
00002 * OCSP subtypes
00003 * (C) 2012 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/ocsp_types.h>
00009 #include <botan/der_enc.h>
00010 #include <botan/ber_dec.h>
00011 #include <botan/x509_ext.h>
00012 #include <botan/lookup.h>
00013 #include <botan/hash.h>
00014 #include <botan/oids.h>
00015 
00016 namespace Botan {
00017 
00018 namespace OCSP {
00019 
00020 CertID::CertID(const X509_Certificate& issuer,
00021                const X509_Certificate& subject)
00022    {
00023    /*
00024    In practice it seems some responders, including, notably,
00025    ocsp.verisign.com, will reject anything but SHA-1 here
00026    */
00027    std::unique_ptr<HashFunction> hash(get_hash("SHA-160"));
00028 
00029    m_hash_id = AlgorithmIdentifier(hash->name(), AlgorithmIdentifier::USE_NULL_PARAM);
00030    m_issuer_key_hash = unlock(hash->process(extract_key_bitstr(issuer)));
00031    m_issuer_dn_hash = unlock(hash->process(subject.raw_issuer_dn()));
00032    m_subject_serial = BigInt::decode(subject.serial_number());
00033    }
00034 
00035 std::vector<byte> CertID::extract_key_bitstr(const X509_Certificate& cert) const
00036    {
00037    const auto key_bits = cert.subject_public_key_bits();
00038 
00039    AlgorithmIdentifier public_key_algid;
00040    std::vector<byte> public_key_bitstr;
00041 
00042    BER_Decoder(key_bits)
00043       .decode(public_key_algid)
00044       .decode(public_key_bitstr, BIT_STRING);
00045 
00046    return public_key_bitstr;
00047    }
00048 
00049 bool CertID::is_id_for(const X509_Certificate& issuer,
00050                        const X509_Certificate& subject) const
00051    {
00052    try
00053       {
00054       if(BigInt::decode(subject.serial_number()) != m_subject_serial)
00055          return false;
00056 
00057       std::unique_ptr<HashFunction> hash(get_hash(OIDS::lookup(m_hash_id.oid)));
00058 
00059       if(m_issuer_dn_hash != unlock(hash->process(subject.raw_issuer_dn())))
00060          return false;
00061 
00062       if(m_issuer_key_hash != unlock(hash->process(extract_key_bitstr(issuer))))
00063          return false;
00064       }
00065    catch(...)
00066       {
00067       return false;
00068       }
00069 
00070    return true;
00071    }
00072 
00073 void CertID::encode_into(class DER_Encoder& to) const
00074    {
00075    to.start_cons(SEQUENCE)
00076       .encode(m_hash_id)
00077       .encode(m_issuer_dn_hash, OCTET_STRING)
00078       .encode(m_issuer_key_hash, OCTET_STRING)
00079       .encode(m_subject_serial)
00080       .end_cons();
00081    }
00082 
00083 void CertID::decode_from(class BER_Decoder& from)
00084    {
00085    from.start_cons(SEQUENCE)
00086       .decode(m_hash_id)
00087       .decode(m_issuer_dn_hash, OCTET_STRING)
00088       .decode(m_issuer_key_hash, OCTET_STRING)
00089       .decode(m_subject_serial)
00090       .end_cons();
00091 
00092    }
00093 
00094 void SingleResponse::encode_into(class DER_Encoder&) const
00095    {
00096    throw std::runtime_error("Not implemented (SingleResponse::encode_into)");
00097    }
00098 
00099 void SingleResponse::decode_from(class BER_Decoder& from)
00100    {
00101    BER_Object cert_status;
00102    Extensions extensions;
00103 
00104    from.start_cons(SEQUENCE)
00105       .decode(m_certid)
00106       .get_next(cert_status)
00107       .decode(m_thisupdate)
00108       .decode_optional(m_nextupdate, ASN1_Tag(0),
00109                        ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))
00110       .decode_optional(extensions,
00111                        ASN1_Tag(1),
00112                        ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))
00113       .end_cons();
00114 
00115    m_cert_status = cert_status.type_tag;
00116    }
00117 
00118 }
00119 
00120 }