diff options
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 - } +} |