Botan
1.11.15
|
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 }