diff options
author | lloyd <[email protected]> | 2008-10-08 20:40:40 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-10-08 20:40:40 +0000 |
commit | 0ffb4257258df236dc469ef086b1871fe7b5afba (patch) | |
tree | 8cad23bb8bdf1db1f4d7e6a19eb23d6c1ef2e4ae /src/cert/cvc/cvc_self.cpp | |
parent | fa7aa7f8dc857bae547fe6981fa6fc2b065b2004 (diff) |
Many improvements towards getting the CVC implementation from InSiTo
compiling against mainline. Add several missing classes extracted from
other files inside InSiTo. Add dependency note for ecdsa and asn1
Diffstat (limited to 'src/cert/cvc/cvc_self.cpp')
-rw-r--r-- | src/cert/cvc/cvc_self.cpp | 467 |
1 files changed, 235 insertions, 232 deletions
diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 130ac6998..9ea561366 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -1,3 +1,8 @@ +/* + (C) 2007 FlexSecure GmbH + 2008 Jack Lloyd +*/ + #include <botan/cvc_self.h> #include <botan/cvc_cert.h> #include <botan/cvc_ca.h> @@ -8,264 +13,262 @@ #include <botan/cvc_req.h> #include <botan/cvc_ado.h> #include <botan/util.h> -#include <botan/config.h> -#include <botan/ec.h> #include <sstream> -using namespace Botan; -namespace Botan - { - namespace - { - std::string padding_and_hash_from_oid(OID const& oid) - { - 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; - } - std::string fixed_len_seqnr(u32bit seqnr, u32bit len) - { - 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) - { - result.insert(0,"0"); - } - return result; - } +namespace Botan { +namespace { + +std::string padding_and_hash_from_oid(OID const& oid) + { + 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; + } +std::string fixed_len_seqnr(u32bit seqnr, u32bit len) + { + 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"); } - namespace CVC_EAC + while (result.size() < len) { + result.insert(0,"0"); + } + return result; + } - EAC1_1_CVC create_self_signed_cert(Private_Key const& key, - EAC1_1_CVC_Options const& opt) - { - // NOTE: we ignore - // the value - // of opt.chr - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); +} +namespace CVC_EAC +{ - if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } +EAC1_1_CVC create_self_signed_cert(Private_Key const& key, + EAC1_1_CVC_Options const& opt) + { + // NOTE: we ignore + // the value + // of opt.chr + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); - ASN1_Chr chr(opt.car.value()); + if (priv_key == 0) + { + throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); + } - AlgorithmIdentifier sig_algo; - std::string padding_and_hash(eac_cvc_emsa + "(" + opt.hash_alg + ")"); - sig_algo.oid = OIDS::lookup_bsi(priv_key->algo_name() + "/" + padding_and_hash); - sig_algo = AlgorithmIdentifier(sig_algo.oid, AlgorithmIdentifier::USE_NULL_PARAM); + ASN1_Chr chr(opt.car.value()); - std::auto_ptr<Botan::PK_Signer> signer = get_pk_signer(*priv_key, padding_and_hash); + AlgorithmIdentifier sig_algo; + std::string padding_and_hash(eac_cvc_emsa + "(" + opt.hash_alg + ")"); + sig_algo.oid = OIDS::lookup_bsi(priv_key->algo_name() + "/" + padding_and_hash); + sig_algo = AlgorithmIdentifier(sig_algo.oid, AlgorithmIdentifier::USE_NULL_PARAM); - std::auto_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); - return EAC1_1_CVC_CA::make_cert(signer, enc_public_key, opt.car, chr, opt.holder_auth_templ, opt.ced, opt.cex); + std::auto_ptr<Botan::PK_Signer> signer(get_pk_signer(*priv_key, padding_and_hash)); - } + std::auto_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder()); + MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); + return EAC1_1_CVC_CA::make_cert(signer, enc_public_key, opt.car, chr, opt.holder_auth_templ, opt.ced, opt.cex); - EAC1_1_Req create_cvc_req(Private_Key const& key, - ASN1_Chr const& chr, - std::string const& hash_alg) - { + } - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); - if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } - AlgorithmIdentifier sig_algo; - std::string padding_and_hash(eac_cvc_emsa + "(" + hash_alg + ")"); - sig_algo.oid = OIDS::lookup_bsi(priv_key->algo_name() + "/" + padding_and_hash); - sig_algo = AlgorithmIdentifier(sig_algo.oid, AlgorithmIdentifier::USE_NULL_PARAM); +EAC1_1_Req create_cvc_req(Private_Key const& key, + ASN1_Chr const& chr, + std::string const& hash_alg) + { - std::auto_ptr<Botan::PK_Signer> signer = get_pk_signer(*priv_key, padding_and_hash); + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + if (priv_key == 0) + { + throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); + } + AlgorithmIdentifier sig_algo; + std::string padding_and_hash(eac_cvc_emsa + "(" + hash_alg + ")"); + sig_algo.oid = OIDS::lookup_bsi(priv_key->algo_name() + "/" + padding_and_hash); + sig_algo = AlgorithmIdentifier(sig_algo.oid, AlgorithmIdentifier::USE_NULL_PARAM); - std::auto_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); - MemoryVector<byte> enc_cpi; - enc_cpi.append(0x00); - MemoryVector<byte> tbs = DER_Encoder() - .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) - .raw_bytes(enc_public_key) - .encode(chr) - .get_contents(); + std::auto_ptr<Botan::PK_Signer> signer = get_pk_signer(*priv_key, padding_and_hash); - 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)); - std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); - return EAC1_1_Req(source); - } + std::auto_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder()); + MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); + MemoryVector<byte> enc_cpi; + enc_cpi.append(0x00); + MemoryVector<byte> tbs = DER_Encoder() + .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) + .raw_bytes(enc_public_key) + .encode(chr) + .get_contents(); - EAC1_1_ADO create_ado_req(Private_Key const& key, - EAC1_1_Req const& req, - ASN1_Car const& car) - { + 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)); + std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); + return EAC1_1_Req(source); + } - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); - if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } - std::string padding_and_hash = padding_and_hash_from_oid(req.signature_algorithm().oid); - std::auto_ptr<Botan::PK_Signer> signer = get_pk_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, tbs_bits); - std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); - return EAC1_1_ADO(source); - } +EAC1_1_ADO create_ado_req(Private_Key const& key, + EAC1_1_Req const& req, + ASN1_Car const& car) + { - } // namespace CVC_EAC - namespace DE_EAC + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + if (priv_key == 0) { - EAC1_1_CVC create_cvca(Private_Key const& key, std::string const& hash, ASN1_Car const& car, bool iris, bool fingerpr) - { - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); - if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } - EAC1_1_CVC_Options opts; - opts.car = car; - const u64bit current_time = system_time(); + throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); + } + std::string padding_and_hash = padding_and_hash_from_oid(req.signature_algorithm().oid); + std::auto_ptr<Botan::PK_Signer> signer(get_pk_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, tbs_bits); + std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); + return EAC1_1_ADO(source); + } - opts.ced = ASN1_Ced(current_time); - opts.cex = ASN1_Cex(opts.ced); - opts.cex.add_months(global_config().option_as_u32bit("eac/ca/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); - } +} // namespace CVC_EAC +namespace DE_EAC +{ +EAC1_1_CVC create_cvca(Private_Key const& key, std::string const& hash, ASN1_Car const& car, bool iris, bool fingerpr) + { + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + if (priv_key == 0) + { + throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); + } + EAC1_1_CVC_Options opts; + opts.car = car; + const u64bit current_time = system_time(); + opts.ced = ASN1_Ced(current_time); + opts.cex = ASN1_Cex(opts.ced); + opts.cex.add_months(global_config().option_as_u32bit("eac/ca/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); + } - EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer, - Private_Key const& key, - EAC1_1_CVC const& signee) - { - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); - if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } - ASN1_Ced ced(system_time()); - ASN1_Cex cex(signee.get_cex()); - if (*static_cast<EAC_Time*>(&ced) > *static_cast<EAC_Time*>(&cex)) - { - std::string detail("link_cvca(): validity periods of provided certificates don´t overlap: currend time = ced = "); - detail += ced.as_string(); - detail += ", signee.cex = "; - detail += cex.as_string(); - throw Invalid_Argument(detail); - } - if (signer.signature_algorithm() != signee.signature_algorithm()) - { - throw Invalid_Argument("link_cvca(): signature algorithms of signer and signee don´t match"); - } - AlgorithmIdentifier sig_algo = signer.signature_algorithm(); - std::string padding_and_hash = padding_and_hash_from_oid(sig_algo.oid); - std::auto_ptr<Botan::PK_Signer> pk_signer = get_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(ENC_EXPLICIT); - std::auto_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); - return EAC1_1_CVC_CA::make_cert(pk_signer, enc_public_key, - signer.get_car(), - signee.get_chr(), - signer.get_chat_value(), - ced, - cex); - } - EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, - Private_Key const& key, - EAC1_1_Req const& signee, - u32bit seqnr, - u32bit seqnr_len, - bool domestic) - { - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); - if (priv_key == 0) - { - 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)); - ASN1_Chr chr(chr_str); - std::string padding_and_hash = padding_and_hash_from_oid(signee.signature_algorithm().oid); - std::auto_ptr<Botan::PK_Signer> pk_signer = get_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::auto_ptr<Public_Key> signer_pk = signer_cert.subject_public_key(); +EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer, + Private_Key const& key, + EAC1_1_CVC const& signee) + { + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + if (priv_key == 0) + { + throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); + } + ASN1_Ced ced(system_time()); + ASN1_Cex cex(signee.get_cex()); + if (*static_cast<EAC_Time*>(&ced) > *static_cast<EAC_Time*>(&cex)) + { + std::string detail("link_cvca(): validity periods of provided certificates don´t overlap: currend time = ced = "); + detail += ced.as_string(); + detail += ", signee.cex = "; + detail += cex.as_string(); + throw Invalid_Argument(detail); + } + if (signer.signature_algorithm() != signee.signature_algorithm()) + { + throw Invalid_Argument("link_cvca(): signature algorithms of signer and signee don´t match"); + } + AlgorithmIdentifier sig_algo = signer.signature_algorithm(); + std::string padding_and_hash = padding_and_hash_from_oid(sig_algo.oid); + std::auto_ptr<Botan::PK_Signer> pk_signer = get_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(ENC_EXPLICIT); + std::auto_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder()); + MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); + return EAC1_1_CVC_CA::make_cert(pk_signer, enc_public_key, + signer.get_car(), + signee.get_chr(), + signer.get_chat_value(), + ced, + cex); + } + +EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert, + Private_Key const& key, + EAC1_1_Req const& signee, + u32bit seqnr, + u32bit seqnr_len, + bool domestic) + { + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key); + if (priv_key == 0) + { + 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)); + ASN1_Chr chr(chr_str); + std::string padding_and_hash = padding_and_hash_from_oid(signee.signature_algorithm().oid); + std::auto_ptr<Botan::PK_Signer> pk_signer = get_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::auto_ptr<Public_Key> signer_pk = signer_cert.subject_public_key(); + + // for the case that the domain parameters are not set... + // (we use those from the signer because they must fit) + subj_pk->set_domain_parameters(priv_key->get_domain_parameters()); - // for the case that the domain parameters are not set... - // (we use those from the signer because they must fit) - subj_pk->set_domain_parameters(priv_key->get_domain_parameters()); + subj_pk->set_parameter_encoding(ENC_IMPLICITCA); + std::auto_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder()); + AlgorithmIdentifier sig_algo(signer_cert.signature_algorithm()); + MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); + const u64bit current_time = system_time(); + ASN1_Ced ced(current_time); + u32bit chat_val; + u32bit chat_low = signer_cert.get_chat_value() & 0x3; // take the chat rights from signer + ASN1_Cex cex(ced); + if ((signer_cert.get_chat_value() & CVCA) == CVCA) + { + // we sign a dvca + cex.add_months(global_config().option_as_u32bit("eac/ca/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) + { + cex.add_months(global_config().option_as_u32bit("eac/ca/is_validity_months")); + chat_val = IS | chat_low; + } + else + { + throw Invalid_Argument("sign_request(): encountered illegal value for CHAT"); + // (IS cannot sign certificates) + } + return EAC1_1_CVC_CA::make_cert(pk_signer, enc_public_key, + ASN1_Car(signer_cert.get_chr().iso_8859()), + chr, + chat_val, + ced, + cex); + } +EAC1_1_Req create_cvc_req(Private_Key const& prkey, + ASN1_Chr const& chr, + std::string const& hash_alg) + { + ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&prkey); + if (priv_key == 0) + { + throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); + } + ECDSA_PrivateKey key(*priv_key); + key.set_parameter_encoding(ENC_IMPLICITCA); + return Botan::CVC_EAC::create_cvc_req(key, chr, hash_alg); + } - subj_pk->set_parameter_encoding(ENC_IMPLICITCA); - std::auto_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder()); - AlgorithmIdentifier sig_algo(signer_cert.signature_algorithm()); - MemoryVector<byte> enc_public_key = enc->public_key(sig_algo); - const u64bit current_time = system_time(); - ASN1_Ced ced(current_time); - u32bit chat_val; - u32bit chat_low = signer_cert.get_chat_value() & 0x3; // take the chat rights from signer - ASN1_Cex cex(ced); - if ((signer_cert.get_chat_value() & CVCA) == CVCA) - { - // we sign a dvca - cex.add_months(global_config().option_as_u32bit("eac/ca/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) - { - cex.add_months(global_config().option_as_u32bit("eac/ca/is_validity_months")); - chat_val = IS | chat_low; - } - else - { - throw Invalid_Argument("sign_request(): encountered illegal value for CHAT"); - // (IS cannot sign certificates) - } - return EAC1_1_CVC_CA::make_cert(pk_signer, enc_public_key, - ASN1_Car(signer_cert.get_chr().iso_8859()), - chr, - chat_val, - ced, - cex); - } - EAC1_1_Req create_cvc_req(Private_Key const& prkey, - ASN1_Chr const& chr, - std::string const& hash_alg) - { - ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&prkey); - if (priv_key == 0) - { - throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type"); - } - ECDSA_PrivateKey key(*priv_key); - key.set_parameter_encoding(ENC_IMPLICITCA); - return Botan::CVC_EAC::create_cvc_req(key, chr, hash_alg); - } +} // namespace DE_EAC - } // namespace DE_EAC - } +} |