aboutsummaryrefslogtreecommitdiffstats
path: root/src/cert/cvc/cvc_self.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cert/cvc/cvc_self.cpp')
-rw-r--r--src/cert/cvc/cvc_self.cpp194
1 files changed, 95 insertions, 99 deletions
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