The unified diff between revisions [3f5f3a8d..] and [48b49b84..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'src/x509_ca.cpp'

#
#
# patch "src/x509_ca.cpp"
#  from [64667c8412d11d40437a32433158122e750c4508]
#    to [be4d6707e41b77daaa91d7cb8c421ca6e16c19a8]
#
============================================================
--- src/x509_ca.cpp	64667c8412d11d40437a32433158122e750c4508
+++ src/x509_ca.cpp	be4d6707e41b77daaa91d7cb8c421ca6e16c19a8
@@ -1,6 +1,6 @@
 /*************************************************
 * X.509 Certificate Authority Source File        *
-* (C) 1999-2006 The Botan Project                *
+* (C) 1999-2008 Jack Lloyd                       *
 *************************************************/

 #include <botan/x509_ca.h>
@@ -11,10 +11,12 @@
 #include <botan/lookup.h>
 #include <botan/look_pk.h>
 #include <botan/numthry.h>
+#include <botan/libstate.h>
 #include <botan/oids.h>
 #include <botan/util.h>
 #include <algorithm>
 #include <typeinfo>
+#include <iterator>
 #include <memory>
 #include <set>

@@ -24,42 +26,31 @@ X509_CA::X509_CA(const X509_Certificate&
 * Load the certificate and private key           *
 *************************************************/
 X509_CA::X509_CA(const X509_Certificate& c,
-                 const PKCS8_PrivateKey& key) : cert(c)
+                 const Private_Key& key) : cert(c)
    {
-   const PKCS8_PrivateKey* key_pointer = &key;
+   const Private_Key* key_pointer = &key;
    if(!dynamic_cast<const PK_Signing_Key*>(key_pointer))
       throw Invalid_Argument("X509_CA: " + key.algo_name() + " cannot sign");

    if(!cert.is_CA_cert())
       throw Invalid_Argument("X509_CA: This certificate is not for a CA");

-   std::string padding;
-   Signature_Format format;
-
-   Config::choose_sig_format(key.algo_name(), padding, format);
-
-   ca_sig_algo.oid = OIDS::lookup(key.algo_name() + "/" + padding);
-   ca_sig_algo.parameters = key.DER_encode_params();
-
-   const PK_Signing_Key& sig_key = dynamic_cast<const PK_Signing_Key&>(key);
-   signer = get_pk_signer(sig_key, padding, format);
+   signer = choose_sig_format(key, ca_sig_algo);
    }

 /*************************************************
 * Sign a PKCS #10 certificate request            *
 *************************************************/
 X509_Certificate X509_CA::sign_request(const PKCS10_Request& req,
-                                       u32bit expire_time) const
+                                       const X509_Time& not_before,
+                                       const X509_Time& not_after)
    {
-   if(req.is_CA() && !global_config().option_as_bool("x509/ca/allow_ca"))
-      throw Policy_Violation("X509_CA: Attempted to sign new CA certificate");
-
    Key_Constraints constraints;
    if(req.is_CA())
       constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
    else
       {
-      std::auto_ptr<X509_PublicKey> key(req.subject_public_key());
+      std::auto_ptr<Public_Key> key(req.subject_public_key());
       constraints = X509::find_constraints(*key, req.constraints());
       }

@@ -78,19 +69,8 @@ X509_Certificate X509_CA::sign_request(c
    extensions.add(
       new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name()));

-   /*
-   extensions.add(
-      new Cert_Extension::Issuer_Alternative_Name(issuer_alt));
-   */
-
-   if(expire_time == 0)
-      expire_time = global_config().option_as_time("x509/ca/default_expire");
-
-   const u64bit current_time = system_time();
-
    return make_cert(signer, ca_sig_algo, req.raw_public_key(),
-                    X509_Time(current_time),
-                    X509_Time(current_time + expire_time),
+                    not_before, not_after,
                     cert.subject_dn(), req.subject_dn(),
                     extensions);
    }
@@ -249,4 +229,50 @@ X509_CA::~X509_CA()
    delete signer;
    }

+/*************************************************
+* Choose a signing format for the key            *
+*************************************************/
+PK_Signer* choose_sig_format(const Private_Key& key,
+                             AlgorithmIdentifier& sig_algo)
+   {
+   std::string padding;
+   Signature_Format format;
+
+   const std::string algo_name = key.algo_name();
+
+   if(algo_name == "RSA")
+      {
+      std::string hash = global_config().option("x509/ca/rsa_hash");
+
+      if(hash == "")
+         throw Invalid_State("No value set for x509/ca/rsa_hash");
+
+      hash = global_config().deref_alias(hash);
+
+      padding = "EMSA3(" + hash + ")";
+      format = IEEE_1363;
+      }
+   else if(algo_name == "DSA")
+      {
+      std::string hash = global_config().deref_alias("SHA-1");
+      padding = "EMSA1(" + hash + ")";
+      format = DER_SEQUENCE;
+      }
+   else
+      throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name);
+
+   sig_algo.oid = OIDS::lookup(algo_name + "/" + padding);
+
+   std::auto_ptr<X509_Encoder> encoding(key.x509_encoder());
+   if(!encoding.get())
+      throw Encoding_Error("Key " + algo_name + " does not support "
+                           "X.509 encoding");
+
+   sig_algo.parameters = encoding->alg_id().parameters;
+
+   const PK_Signing_Key& sig_key = dynamic_cast<const PK_Signing_Key&>(key);
+
+   return get_pk_signer(sig_key, padding, format);
+   }
+
 }