diff options
Diffstat (limited to 'src/lib/cert')
-rw-r--r-- | src/lib/cert/x509/key_constraint.cpp | 30 | ||||
-rw-r--r-- | src/lib/cert/x509/key_constraint.h | 16 | ||||
-rw-r--r-- | src/lib/cert/x509/x509_ca.cpp | 10 | ||||
-rw-r--r-- | src/lib/cert/x509/x509self.cpp | 35 |
4 files changed, 59 insertions, 32 deletions
diff --git a/src/lib/cert/x509/key_constraint.cpp b/src/lib/cert/x509/key_constraint.cpp index f10105f91..a90af013c 100644 --- a/src/lib/cert/x509/key_constraint.cpp +++ b/src/lib/cert/x509/key_constraint.cpp @@ -12,29 +12,35 @@ namespace Botan { /* -* Find the allowable key constraints +* Make sure the given key constraints are permitted for the given key type */ -Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits) +void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key, + Key_Constraints constraints) { const std::string name = pub_key.algo_name(); - size_t constraints = 0; + size_t permitted = 0; if(name == "DH" || name == "ECDH") - constraints |= KEY_AGREEMENT; + { + permitted |= KEY_AGREEMENT | ENCIPHER_ONLY | DECIPHER_ONLY; + } if(name == "RSA" || name == "ElGamal") - constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT | ENCIPHER_ONLY | DECIPHER_ONLY; + { + permitted |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; + } if(name == "RSA" || name == "RW" || name == "NR" || name == "DSA" || name == "ECDSA" || name == "ECGDSA" || name == "ECKCDSA") - constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION | KEY_CERT_SIGN | CRL_SIGN; - - if(limits) - constraints &= limits; - - return Key_Constraints(constraints); + { + permitted |= DIGITAL_SIGNATURE | NON_REPUDIATION | KEY_CERT_SIGN | CRL_SIGN; + } + + if ( ( constraints & permitted ) != constraints ) + { + throw Exception("Constraint not permitted for key type " + name); + } } } diff --git a/src/lib/cert/x509/key_constraint.h b/src/lib/cert/x509/key_constraint.h index 7ae4e26bd..b67eb7010 100644 --- a/src/lib/cert/x509/key_constraint.h +++ b/src/lib/cert/x509/key_constraint.h @@ -33,17 +33,13 @@ enum Key_Constraints { class Public_Key; /** -* Create the key constraints for a specific public key. -* @param pub_key the public key from which the basic set of -* constraints to be placed in the return value is derived -* @param limits additional limits that will be incorporated into the -* return value -* @return combination of key type specific constraints and -* additional limits +* Check that key constraints are permitted for a specific public key. +* @param pub_key the public key on which the constraints shall be enforced on +* @param constrains the constraints that shall be enforced on the key +* @throw Exception if the given constraints are not permitted for this key */ - -BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits); +BOTAN_DLL void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key, + Key_Constraints constraints); } diff --git a/src/lib/cert/x509/x509_ca.cpp b/src/lib/cert/x509/x509_ca.cpp index d64ade6cd..58c6676f4 100644 --- a/src/lib/cert/x509/x509_ca.cpp +++ b/src/lib/cert/x509/x509_ca.cpp @@ -52,11 +52,14 @@ X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, { Key_Constraints constraints; if(req.is_CA()) + { constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); + } else { std::unique_ptr<Public_Key> key(req.subject_public_key()); - constraints = find_constraints(*key, req.constraints()); + verify_cert_constraints_valid_for_key_type(*key, req.constraints()); + constraints = req.constraints(); } Extensions extensions; @@ -65,7 +68,10 @@ X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, new Cert_Extension::Basic_Constraints(req.is_CA(), req.path_limit()), true); - extensions.add(new Cert_Extension::Key_Usage(constraints), true); + if(constraints != NO_CONSTRAINTS) + { + extensions.add(new Cert_Extension::Key_Usage(constraints), true); + } extensions.add(new Cert_Extension::Authority_Key_ID(m_cert.subject_key_id())); extensions.add(new Cert_Extension::Subject_Key_ID(req.raw_public_key())); diff --git a/src/lib/cert/x509/x509self.cpp b/src/lib/cert/x509/x509self.cpp index 8b9aeda09..102e24f77 100644 --- a/src/lib/cert/x509/x509self.cpp +++ b/src/lib/cert/x509/x509self.cpp @@ -55,9 +55,14 @@ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, Key_Constraints constraints; if(opts.is_CA) + { constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); + } else - constraints = find_constraints(key, opts.constraints); + { + verify_cert_constraints_valid_for_key_type(key, opts.constraints); + constraints = opts.constraints; + } Extensions extensions; @@ -65,7 +70,10 @@ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit), true); - extensions.add(new Cert_Extension::Key_Usage(constraints), true); + if(constraints != NO_CONSTRAINTS) + { + extensions.add(new Cert_Extension::Key_Usage(constraints), true); + } extensions.add(new Cert_Extension::Subject_Key_ID(pub_key)); @@ -99,16 +107,27 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, const size_t PKCS10_VERSION = 0; + Key_Constraints constraints; + if(opts.is_CA) + { + constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); + } + else + { + verify_cert_constraints_valid_for_key_type(key, opts.constraints); + constraints = opts.constraints; + } + Extensions extensions; extensions.add( new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit)); - extensions.add( - new Cert_Extension::Key_Usage( - opts.is_CA ? Key_Constraints(KEY_CERT_SIGN | CRL_SIGN) : - find_constraints(key, opts.constraints) - ) - ); + + if(constraints != NO_CONSTRAINTS) + { + extensions.add( + new Cert_Extension::Key_Usage(constraints)); + } extensions.add( new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); extensions.add( |