diff options
Diffstat (limited to 'src/cert/cvc')
-rw-r--r-- | src/cert/cvc/cvc_ado.cpp | 10 | ||||
-rw-r--r-- | src/cert/cvc/cvc_ado.h | 5 | ||||
-rw-r--r-- | src/cert/cvc/cvc_ca.cpp | 44 | ||||
-rw-r--r-- | src/cert/cvc/cvc_ca.h | 51 | ||||
-rw-r--r-- | src/cert/cvc/cvc_cert.cpp | 65 | ||||
-rw-r--r-- | src/cert/cvc/cvc_cert.h | 37 | ||||
-rw-r--r-- | src/cert/cvc/cvc_gen_cert.h | 27 | ||||
-rw-r--r-- | src/cert/cvc/cvc_key.h | 53 | ||||
-rw-r--r-- | src/cert/cvc/cvc_req.cpp | 18 | ||||
-rw-r--r-- | src/cert/cvc/cvc_req.h | 5 | ||||
-rw-r--r-- | src/cert/cvc/cvc_self.cpp | 194 | ||||
-rw-r--r-- | src/cert/cvc/eac_asn_obj.h | 5 | ||||
-rw-r--r-- | src/cert/cvc/eac_obj.h | 112 | ||||
-rw-r--r-- | src/cert/cvc/ecdsa_sig.cpp | 50 | ||||
-rw-r--r-- | src/cert/cvc/ecdsa_sig.h | 62 | ||||
-rw-r--r-- | src/cert/cvc/info.txt | 4 | ||||
-rw-r--r-- | src/cert/cvc/signed_obj.cpp | 41 | ||||
-rw-r--r-- | src/cert/cvc/signed_obj.h | 3 |
18 files changed, 292 insertions, 494 deletions
diff --git a/src/cert/cvc/cvc_ado.cpp b/src/cert/cvc/cvc_ado.cpp index fd5b80f13..8c38e90ae 100644 --- a/src/cert/cvc/cvc_ado.cpp +++ b/src/cert/cvc/cvc_ado.cpp @@ -45,13 +45,11 @@ void EAC1_1_ADO::force_decode() sig_algo = m_req.sig_algo; } -MemoryVector<byte> EAC1_1_ADO::make_signed( - PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, - RandomNumberGenerator& rng) +MemoryVector<byte> EAC1_1_ADO::make_signed(PK_Signer& signer, + const MemoryRegion<byte>& tbs_bits, + RandomNumberGenerator& rng) { - SecureVector<byte> concat_sig = - EAC1_1_obj<EAC1_1_ADO>::make_signature(signer, tbs_bits, rng); + SecureVector<byte> concat_sig = signer.sign_message(tbs_bits, rng); return DER_Encoder() .start_cons(ASN1_Tag(7), APPLICATION) diff --git a/src/cert/cvc/cvc_ado.h b/src/cert/cvc/cvc_ado.h index 100888d29..230ee8b8d 100644 --- a/src/cert/cvc/cvc_ado.h +++ b/src/cert/cvc/cvc_ado.h @@ -8,11 +8,8 @@ #ifndef BOTAN_EAC_CVC_ADO_H__ #define BOTAN_EAC_CVC_ADO_H__ -#include <botan/x509_key.h> -#include <botan/pubkey_enums.h> -#include <botan/pubkey.h> -#include <botan/ecdsa.h> #include <botan/eac_obj.h> +#include <botan/eac_asn_obj.h> #include <botan/cvc_req.h> #include <string> diff --git a/src/cert/cvc/cvc_ca.cpp b/src/cert/cvc/cvc_ca.cpp deleted file mode 100644 index af40fcd05..000000000 --- a/src/cert/cvc/cvc_ca.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include <botan/cvc_ca.h> -#include <botan/cvc_cert.h> -#include <botan/der_enc.h> -#include <botan/oids.h> -namespace Botan { - -EAC1_1_CVC EAC1_1_CVC_CA::make_cert(PK_Signer& signer, - MemoryRegion<byte> const& public_key, - ASN1_Car const& car, - ASN1_Chr const& chr, - byte holder_auth_templ, - ASN1_Ced ced, - ASN1_Cex cex, - RandomNumberGenerator& rng) - { - OID chat_oid(OIDS::lookup("CertificateHolderAuthorizationTemplate")); - MemoryVector<byte> enc_chat_val; - enc_chat_val.append(holder_auth_templ); - - MemoryVector<byte> enc_cpi; - enc_cpi.append(0x00); - MemoryVector<byte> tbs = DER_Encoder() - .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) // cpi - .encode(car) - .raw_bytes(public_key) - .encode(chr) - .start_cons(ASN1_Tag(76), APPLICATION) - .encode(chat_oid) - .encode(enc_chat_val, OCTET_STRING, ASN1_Tag(19), APPLICATION) - .end_cons() - .encode(ced) - .encode(cex) - .get_contents(); - - MemoryVector<byte> signed_cert = - EAC1_1_CVC::make_signed(signer, - EAC1_1_CVC::build_cert_body(tbs), - rng); - - DataSource_Memory source(signed_cert); - return EAC1_1_CVC(source); - } - -} diff --git a/src/cert/cvc/cvc_ca.h b/src/cert/cvc/cvc_ca.h deleted file mode 100644 index 87699808f..000000000 --- a/src/cert/cvc/cvc_ca.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* EAC1.1 CVC Certificate Authority -* (C) 2007 FlexSecure GmbH -* 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_CVC_CA_H__ -#define BOTAN_CVC_CA_H__ - -#include <botan/pkcs8.h> -#include <botan/pkcs10.h> -#include <botan/pubkey.h> -#include <botan/cvc_cert.h> - -namespace Botan { - -/** -* This class represents a CVC CA. -*/ -class BOTAN_DLL EAC1_1_CVC_CA - { - public: - - /** - * Create an arbitrary EAC 1.1 CVC. - * The desired key encoding must be set within the key (if applicable). - * @param signer the signer used to sign the certificate - * @param public_key the DER encoded public key to appear in - * the certificate - * @param car the CAR of the certificate - * @param chr the CHR of the certificate - * @param holder_auth_templ the holder authorization value byte to - * appear in the CHAT of the certificate - * @param ced the CED to appear in the certificate - * @param ced the CEX to appear in the certificate - */ - static EAC1_1_CVC make_cert(PK_Signer& signer, - MemoryRegion<byte> const& public_key, - ASN1_Car const& car, - ASN1_Chr const& chr, - byte holder_auth_templ, - ASN1_Ced ced, - ASN1_Cex cex, - RandomNumberGenerator& rng); - }; - -} - -#endif diff --git a/src/cert/cvc/cvc_cert.cpp b/src/cert/cvc/cvc_cert.cpp index 4274e143b..9cc2bb7e5 100644 --- a/src/cert/cvc/cvc_cert.cpp +++ b/src/cert/cvc/cvc_cert.cpp @@ -1,13 +1,12 @@ /* (C) 2007 FlexSecure GmbH - 2008 Jack Lloyd + 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/cvc_cert.h> -#include <botan/cvc_key.h> -#include <botan/ecdsa.h> +#include <botan/oids.h> namespace Botan { @@ -58,21 +57,11 @@ void EAC1_1_CVC::force_decode() if(cpi != 0) throw Decoding_Error("EAC1_1 certificate's cpi was not 0"); - // FIXME: PK algos have no notion of EAC encoder/decoder currently -#if 0 - ECDSA_PublicKey tmp_pk; - std::unique_ptr<EAC1_1_CVC_Decoder> dec = tmp_pk.cvc_eac1_1_decoder(); - sig_algo = dec->public_key(enc_pk); + m_pk = decode_eac1_1_key(enc_pk, sig_algo); - - m_pk = tmp_pk; m_chat_val = enc_chat_val[0]; - self_signed = false; - if(m_car.iso_8859() == m_chr.iso_8859()) - { - self_signed= true; - } -#endif + + self_signed = (m_car.iso_8859() == m_chr.iso_8859()); } /* @@ -99,4 +88,48 @@ bool EAC1_1_CVC::operator==(EAC1_1_CVC const& rhs) const && get_concat_sig() == rhs.get_concat_sig()); } +ECDSA_PublicKey* decode_eac1_1_key(const MemoryRegion<byte>&, + AlgorithmIdentifier&) + { + throw Internal_Error("decode_eac1_1_key: Unimplemented"); + return 0; + } + +EAC1_1_CVC make_cvc_cert(PK_Signer& signer, + MemoryRegion<byte> const& public_key, + ASN1_Car const& car, + ASN1_Chr const& chr, + byte holder_auth_templ, + ASN1_Ced ced, + ASN1_Cex cex, + RandomNumberGenerator& rng) + { + OID chat_oid(OIDS::lookup("CertificateHolderAuthorizationTemplate")); + MemoryVector<byte> enc_chat_val; + enc_chat_val.append(holder_auth_templ); + + MemoryVector<byte> enc_cpi; + enc_cpi.append(0x00); + MemoryVector<byte> tbs = DER_Encoder() + .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) // cpi + .encode(car) + .raw_bytes(public_key) + .encode(chr) + .start_cons(ASN1_Tag(76), APPLICATION) + .encode(chat_oid) + .encode(enc_chat_val, OCTET_STRING, ASN1_Tag(19), APPLICATION) + .end_cons() + .encode(ced) + .encode(cex) + .get_contents(); + + MemoryVector<byte> signed_cert = + EAC1_1_CVC::make_signed(signer, + EAC1_1_CVC::build_cert_body(tbs), + rng); + + DataSource_Memory source(signed_cert); + return EAC1_1_CVC(source); + } + } diff --git a/src/cert/cvc/cvc_cert.h b/src/cert/cvc/cvc_cert.h index ae0c21d7b..12bc41a9c 100644 --- a/src/cert/cvc/cvc_cert.h +++ b/src/cert/cvc/cvc_cert.h @@ -9,14 +9,8 @@ #ifndef BOTAN_CVC_EAC_H__ #define BOTAN_CVC_EAC_H__ -#include <botan/x509_key.h> -#include <botan/pubkey_enums.h> -#include <botan/signed_obj.h> -#include <botan/pubkey.h> -#include <botan/ecdsa.h> -#include <botan/ecdsa_sig.h> -#include <botan/eac_obj.h> #include <botan/cvc_gen_cert.h> +#include <botan/ecdsa.h> #include <string> namespace Botan { @@ -70,7 +64,6 @@ class BOTAN_DLL EAC1_1_CVC : public EAC1_1_gen_CVC<EAC1_1_CVC>//Signed_Object virtual ~EAC1_1_CVC() {} private: void force_decode(); - friend class EAC1_1_CVC_CA; EAC1_1_CVC() {} ASN1_Car m_car; @@ -88,6 +81,34 @@ inline bool operator!=(EAC1_1_CVC const& lhs, EAC1_1_CVC const& rhs) return !(lhs == rhs); } +/** +* Create an arbitrary EAC 1.1 CVC. +* The desired key encoding must be set within the key (if applicable). +* @param signer the signer used to sign the certificate +* @param public_key the DER encoded public key to appear in +* the certificate +* @param car the CAR of the certificate +* @param chr the CHR of the certificate +* @param holder_auth_templ the holder authorization value byte to +* appear in the CHAT of the certificate +* @param ced the CED to appear in the certificate +* @param ced the CEX to appear in the certificate +*/ +EAC1_1_CVC BOTAN_DLL make_cvc_cert(PK_Signer& signer, + const MemoryRegion<byte>& public_key, + ASN1_Car const& car, + ASN1_Chr const& chr, + byte holder_auth_templ, + ASN1_Ced ced, + ASN1_Cex cex, + RandomNumberGenerator& rng); + +/** +* Decode an EAC encoding ECDSA key +*/ +BOTAN_DLL ECDSA_PublicKey* decode_eac1_1_key(const MemoryRegion<byte>& enc_key, + AlgorithmIdentifier& sig_algo); + } #endif diff --git a/src/cert/cvc/cvc_gen_cert.h b/src/cert/cvc/cvc_gen_cert.h index ab6e22ff0..8c3b1b989 100644 --- a/src/cert/cvc/cvc_gen_cert.h +++ b/src/cert/cvc/cvc_gen_cert.h @@ -1,7 +1,7 @@ /* * EAC1_1 general CVC * (C) 2008 Falko Strenzke -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -9,13 +9,11 @@ #ifndef BOTAN_EAC_CVC_GEN_CERT_H__ #define BOTAN_EAC_CVC_GEN_CERT_H__ -#include <botan/x509_key.h> +#include <botan/eac_obj.h> #include <botan/eac_asn_obj.h> -#include <botan/pubkey_enums.h> -#include <botan/pubkey.h> #include <botan/ecdsa.h> -#include <botan/ecdsa_sig.h> -#include <string> +#include <botan/pubkey.h> +#include <memory> namespace Botan { @@ -23,7 +21,7 @@ namespace Botan { * This class represents TR03110 (EAC) v1.1 generalized CV Certificates */ template<typename Derived> -class BOTAN_DLL EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1_1_obj +class EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1_1_obj { friend class EAC1_1_obj<EAC1_1_gen_CVC>; @@ -78,11 +76,12 @@ class BOTAN_DLL EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation PK_Signer& signer, const MemoryRegion<byte>& tbs_bits, RandomNumberGenerator& rng); + virtual ~EAC1_1_gen_CVC<Derived>() - {} + { delete m_pk; } protected: - ECDSA_PublicKey m_pk; // public key + ECDSA_PublicKey* m_pk; ASN1_Chr m_chr; bool self_signed; @@ -102,12 +101,13 @@ template<typename Derived> bool EAC1_1_gen_CVC<Derived>::is_self_signed() const return self_signed; } -template<typename Derived> MemoryVector<byte> EAC1_1_gen_CVC<Derived>::make_signed( +template<typename Derived> +MemoryVector<byte> EAC1_1_gen_CVC<Derived>::make_signed( PK_Signer& signer, const MemoryRegion<byte>& tbs_bits, RandomNumberGenerator& rng) // static { - SecureVector<byte> concat_sig = EAC1_1_obj<Derived>::make_signature(signer, tbs_bits, rng); + SecureVector<byte> concat_sig = signer.sign_message(tbs_bits, rng); return DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) @@ -117,9 +117,10 @@ template<typename Derived> MemoryVector<byte> EAC1_1_gen_CVC<Derived>::make_sign .get_contents(); } -template<typename Derived> std::unique_ptr<Public_Key> EAC1_1_gen_CVC<Derived>::subject_public_key() const +template<typename Derived> +std::unique_ptr<Public_Key> EAC1_1_gen_CVC<Derived>::subject_public_key() const { - return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(m_pk)); + return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(*m_pk)); } template<typename Derived> SecureVector<byte> EAC1_1_gen_CVC<Derived>::build_cert_body(MemoryRegion<byte> const& tbs) diff --git a/src/cert/cvc/cvc_key.h b/src/cert/cvc/cvc_key.h deleted file mode 100644 index a81660597..000000000 --- a/src/cert/cvc/cvc_key.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* EAC CVC Public Key -* (C) 2008 FlexSecure Gmbh -* Falko Strenzke -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_EAC1_1_CVC_PUBLIC_KEY_H__ -#define BOTAN_EAC1_1_CVC_PUBLIC_KEY_H__ - -#include <botan/pipe.h> -#include <botan/pk_keys.h> -#include <botan/alg_id.h> - -namespace Botan { - -/** -* This class represents EAC 1.1 CVC public key encoders. -*/ -class BOTAN_DLL EAC1_1_CVC_Encoder - { - public: - /** - * Get the DER encoded CVC public key. - * @param alg_id the algorithm identifier to use in the encoding - * @return the DER encoded public key - */ - virtual MemoryVector<byte> - public_key(const AlgorithmIdentifier& enc) const = 0; - - virtual ~EAC1_1_CVC_Encoder() {} - }; - -/** -* This class represents EAC 1.1 CVC public key decoders. -*/ -class BOTAN_DLL EAC1_1_CVC_Decoder - { - public: - /** - * Decode a CVC public key. - * @param enc the DER encoded public key to decode - * @return the algorithm identifier found in the encoded public key - */ - virtual AlgorithmIdentifier const - public_key(const MemoryRegion<byte>& enc) = 0; - - virtual ~EAC1_1_CVC_Decoder() {} - }; -} - -#endif diff --git a/src/cert/cvc/cvc_req.cpp b/src/cert/cvc/cvc_req.cpp index 6df6157ad..0a33d4dca 100644 --- a/src/cert/cvc/cvc_req.cpp +++ b/src/cert/cvc/cvc_req.cpp @@ -1,19 +1,13 @@ /* (C) 2007 FlexSecure GmbH - 2008 Jack Lloyd + 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ +#include <botan/cvc_req.h> #include <botan/cvc_cert.h> -#include <botan/der_enc.h> #include <botan/ber_dec.h> -#include <botan/pem.h> -#include <botan/parsing.h> -#include <botan/cvc_key.h> -#include <botan/oids.h> -#include <botan/look_pk.h> -#include <botan/cvc_req.h> namespace Botan { @@ -38,13 +32,7 @@ void EAC1_1_Req::force_decode() if(cpi != 0) throw Decoding_Error("EAC1_1 requests cpi was not 0"); - // FIXME: No EAC support in ECDSA -#if 0 - ECDSA_PublicKey tmp_pk; - std::unique_ptr<EAC1_1_CVC_Decoder> dec = tmp_pk.cvc_eac1_1_decoder(); - sig_algo = dec->public_key(enc_pk); - m_pk = tmp_pk; -#endif + m_pk = decode_eac1_1_key(enc_pk, sig_algo); } EAC1_1_Req::EAC1_1_Req(DataSource& in) diff --git a/src/cert/cvc/cvc_req.h b/src/cert/cvc/cvc_req.h index 2abc72c9a..1e8cea7f8 100644 --- a/src/cert/cvc/cvc_req.h +++ b/src/cert/cvc/cvc_req.h @@ -1,6 +1,7 @@ /* * EAC1_1 CVC Request * (C) 2008 Falko Strenzke +* 2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -8,10 +9,7 @@ #ifndef BOTAN_EAC_CVC_REQ_H__ #define BOTAN_EAC_CVC_REQ_H__ -#include <botan/x509_key.h> -#include <botan/pubkey_enums.h> #include <botan/cvc_gen_cert.h> -#include <botan/cvc_req.h> namespace Botan { @@ -21,7 +19,6 @@ namespace Botan { class BOTAN_DLL EAC1_1_Req : public EAC1_1_gen_CVC<EAC1_1_Req> { public: - friend class EAC1_1_Req_CA; friend class EAC1_1_ADO; friend class EAC1_1_obj<EAC1_1_Req>; diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 1d06acd66..0c765347f 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -1,22 +1,16 @@ /* (C) 2007 FlexSecure GmbH - 2008 Jack Lloyd + 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/cvc_self.h> -#include <botan/cvc_cert.h> -#include <botan/cvc_ca.h> -#include <botan/alg_id.h> -#include <botan/cvc_key.h> +#include <botan/ecc_key.h> +#include <botan/point_gfp.h> +#include <botan/time.h> #include <botan/oids.h> -#include <botan/look_pk.h> -#include <botan/cvc_req.h> -#include <botan/cvc_ado.h> -#include <chrono> #include <sstream> -#include <assert.h> namespace Botan { @@ -35,49 +29,73 @@ enum CHAT_values{ FINGERPRINT = 0x01 }; -std::string padding_and_hash_from_oid(OID const& oid) +void encode_eac_bigint(DER_Encoder& der, const BigInt& x, ASN1_Tag tag) { - std::string padding_and_hash = OIDS::lookup(oid); // use the hash - assert(padding_and_hash.substr(0,6) == "ECDSA/"); // can only be ECDSA for now - assert(padding_and_hash.find("/",0) == 5); - padding_and_hash.erase(0, padding_and_hash.find("/",0) + 1); - return padding_and_hash; + der.encode(BigInt::encode_1363(x, x.bytes()), OCTET_STRING, tag); } -std::string fixed_len_seqnr(u32bit seqnr, u32bit len) +MemoryVector<byte> eac_1_1_encoding(const EC_PublicKey* key, + const OID& sig_algo) { - std::stringstream ss; - std::string result; - ss << seqnr; - ss >> result; - if (result.size() > len) - { - throw Invalid_Argument("fixed_len_seqnr(): number too high to be encoded in provided length"); - } - while (result.size() < len) + if(key->domain_format() == EC_DOMPAR_ENC_OID) + throw Encoding_Error("CVC encoder: cannot encode parameters by OID"); + + const EC_Domain_Params& domain = key->domain(); + + // This is why we can't have nice things + + DER_Encoder enc; + enc.start_cons(ASN1_Tag(73), APPLICATION) + .encode(sig_algo); + + if(key->domain_format() == EC_DOMPAR_ENC_EXPLICIT) { - result.insert(0,"0"); + encode_eac_bigint(enc, domain.get_curve().get_p(), ASN1_Tag(1)); + encode_eac_bigint(enc, domain.get_curve().get_a(), ASN1_Tag(2)); + encode_eac_bigint(enc, domain.get_curve().get_b(), ASN1_Tag(3)); + + enc.encode(EC2OSP(domain.get_base_point(), PointGFp::UNCOMPRESSED), + OCTET_STRING, ASN1_Tag(4)); + + encode_eac_bigint(enc, domain.get_order(), ASN1_Tag(4)); } - return result; + + enc.encode(EC2OSP(key->public_point(), PointGFp::UNCOMPRESSED), + OCTET_STRING, ASN1_Tag(6)); + + if(key->domain_format() == EC_DOMPAR_ENC_EXPLICIT) + encode_eac_bigint(enc, domain.get_cofactor(), ASN1_Tag(7)); + + enc.end_cons(); + + return enc.get_contents(); + } + +std::string padding_and_hash_from_oid(OID const& oid) + { + std::string padding_and_hash = OIDS::lookup(oid); // use the hash + + if(padding_and_hash.substr(0,6) != "ECDSA/") + throw Invalid_State("CVC: Can only use ECDSA, not " + padding_and_hash); + + padding_and_hash.erase(0, padding_and_hash.find("/") + 1); + return padding_and_hash; } } -namespace CVC_EAC -{ + +namespace CVC_EAC { EAC1_1_CVC create_self_signed_cert(Private_Key const& key, EAC1_1_CVC_Options const& opt, RandomNumberGenerator& rng) { - // NOTE: we ignore - // the value - // of opt.chr - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + // NOTE: we ignore the value of opt.chr - if (priv_key == 0) - { + const ECDSA_PrivateKey* priv_key = dynamic_cast<const ECDSA_PrivateKey*>(&key); + + if(priv_key == 0) throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } ASN1_Chr chr(opt.car.value()); @@ -86,19 +104,15 @@ EAC1_1_CVC create_self_signed_cert(Private_Key const& key, sig_algo.oid = OIDS::lookup(priv_key->algo_name() + "/" + padding_and_hash); sig_algo = AlgorithmIdentifier(sig_algo.oid, AlgorithmIdentifier::USE_NULL_PARAM); - std::unique_ptr<Botan::PK_Signer> signer(get_pk_signer(*priv_key, padding_and_hash)); - -#if 0 // FIXME - std::unique_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); -#else - MemoryVector<byte> enc_public_key; -#endif + PK_Signer signer(*priv_key, padding_and_hash); - return EAC1_1_CVC_CA::make_cert(*signer.get(), enc_public_key, - opt.car, chr, opt.holder_auth_templ, - opt.ced, opt.cex, rng); + MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + return make_cvc_cert(signer, + enc_public_key, + opt.car, chr, + opt.holder_auth_templ, + opt.ced, opt.cex, rng); } EAC1_1_Req create_cvc_req(Private_Key const& key, @@ -117,14 +131,9 @@ EAC1_1_Req create_cvc_req(Private_Key const& key, sig_algo.oid = OIDS::lookup(priv_key->algo_name() + "/" + padding_and_hash); sig_algo = AlgorithmIdentifier(sig_algo.oid, AlgorithmIdentifier::USE_NULL_PARAM); - std::unique_ptr<Botan::PK_Signer> signer(get_pk_signer(*priv_key, padding_and_hash)); + PK_Signer signer(*priv_key, padding_and_hash); -#if 0 // FIXME - std::unique_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); -#else - MemoryVector<byte> enc_public_key; -#endif + MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); MemoryVector<byte> enc_cpi; enc_cpi.append(0x00); @@ -134,7 +143,10 @@ EAC1_1_Req create_cvc_req(Private_Key const& key, .encode(chr) .get_contents(); - MemoryVector<byte> signed_cert = EAC1_1_gen_CVC<EAC1_1_Req>::make_signed(*signer.get(), EAC1_1_gen_CVC<EAC1_1_Req>::build_cert_body(tbs), rng); + MemoryVector<byte> signed_cert = + EAC1_1_gen_CVC<EAC1_1_Req>::make_signed(signer, + EAC1_1_gen_CVC<EAC1_1_Req>::build_cert_body(tbs), + rng); DataSource_Memory source(signed_cert); return EAC1_1_Req(source); @@ -153,9 +165,7 @@ EAC1_1_ADO create_ado_req(Private_Key const& key, } std::string padding_and_hash = padding_and_hash_from_oid(req.signature_algorithm().oid); - - std::unique_ptr<Botan::PK_Signer> signer(get_pk_signer(*priv_key, padding_and_hash)); - + PK_Signer signer(*priv_key, padding_and_hash); SecureVector<byte> tbs_bits = req.BER_encode(); tbs_bits.append(DER_Encoder().encode(car).get_contents()); MemoryVector<byte> signed_cert = EAC1_1_ADO::make_signed(*signer.get(), tbs_bits, rng); @@ -187,7 +197,7 @@ EAC1_1_CVC create_cvca(Private_Key const& key, opts.cex.add_months(cvca_validity_months); opts.holder_auth_templ = (CVCA | (iris * IRIS) | (fingerpr * FINGERPRINT)); opts.hash_alg = hash; - return Botan::CVC_EAC::create_self_signed_cert(*priv_key, opts, rng); + return CVC_EAC::create_self_signed_cert(*priv_key, opts, rng); } @@ -218,25 +228,19 @@ EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer, } AlgorithmIdentifier sig_algo = signer.signature_algorithm(); std::string padding_and_hash = padding_and_hash_from_oid(sig_algo.oid); - std::unique_ptr<Botan::PK_Signer> pk_signer(get_pk_signer(*priv_key, padding_and_hash)); - std::unique_ptr<Public_Key> pk = signee.subject_public_key(); - ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get()); + PK_Signer pk_signer(*priv_key, padding_and_hash); + std::auto_ptr<Public_Key> pk = signee.subject_public_key(); + ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get()); subj_pk->set_parameter_encoding(EC_DOMPAR_ENC_EXPLICIT); -#if 0 // FIXME - std::unique_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); -#else - MemoryVector<byte> enc_public_key; -#endif - - return EAC1_1_CVC_CA::make_cert(*pk_signer.get(), enc_public_key, - signer.get_car(), - signee.get_chr(), - signer.get_chat_value(), - ced, - cex, - rng); + MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + + return make_cvc_cert(pk_signer, enc_public_key, + signer.get_car(), + signee.get_chr(), + signer.get_chat_value(), + ced, cex, + rng); } EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, @@ -255,11 +259,11 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); } std::string chr_str = signee.get_chr().value(); - chr_str.append(fixed_len_seqnr(seqnr, seqnr_len)); + chr_str += to_string(seqnr, seqnr_len); ASN1_Chr chr(chr_str); std::string padding_and_hash = padding_and_hash_from_oid(signee.signature_algorithm().oid); - std::unique_ptr<Botan::PK_Signer> pk_signer(get_pk_signer(*priv_key, padding_and_hash)); - std::unique_ptr<Public_Key> pk = signee.subject_public_key(); + PK_Signer pk_signer(*priv_key, padding_and_hash); + std::auto_ptr<Public_Key> pk = signee.subject_public_key(); ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get()); std::unique_ptr<Public_Key> signer_pk = signer_cert.subject_public_key(); @@ -269,13 +273,6 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, subj_pk->set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA); -#if 0 // FIXME - std::unique_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); -#else - MemoryVector<byte> enc_public_key; -#endif - AlgorithmIdentifier sig_algo(signer_cert.signature_algorithm()); ASN1_Ced ced(std::chrono::system_clock::now()); @@ -288,13 +285,9 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, // we sign a dvca cex.add_months(dvca_validity_months); if (domestic) - { chat_val = DVCA_domestic | chat_low; - } else - { chat_val = DVCA_foreign | chat_low; - } } else if ((signer_cert.get_chat_value() & DVCA_domestic) == DVCA_domestic || (signer_cert.get_chat_value() & DVCA_foreign) == DVCA_foreign) @@ -307,13 +300,16 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, throw Invalid_Argument("sign_request(): encountered illegal value for CHAT"); // (IS cannot sign certificates) } - return EAC1_1_CVC_CA::make_cert(*pk_signer.get(), enc_public_key, - ASN1_Car(signer_cert.get_chr().iso_8859()), - chr, - chat_val, - ced, - cex, - rng); + + MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid); + + return make_cvc_cert(pk_signer, enc_public_key, + ASN1_Car(signer_cert.get_chr().iso_8859()), + chr, + chat_val, + ced, + cex, + rng); } EAC1_1_Req create_cvc_req(Private_Key const& prkey, @@ -328,7 +324,7 @@ EAC1_1_Req create_cvc_req(Private_Key const& prkey, } ECDSA_PrivateKey key(*priv_key); key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA); - return Botan::CVC_EAC::create_cvc_req(key, chr, hash_alg, rng); + return CVC_EAC::create_cvc_req(key, chr, hash_alg, rng); } } // namespace DE_EAC diff --git a/src/cert/cvc/eac_asn_obj.h b/src/cert/cvc/eac_asn_obj.h index 79802951c..3ab57d7e4 100644 --- a/src/cert/cvc/eac_asn_obj.h +++ b/src/cert/cvc/eac_asn_obj.h @@ -1,7 +1,7 @@ /* * EAC ASN.1 Objects * (C) 2007-2008 FlexSecure GmbH -* 2008-2009 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -10,9 +10,6 @@ #define BOTAN_EAC_ASN1_OBJ_H__ #include <botan/asn1_obj.h> -#include <vector> -#include <map> -#include <chrono> namespace Botan { diff --git a/src/cert/cvc/eac_obj.h b/src/cert/cvc/eac_obj.h index 419929a19..66752b10c 100644 --- a/src/cert/cvc/eac_obj.h +++ b/src/cert/cvc/eac_obj.h @@ -8,17 +8,8 @@ #ifndef BOTAN_EAC_OBJ_H__ #define BOTAN_EAC_OBJ_H__ -#include <botan/pubkey.h> -#include <botan/x509_key.h> #include <botan/signed_obj.h> -#include <botan/pubkey_enums.h> -#include <botan/pubkey.h> -#include <botan/parsing.h> -#include <botan/pem.h> -#include <botan/oids.h> -#include <botan/look_pk.h> #include <botan/ecdsa_sig.h> -#include <string> namespace Botan { @@ -26,103 +17,38 @@ namespace Botan { * TR03110 v1.1 EAC CV Certificate */ template<typename Derived> // CRTP is used enable the call sequence: -class BOTAN_DLL EAC1_1_obj : public EAC_Signed_Object +class EAC1_1_obj : public EAC_Signed_Object { - // data members first: - protected: - - ECDSA_Signature m_sig; - - // member functions here: public: /** * Return the signature as a concatenation of the encoded parts. * @result the concatenated signature */ - SecureVector<byte> get_concat_sig() const; + SecureVector<byte> get_concat_sig() const + { return m_sig.get_concatenation(); } - /** - * Verify the signature of this objects. - * @param pub_key the public key to verify the signature with - * @result true if the verification succeeded - */ - virtual bool check_signature(Public_Key& pub_key) const; + bool check_signature(class Public_Key& key) const + { + return EAC_Signed_Object::check_signature(key, m_sig.DER_encode()); + } protected: - void init(DataSource& in); - - static SecureVector<byte> make_signature(PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, - RandomNumberGenerator& rng); - - virtual ~EAC1_1_obj<Derived>(){} - - }; - -template<typename Derived> SecureVector<byte> EAC1_1_obj<Derived>::get_concat_sig() const - { - return m_sig.get_concatenation(); - } - -template<typename Derived> SecureVector<byte> -EAC1_1_obj<Derived>::make_signature(PK_Signer& signer, - const MemoryRegion<byte>& tbs_bits, - RandomNumberGenerator& rng) - { - // this is the signature as a der sequence - SecureVector<byte> seq_sig = signer.sign_message(tbs_bits, rng); - - ECDSA_Signature sig(decode_seq(seq_sig)); - SecureVector<byte> concat_sig(sig.get_concatenation()); - return concat_sig; - } - -template<typename Derived> -void EAC1_1_obj<Derived>::init(DataSource& in) - { - try - { - Derived::decode_info(in, tbs_bits, m_sig); - } - catch(Decoding_Error) - { - throw Decoding_Error(PEM_label_pref + " decoding failed"); - } - } - -template<typename Derived> -bool EAC1_1_obj<Derived>::check_signature(Public_Key& pub_key) const - { - try - { - std::vector<std::string> sig_info = - split_on(OIDS::lookup(sig_algo.oid), '/'); + ECDSA_Signature m_sig; - if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name()) + void init(DataSource& in) { - return false; + try + { + Derived::decode_info(in, tbs_bits, m_sig); + } + catch(Decoding_Error) + { + throw Decoding_Error(PEM_label_pref + " decoding failed"); + } } - std::string padding = sig_info[1]; - Signature_Format format = - (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - - if(!dynamic_cast<PK_Verifying_wo_MR_Key*>(&pub_key)) - return false; - - std::unique_ptr<ECDSA_Signature_Encoder> enc(new ECDSA_Signature_Encoder(&m_sig)); - SecureVector<byte> seq_sig = enc->signature_bits(); - SecureVector<byte> to_sign = tbs_data(); - - PK_Verifying_wo_MR_Key& sig_key = dynamic_cast<PK_Verifying_wo_MR_Key&>(pub_key); - std::unique_ptr<PK_Verifier> verifier(get_pk_verifier(sig_key, padding, format)); - return verifier->verify_message(to_sign, seq_sig); - } - catch(...) - { - return false; - } - } + virtual ~EAC1_1_obj<Derived>(){} + }; } diff --git a/src/cert/cvc/ecdsa_sig.cpp b/src/cert/cvc/ecdsa_sig.cpp index 1a60f7aa8..e003bb369 100644 --- a/src/cert/cvc/ecdsa_sig.cpp +++ b/src/cert/cvc/ecdsa_sig.cpp @@ -1,31 +1,36 @@ +/* +* ECDSA Signature +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* (C) 2008-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ #include <botan/ecdsa_sig.h> -#include <memory> namespace Botan { -ECDSA_Signature::ECDSA_Signature(const BigInt& r, const BigInt& s) - : m_r(r), - m_s(s) - {} - -ECDSA_Signature::ECDSA_Signature(const ECDSA_Signature& other) - : m_r(other.m_r), m_s(other.m_s) - {} - -ECDSA_Signature const& ECDSA_Signature::operator=(const ECDSA_Signature& other) +ECDSA_Signature::ECDSA_Signature(const MemoryRegion<byte>& ber) { - m_r = other.m_r; - m_s = other.m_s; - return *this; + BER_Decoder(ber) + .start_cons(SEQUENCE) + .decode(m_r) + .decode(m_s) + .end_cons() + .verify_end(); } -bool operator==(const ECDSA_Signature& lhs, const ECDSA_Signature& rhs) +MemoryVector<byte> ECDSA_Signature::DER_encode() const { - return (lhs.get_r() == rhs.get_r() && lhs.get_s() == rhs.get_s()); + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(get_r()) + .encode(get_s()) + .end_cons() + .get_contents(); } -SecureVector<byte> const ECDSA_Signature::get_concatenation() const +MemoryVector<byte> ECDSA_Signature::get_concatenation() const { u32bit enc_len = m_r > m_s ? m_r.bytes() : m_s.bytes(); // use the larger @@ -37,16 +42,7 @@ SecureVector<byte> const ECDSA_Signature::get_concatenation() const return result; } -ECDSA_Signature const decode_seq(MemoryRegion<byte> const& seq) - { - ECDSA_Signature sig; - - std::unique_ptr<ECDSA_Signature_Decoder> dec(new ECDSA_Signature_Decoder(&sig)); - dec->signature_bits(seq); - return sig; - } - -ECDSA_Signature const decode_concatenation(MemoryRegion<byte> const& concat) +ECDSA_Signature decode_concatenation(const MemoryRegion<byte>& concat) { if(concat.size() % 2 != 0) throw Invalid_Argument("Erroneous length of signature"); diff --git a/src/cert/cvc/ecdsa_sig.h b/src/cert/cvc/ecdsa_sig.h index 15015c76d..1397a92b1 100644 --- a/src/cert/cvc/ecdsa_sig.h +++ b/src/cert/cvc/ecdsa_sig.h @@ -1,7 +1,7 @@ /* -* ECDSA +* ECDSA Signature * (C) 2007 Falko Strenzke, FlexSecure GmbH -* (C) 2008 Jack Lloyd +* (C) 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -21,9 +21,10 @@ class BOTAN_DLL ECDSA_Signature friend class ECDSA_Signature_Decoder; ECDSA_Signature() {} - ECDSA_Signature(const BigInt& r, const BigInt& s); - ECDSA_Signature(ECDSA_Signature const& other); - ECDSA_Signature const& operator=(ECDSA_Signature const& other); + ECDSA_Signature(const BigInt& r, const BigInt& s) : + m_r(r), m_s(s) {} + + ECDSA_Signature(const MemoryRegion<byte>& ber); const BigInt& get_r() const { return m_r; } const BigInt& get_s() const { return m_s; } @@ -31,57 +32,26 @@ class BOTAN_DLL ECDSA_Signature /** * return the r||s */ - SecureVector<byte> const get_concatenation() const; + MemoryVector<byte> get_concatenation() const; + + MemoryVector<byte> DER_encode() const; + + bool operator==(const ECDSA_Signature& other) const + { + return (get_r() == other.get_r() && get_s() == other.get_s()); + } + private: BigInt m_r; BigInt m_s; }; -/* Equality of ECDSA_Signature */ -bool operator==(const ECDSA_Signature& lhs, const ECDSA_Signature& rhs); inline bool operator!=(const ECDSA_Signature& lhs, const ECDSA_Signature& rhs) { return !(lhs == rhs); } -class BOTAN_DLL ECDSA_Signature_Decoder - { - public: - void signature_bits(const MemoryRegion<byte>& bits) - { - BER_Decoder(bits) - .start_cons(SEQUENCE) - .decode(m_signature->m_r) - .decode(m_signature->m_s) - .verify_end() - .end_cons(); - } - ECDSA_Signature_Decoder(ECDSA_Signature* signature) : m_signature(signature) - {} - private: - ECDSA_Signature* m_signature; - }; - -class BOTAN_DLL ECDSA_Signature_Encoder - { - public: - MemoryVector<byte> signature_bits() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(m_signature->get_r()) - .encode(m_signature->get_s()) - .end_cons() - .get_contents(); - } - ECDSA_Signature_Encoder(const ECDSA_Signature* signature) : m_signature(signature) - {} - private: - const ECDSA_Signature* m_signature; - }; - -ECDSA_Signature const decode_seq(MemoryRegion<byte> const& seq); -ECDSA_Signature const decode_concatenation(MemoryRegion<byte> const& concatenation); +ECDSA_Signature decode_concatenation(const MemoryRegion<byte>& concatenation); } diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index 285838379..91de3bc19 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -3,10 +3,8 @@ load_on auto <header:public> cvc_ado.h -cvc_ca.h cvc_cert.h cvc_gen_cert.h -cvc_key.h cvc_req.h cvc_self.h eac_asn_obj.h @@ -20,7 +18,6 @@ asn1_eac_str.cpp asn1_eac_tm.cpp ecdsa_sig.cpp cvc_ado.cpp -cvc_ca.cpp cvc_cert.cpp cvc_req.cpp cvc_self.cpp @@ -35,7 +32,6 @@ filters libstate oid_lookup pem -pk_codecs pubkey x509 </requires> diff --git a/src/cert/cvc/signed_obj.cpp b/src/cert/cvc/signed_obj.cpp index 4a08ed0ac..d6aa2f02b 100644 --- a/src/cert/cvc/signed_obj.cpp +++ b/src/cert/cvc/signed_obj.cpp @@ -1,12 +1,15 @@ /* -* X.509 SIGNED Object -* (C) 1999-2007 Jack Lloyd +* EAC SIGNED Object +* (C) 1999-2010 Jack Lloyd * 2007 FlexSecure GmbH * * Distributed under the terms of the Botan license */ #include <botan/signed_obj.h> +#include <botan/pubkey.h> +#include <botan/oids.h> +#include <memory> namespace Botan { @@ -42,6 +45,34 @@ AlgorithmIdentifier EAC_Signed_Object::signature_algorithm() const return sig_algo; } +bool EAC_Signed_Object::check_signature(Public_Key& pub_key, + const MemoryRegion<byte>& sig) const + { + try + { + std::vector<std::string> sig_info = + split_on(OIDS::lookup(sig_algo.oid), '/'); + + if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name()) + { + return false; + } + + std::string padding = sig_info[1]; + Signature_Format format = + (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; + + SecureVector<byte> to_sign = tbs_data(); + + PK_Verifier verifier(pub_key, padding, format); + return verifier.verify_message(to_sign, sig); + } + catch(...) + { + return false; + } + } + /* * Try to decode the actual information */ @@ -53,14 +84,12 @@ void EAC_Signed_Object::do_decode() catch(Decoding_Error& e) { const std::string what = e.what(); - throw Decoding_Error(PEM_label_pref + " decoding failed (" + - what.substr(23, std::string::npos) + ")"); + throw Decoding_Error(PEM_label_pref + " decoding failed (" + what + ")"); } catch(Invalid_Argument& e) { const std::string what = e.what(); - throw Decoding_Error(PEM_label_pref + " decoding failed (" + - what.substr(7, std::string::npos) + ")"); + throw Decoding_Error(PEM_label_pref + " decoding failed (" + what + ")"); } } diff --git a/src/cert/cvc/signed_obj.h b/src/cert/cvc/signed_obj.h index 17b75a08a..0e7dd6bdb 100644 --- a/src/cert/cvc/signed_obj.h +++ b/src/cert/cvc/signed_obj.h @@ -53,7 +53,8 @@ class BOTAN_DLL EAC_Signed_Object * @return true if the signature was created by the private key * associated with this public key */ - virtual bool check_signature(class Public_Key&) const = 0; + bool check_signature(class Public_Key& key, + const MemoryRegion<byte>& sig) const; /** * Write this object DER encoded into a specified pipe. |