aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/cert
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/cert')
-rw-r--r--src/lib/cert/x509/key_constraint.cpp30
-rw-r--r--src/lib/cert/x509/key_constraint.h16
-rw-r--r--src/lib/cert/x509/x509_ca.cpp10
-rw-r--r--src/lib/cert/x509/x509self.cpp35
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(