/************************************************* * EAC1_1 general CVC Header File * * (C) 2008 Falko Strenzke * * strenzke@flexsecure.de * *************************************************/ #ifndef BOTAN_EAC_CVC_GCERT_H__ #define BOTAN_EAC_CVC_GCERT_H__ #include #include #include #include #include #include #include namespace Botan { /** * This class represents TR03110 (EAC) v1.1 generalized CV Certificates */ template class BOTAN_DLL EAC1_1_gen_CVC : public EAC1_1_obj // CRTP continuation from EAC1_1_obj { friend class EAC1_1_obj; protected: ECDSA_PublicKey m_pk; // public key ASN1_Chr m_chr; bool self_signed; static void decode_info(SharedPtrConverter source, SecureVector & res_tbs_bits, ECDSA_Signature & res_sig); public: /** * Get this certificates public key. * @result this certificates public key */ std::auto_ptr subject_public_key() const; /** * Find out whether this object is self signed. * @result true if this object is self signed */ bool is_self_signed() const; /** * Get the CHR of the certificate. * @result the CHR of the certificate */ ASN1_Chr get_chr() const; /** * Put the DER encoded version of this object into a pipe. PEM * is not supported. * @param out the pipe to push the DER encoded version into * @param encoding the encoding to use. Must be DER. */ void encode(Pipe& out, X509_Encoding encoding) const; /** * Get the to-be-signed (TBS) data of this object. * @result the TBS data of this object */ SecureVector tbs_data() const; /** * Build the DER encoded certifcate body of an object * @param tbs the data to be signed * @result the correctly encoded body of the object */ static SecureVector build_cert_body(MemoryRegion const& tbs); /** * Create a signed generalized CVC object. * @param signer the signer used to sign this object * @param tbs_bits the body the generalized CVC object to be signed * @result the DER encoded signed generalized CVC object */ static MemoryVector make_signed( std::auto_ptr signer, const MemoryRegion& tbs_bits, RandomNumberGenerator& rng); virtual ~EAC1_1_gen_CVC() {} } ; template ASN1_Chr EAC1_1_gen_CVC::get_chr() const { return m_chr; } template bool EAC1_1_gen_CVC::is_self_signed() const { return self_signed; } template MemoryVector EAC1_1_gen_CVC::make_signed( std::auto_ptr signer, const MemoryRegion& tbs_bits, RandomNumberGenerator& rng) // static { SecureVector concat_sig = EAC1_1_obj::make_signature(signer.get(), tbs_bits, rng); assert(concat_sig.size() % 2 == 0); return DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) .raw_bytes(tbs_bits) .encode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) .end_cons() .get_contents(); } template std::auto_ptr EAC1_1_gen_CVC::subject_public_key() const { return std::auto_ptr(new ECDSA_PublicKey(m_pk)); } template SecureVector EAC1_1_gen_CVC::build_cert_body(MemoryRegion const& tbs) { return DER_Encoder() .start_cons(ASN1_Tag(78), APPLICATION) .raw_bytes(tbs) .end_cons().get_contents(); } template SecureVector EAC1_1_gen_CVC::tbs_data() const { return build_cert_body(EAC1_1_obj::tbs_bits); } template void EAC1_1_gen_CVC::encode(Pipe& out, X509_Encoding encoding) const { SecureVector concat_sig(EAC1_1_obj::m_sig.get_concatenation()); SecureVector der = DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) .start_cons(ASN1_Tag(78), APPLICATION) .raw_bytes(EAC1_1_obj::tbs_bits) .end_cons() .encode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) .end_cons() .get_contents(); if (encoding == PEM) throw Invalid_Argument("EAC1_1_gen_CVC::encode() cannot PEM encode an EAC object"); else out.write(der); } template void EAC1_1_gen_CVC::decode_info( SharedPtrConverter source, SecureVector & res_tbs_bits, ECDSA_Signature & res_sig) { SecureVector concat_sig; BER_Decoder(*source.get_shared().get()) .start_cons(ASN1_Tag(33)) .start_cons(ASN1_Tag(78)) .raw_bytes(res_tbs_bits) .end_cons() .decode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) .end_cons(); res_sig = decode_concatenation(concat_sig); } } #endif