aboutsummaryrefslogtreecommitdiffstats
path: root/src/x509_ca.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/x509_ca.cpp')
-rw-r--r--src/x509_ca.cpp147
1 files changed, 73 insertions, 74 deletions
diff --git a/src/x509_ca.cpp b/src/x509_ca.cpp
index eed733f17..3600843d3 100644
--- a/src/x509_ca.cpp
+++ b/src/x509_ca.cpp
@@ -6,6 +6,8 @@
#include <botan/x509_ca.h>
#include <botan/x509_ext.h>
#include <botan/x509stor.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
#include <botan/conf.h>
#include <botan/lookup.h>
#include <botan/look_pk.h>
@@ -13,11 +15,29 @@
#include <botan/oids.h>
#include <botan/util.h>
#include <algorithm>
+#include <typeinfo>
#include <memory>
#include <set>
namespace Botan {
+namespace {
+
+// FIXME: move elsewhere
+MemoryVector<byte> make_signed(PK_Signer* signer,
+ const AlgorithmIdentifier& sig_algo,
+ const MemoryRegion<byte>& tbs_bits)
+ {
+ return DER_Encoder().start_cons(SEQUENCE)
+ .raw_bytes(tbs_bits)
+ .encode(sig_algo)
+ .encode(signer->sign_message(tbs_bits), BIT_STRING)
+ .end_cons()
+ .get_contents();
+ }
+
+}
+
/*************************************************
* Load the certificate and private key *
*************************************************/
@@ -28,8 +48,11 @@ X509_CA::X509_CA(const X509_Certificate& c,
if(!dynamic_cast<const PK_Signing_Key*>(key_pointer))
throw Invalid_Argument("X509_CA: " + key.algo_name() + " cannot sign");
+#if 0
+ // FIXME!
if(!cert.is_CA_cert())
throw Invalid_Argument("X509_CA: This certificate is not for a CA");
+#endif
std::string padding;
Signature_Format format;
@@ -93,11 +116,9 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer,
Key_Constraints constraints,
const std::vector<OID>& ex_constraints)
{
- const u32bit X509_CERT_VERSION = 2;
- const u32bit SERIAL_BITS = 128;
-
Extensions extensions;
+ // POLICY: which extensions
extensions.add(new Cert_Extension::Subject_Key_ID(pub_key));
extensions.add(new Cert_Extension::Authority_Key_ID(auth_key_id));
@@ -120,41 +141,35 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer,
"issuer_alternative_name")
);
- MemoryVector<byte> tbs_bits =
- DER_Encoder().start_sequence()
- .start_explicit(ASN1_Tag(0))
- .encode(X509_CERT_VERSION)
- .end_explicit(ASN1_Tag(0))
-
- .encode(random_integer(SERIAL_BITS))
- .encode(sig_algo)
- .encode(issuer_dn)
-
- .start_sequence()
- .encode(not_before)
- .encode(not_after)
- .end_sequence()
-
- .encode(subject_dn)
- .add_raw_octets(pub_key)
-
- .start_explicit(ASN1_Tag(3))
- .start_sequence()
- .encode(extensions)
- .end_sequence()
- .end_explicit(ASN1_Tag(3))
- .end_sequence()
- .get_contents();
-
- DataSource_Memory source(
- DER_Encoder()
- .start_sequence()
- .add_raw_octets(tbs_bits)
+ const u32bit X509_CERT_VERSION = 3;
+ const u32bit SERIAL_BITS = 128;
+
+ DataSource_Memory source(make_signed(signer, sig_algo,
+ DER_Encoder().start_cons(SEQUENCE)
+ .start_explicit(0)
+ .encode(X509_CERT_VERSION-1)
+ .end_explicit()
+
+ .encode(random_integer(SERIAL_BITS))
.encode(sig_algo)
- .encode(signer->sign_message(tbs_bits), BIT_STRING)
- .end_sequence()
+ .encode(issuer_dn)
+
+ .start_cons(SEQUENCE)
+ .encode(not_before)
+ .encode(not_after)
+ .end_cons()
+
+ .encode(subject_dn)
+ .raw_bytes(pub_key)
+
+ .start_explicit(3)
+ .start_cons(SEQUENCE)
+ .encode(extensions)
+ .end_cons()
+ .end_explicit()
+ .end_cons()
.get_contents()
- );
+ ));
return X509_Certificate(source);
}
@@ -215,7 +230,7 @@ X509_CRL X509_CA::update_crl(const X509_CRL& crl,
X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked,
u32bit crl_number, u32bit next_update) const
{
- const u32bit X509_CRL_VERSION = 1;
+ const u32bit X509_CRL_VERSION = 2;
if(next_update == 0)
next_update = Config::get_time("x509/crl/next_update");
@@ -223,47 +238,31 @@ X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked,
const u64bit current_time = system_time();
Extensions extensions;
- extensions.add(new Cert_Extension::Authority_Key_ID(cert.subject_key_id()));
+ extensions.add(
+ new Cert_Extension::Authority_Key_ID(cert.subject_key_id()));
extensions.add(new Cert_Extension::CRL_Number(crl_number));
- DER_Encoder tbs_crl;
-
- tbs_crl
- .start_sequence()
- .encode(X509_CRL_VERSION)
- .encode(ca_sig_algo)
- .encode(cert.subject_dn())
- .encode(X509_Time(current_time))
- .encode(X509_Time(current_time + next_update));
-
- if(revoked.size())
- {
- tbs_crl.start_sequence();
- for(u32bit j = 0; j != revoked.size(); ++j)
- DER::encode(tbs_crl, revoked[j]);
- tbs_crl.end_sequence();
- }
-
- tbs_crl
- .start_explicit(ASN1_Tag(0))
- .start_sequence()
- .encode(extensions)
- .end_sequence()
- .end_explicit(ASN1_Tag(0))
- .end_sequence();
-
- MemoryVector<byte> tbs_bits = tbs_crl.get_contents();
- MemoryVector<byte> sig = signer->sign_message(tbs_bits);
-
- DataSource_Memory source(
- DER_Encoder()
- .start_sequence()
- .add_raw_octets(tbs_bits)
+ DataSource_Memory source(make_signed(signer, ca_sig_algo,
+ DER_Encoder().start_cons(SEQUENCE)
+ .encode(X509_CRL_VERSION-1)
.encode(ca_sig_algo)
- .encode(sig, BIT_STRING)
- .end_sequence()
+ .encode(cert.issuer_dn())
+ .encode(X509_Time(current_time))
+ .encode(X509_Time(current_time + next_update))
+ .encode_if(revoked.size() > 0,
+ DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode_list(revoked)
+ .end_cons()
+ )
+ .start_explicit(0)
+ .start_cons(SEQUENCE)
+ .encode(extensions)
+ .end_cons()
+ .end_explicit()
+ .end_cons()
.get_contents()
- );
+ ));
return X509_CRL(source);
}