Botan
1.11.15
|
00001 /* 00002 * X.509 Certificate Authority 00003 * (C) 1999-2010 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/x509_ca.h> 00009 #include <botan/pubkey.h> 00010 #include <botan/der_enc.h> 00011 #include <botan/ber_dec.h> 00012 #include <botan/bigint.h> 00013 #include <botan/parsing.h> 00014 #include <botan/lookup.h> 00015 #include <botan/oids.h> 00016 #include <botan/hash.h> 00017 #include <botan/key_constraint.h> 00018 #include <algorithm> 00019 #include <typeinfo> 00020 #include <iterator> 00021 #include <set> 00022 00023 namespace Botan { 00024 00025 /* 00026 * Load the certificate and private key 00027 */ 00028 X509_CA::X509_CA(const X509_Certificate& c, 00029 const Private_Key& key, 00030 const std::string& hash_fn) : cert(c) 00031 { 00032 if(!cert.is_CA_cert()) 00033 throw Invalid_Argument("X509_CA: This certificate is not for a CA"); 00034 00035 signer = choose_sig_format(key, hash_fn, ca_sig_algo); 00036 } 00037 00038 /* 00039 * X509_CA Destructor 00040 */ 00041 X509_CA::~X509_CA() 00042 { 00043 delete signer; 00044 } 00045 00046 /* 00047 * Sign a PKCS #10 certificate request 00048 */ 00049 X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, 00050 RandomNumberGenerator& rng, 00051 const X509_Time& not_before, 00052 const X509_Time& not_after) 00053 { 00054 Key_Constraints constraints; 00055 if(req.is_CA()) 00056 constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); 00057 else 00058 { 00059 std::unique_ptr<Public_Key> key(req.subject_public_key()); 00060 constraints = find_constraints(*key, req.constraints()); 00061 } 00062 00063 Extensions extensions; 00064 00065 extensions.add( 00066 new Cert_Extension::Basic_Constraints(req.is_CA(), req.path_limit()), 00067 true); 00068 00069 extensions.add(new Cert_Extension::Key_Usage(constraints), true); 00070 00071 extensions.add(new Cert_Extension::Authority_Key_ID(cert.subject_key_id())); 00072 extensions.add(new Cert_Extension::Subject_Key_ID(req.raw_public_key())); 00073 00074 extensions.add( 00075 new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name())); 00076 00077 extensions.add( 00078 new Cert_Extension::Extended_Key_Usage(req.ex_constraints())); 00079 00080 return make_cert(signer, rng, ca_sig_algo, 00081 req.raw_public_key(), 00082 not_before, not_after, 00083 cert.subject_dn(), req.subject_dn(), 00084 extensions); 00085 } 00086 00087 /* 00088 * Create a new certificate 00089 */ 00090 X509_Certificate X509_CA::make_cert(PK_Signer* signer, 00091 RandomNumberGenerator& rng, 00092 const AlgorithmIdentifier& sig_algo, 00093 const std::vector<byte>& pub_key, 00094 const X509_Time& not_before, 00095 const X509_Time& not_after, 00096 const X509_DN& issuer_dn, 00097 const X509_DN& subject_dn, 00098 const Extensions& extensions) 00099 { 00100 const size_t X509_CERT_VERSION = 3; 00101 const size_t SERIAL_BITS = 128; 00102 00103 BigInt serial_no(rng, SERIAL_BITS); 00104 00105 return X509_Certificate(X509_Object::make_signed( 00106 signer, rng, sig_algo, 00107 DER_Encoder().start_cons(SEQUENCE) 00108 .start_explicit(0) 00109 .encode(X509_CERT_VERSION-1) 00110 .end_explicit() 00111 00112 .encode(serial_no) 00113 00114 .encode(sig_algo) 00115 .encode(issuer_dn) 00116 00117 .start_cons(SEQUENCE) 00118 .encode(not_before) 00119 .encode(not_after) 00120 .end_cons() 00121 00122 .encode(subject_dn) 00123 .raw_bytes(pub_key) 00124 00125 .start_explicit(3) 00126 .start_cons(SEQUENCE) 00127 .encode(extensions) 00128 .end_cons() 00129 .end_explicit() 00130 .end_cons() 00131 .get_contents() 00132 ));; 00133 } 00134 00135 /* 00136 * Create a new, empty CRL 00137 */ 00138 X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng, 00139 u32bit next_update) const 00140 { 00141 std::vector<CRL_Entry> empty; 00142 return make_crl(empty, 1, next_update, rng); 00143 } 00144 00145 /* 00146 * Update a CRL with new entries 00147 */ 00148 X509_CRL X509_CA::update_crl(const X509_CRL& crl, 00149 const std::vector<CRL_Entry>& new_revoked, 00150 RandomNumberGenerator& rng, 00151 u32bit next_update) const 00152 { 00153 std::vector<CRL_Entry> revoked = crl.get_revoked(); 00154 00155 std::copy(new_revoked.begin(), new_revoked.end(), 00156 std::back_inserter(revoked)); 00157 00158 return make_crl(revoked, crl.crl_number() + 1, next_update, rng); 00159 } 00160 00161 /* 00162 * Create a CRL 00163 */ 00164 X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked, 00165 u32bit crl_number, u32bit next_update, 00166 RandomNumberGenerator& rng) const 00167 { 00168 const size_t X509_CRL_VERSION = 2; 00169 00170 if(next_update == 0) 00171 next_update = timespec_to_u32bit("7d"); 00172 00173 // Totally stupid: ties encoding logic to the return of std::time!! 00174 auto current_time = std::chrono::system_clock::now(); 00175 auto expire_time = current_time + std::chrono::seconds(next_update); 00176 00177 Extensions extensions; 00178 extensions.add( 00179 new Cert_Extension::Authority_Key_ID(cert.subject_key_id())); 00180 extensions.add(new Cert_Extension::CRL_Number(crl_number)); 00181 00182 const std::vector<byte> crl = X509_Object::make_signed( 00183 signer, rng, ca_sig_algo, 00184 DER_Encoder().start_cons(SEQUENCE) 00185 .encode(X509_CRL_VERSION-1) 00186 .encode(ca_sig_algo) 00187 .encode(cert.issuer_dn()) 00188 .encode(X509_Time(current_time)) 00189 .encode(X509_Time(expire_time)) 00190 .encode_if(revoked.size() > 0, 00191 DER_Encoder() 00192 .start_cons(SEQUENCE) 00193 .encode_list(revoked) 00194 .end_cons() 00195 ) 00196 .start_explicit(0) 00197 .start_cons(SEQUENCE) 00198 .encode(extensions) 00199 .end_cons() 00200 .end_explicit() 00201 .end_cons() 00202 .get_contents()); 00203 00204 return X509_CRL(crl); 00205 } 00206 00207 /* 00208 * Return the CA's certificate 00209 */ 00210 X509_Certificate X509_CA::ca_certificate() const 00211 { 00212 return cert; 00213 } 00214 00215 /* 00216 * Choose a signing format for the key 00217 */ 00218 PK_Signer* choose_sig_format(const Private_Key& key, 00219 const std::string& hash_fn, 00220 AlgorithmIdentifier& sig_algo) 00221 { 00222 const std::string algo_name = key.algo_name(); 00223 00224 std::unique_ptr<HashFunction> hash(get_hash(hash_fn)); 00225 if(!hash) 00226 throw Algorithm_Not_Found(hash_fn); 00227 00228 if(key.max_input_bits() < hash->output_length() * 8) 00229 throw Invalid_Argument("Key is too small for chosen hash function"); 00230 00231 std::string padding; 00232 if(algo_name == "RSA") 00233 padding = "EMSA3"; 00234 else if(algo_name == "DSA") 00235 padding = "EMSA1"; 00236 else if(algo_name == "ECDSA") 00237 padding = "EMSA1_BSI"; 00238 else 00239 throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name); 00240 00241 const Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363; 00242 00243 padding = padding + '(' + hash->name() + ')'; 00244 00245 sig_algo.oid = OIDS::lookup(algo_name + "/" + padding); 00246 sig_algo.parameters = key.algorithm_identifier().parameters; 00247 00248 return new PK_Signer(key, padding, format); 00249 } 00250 00251 }