aboutsummaryrefslogtreecommitdiffstats
path: root/src/cert/cvc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cert/cvc')
-rw-r--r--src/cert/cvc/cvc_ado.cpp10
-rw-r--r--src/cert/cvc/cvc_ado.h5
-rw-r--r--src/cert/cvc/cvc_ca.cpp44
-rw-r--r--src/cert/cvc/cvc_ca.h51
-rw-r--r--src/cert/cvc/cvc_cert.cpp65
-rw-r--r--src/cert/cvc/cvc_cert.h37
-rw-r--r--src/cert/cvc/cvc_gen_cert.h27
-rw-r--r--src/cert/cvc/cvc_key.h53
-rw-r--r--src/cert/cvc/cvc_req.cpp18
-rw-r--r--src/cert/cvc/cvc_req.h5
-rw-r--r--src/cert/cvc/cvc_self.cpp194
-rw-r--r--src/cert/cvc/eac_asn_obj.h5
-rw-r--r--src/cert/cvc/eac_obj.h112
-rw-r--r--src/cert/cvc/ecdsa_sig.cpp50
-rw-r--r--src/cert/cvc/ecdsa_sig.h62
-rw-r--r--src/cert/cvc/info.txt4
-rw-r--r--src/cert/cvc/signed_obj.cpp41
-rw-r--r--src/cert/cvc/signed_obj.h3
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.