summaryrefslogtreecommitdiff
path: root/src/crypto/x509/x509_vpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/x509/x509_vpm.c')
-rw-r--r--src/crypto/x509/x509_vpm.c308
1 files changed, 93 insertions, 215 deletions
diff --git a/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 583b4a05..7314c443 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/crypto/x509/x509_vpm.c
@@ -60,10 +60,8 @@
#include <openssl/obj.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
-#include <openssl/x509v3.h>
#include "../internal.h"
-#include "../x509v3/internal.h"
#include "internal.h"
@@ -74,8 +72,6 @@
static void str_free(char *s) { OPENSSL_free(s); }
-#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
-
static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode,
const char *name, size_t namelen) {
char *copy;
@@ -92,7 +88,7 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode,
}
if (mode == SET_HOST && param->hosts) {
- string_stack_free(param->hosts);
+ sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
param->hosts = NULL;
}
@@ -119,50 +115,12 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode,
return 1;
}
-static void x509_verify_param_zero(X509_VERIFY_PARAM *param) {
- if (!param) {
- return;
- }
- param->name = NULL;
- param->purpose = 0;
- param->trust = 0;
- // param->inh_flags = X509_VP_FLAG_DEFAULT;
- param->inh_flags = 0;
- param->flags = 0;
- param->depth = -1;
- if (param->policies) {
- sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
- param->policies = NULL;
- }
- if (param->hosts) {
- string_stack_free(param->hosts);
- param->hosts = NULL;
- }
- if (param->peername) {
- OPENSSL_free(param->peername);
- param->peername = NULL;
- }
- if (param->email) {
- OPENSSL_free(param->email);
- param->email = NULL;
- param->emaillen = 0;
- }
- if (param->ip) {
- OPENSSL_free(param->ip);
- param->ip = NULL;
- param->iplen = 0;
- }
- param->poison = 0;
-}
-
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) {
- X509_VERIFY_PARAM *param;
- param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
+ X509_VERIFY_PARAM *param = OPENSSL_zalloc(sizeof(X509_VERIFY_PARAM));
if (!param) {
return NULL;
}
- OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM));
- x509_verify_param_zero(param);
+ param->depth = -1;
return param;
}
@@ -170,147 +128,105 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) {
if (param == NULL) {
return;
}
- x509_verify_param_zero(param);
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+ sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
+ OPENSSL_free(param->email);
+ OPENSSL_free(param->ip);
OPENSSL_free(param);
}
-//-
-// This function determines how parameters are "inherited" from one structure
-// to another. There are several different ways this can happen.
-//
-// 1. If a child structure needs to have its values initialized from a parent
-// they are simply copied across. For example SSL_CTX copied to SSL.
-// 2. If the structure should take on values only if they are currently unset.
-// For example the values in an SSL structure will take appropriate value
-// for SSL servers or clients but only if the application has not set new
-// ones.
-//
-// The "inh_flags" field determines how this function behaves.
-//
-// Normally any values which are set in the default are not copied from the
-// destination and verify flags are ORed together.
-//
-// If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
-// to the destination. Effectively the values in "to" become default values
-// which will be used only if nothing new is set in "from".
-//
-// If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
-// they are set or not. Flags is still Ored though.
-//
-// If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
-// of ORed.
-//
-// If X509_VP_FLAG_LOCKED is set then no values are copied.
-//
-// If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
-// after the next call.
-
-// Macro to test if a field should be copied from src to dest
-
-#define test_x509_verify_param_copy(field, def) \
- (to_overwrite || \
- ((src->field != (def)) && (to_default || (dest->field == (def)))))
-
-// Macro to test and copy a field if necessary
-
-#define x509_verify_param_copy(field, def) \
- if (test_x509_verify_param_copy(field, def)) \
- dest->field = src->field
-
-int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
- const X509_VERIFY_PARAM *src) {
- unsigned long inh_flags;
- int to_default, to_overwrite;
- if (!src) {
- return 1;
- }
- inh_flags = dest->inh_flags | src->inh_flags;
-
- if (inh_flags & X509_VP_FLAG_ONCE) {
- dest->inh_flags = 0;
+static int should_copy(int dest_is_set, int src_is_set, int prefer_src) {
+ if (prefer_src) {
+ // We prefer the source, so as long as there is a value to copy, copy it.
+ return src_is_set;
}
- if (inh_flags & X509_VP_FLAG_LOCKED) {
- return 1;
- }
+ // We prefer the destination, so only copy if the destination is unset.
+ return src_is_set && !dest_is_set;
+}
- if (inh_flags & X509_VP_FLAG_DEFAULT) {
- to_default = 1;
- } else {
- to_default = 0;
+static void copy_int_param(int *dest, const int *src, int default_val,
+ int prefer_src) {
+ if (should_copy(*dest != default_val, *src != default_val, prefer_src)) {
+ *dest = *src;
}
+}
- if (inh_flags & X509_VP_FLAG_OVERWRITE) {
- to_overwrite = 1;
- } else {
- to_overwrite = 0;
+// x509_verify_param_copy copies fields from |src| to |dest|. If both |src| and
+// |dest| have some field set, |prefer_src| determines whether |src| or |dest|'s
+// version is used.
+static int x509_verify_param_copy(X509_VERIFY_PARAM *dest,
+ const X509_VERIFY_PARAM *src,
+ int prefer_src) {
+ if (src == NULL) {
+ return 1;
}
- x509_verify_param_copy(purpose, 0);
- x509_verify_param_copy(trust, 0);
- x509_verify_param_copy(depth, -1);
+ copy_int_param(&dest->purpose, &src->purpose, /*default_val=*/0, prefer_src);
+ copy_int_param(&dest->trust, &src->trust, /*default_val=*/0, prefer_src);
+ copy_int_param(&dest->depth, &src->depth, /*default_val=*/-1, prefer_src);
- // If overwrite or check time not set, copy across
-
- if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
+ // |check_time|, unlike all other parameters, does not honor |prefer_src|.
+ // This means |X509_VERIFY_PARAM_set1| will not overwrite it. This behavior
+ // comes from OpenSSL but may have been a bug.
+ if (!(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
dest->check_time = src->check_time;
- dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
- // Don't need to copy flag: that is done below
- }
-
- if (inh_flags & X509_VP_FLAG_RESET_FLAGS) {
- dest->flags = 0;
+ // The source |X509_V_FLAG_USE_CHECK_TIME| flag, if set, is copied below.
}
dest->flags |= src->flags;
- if (test_x509_verify_param_copy(policies, NULL)) {
+ if (should_copy(dest->policies != NULL, src->policies != NULL, prefer_src)) {
if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) {
return 0;
}
}
- // Copy the host flags if and only if we're copying the host list
- if (test_x509_verify_param_copy(hosts, NULL)) {
- if (dest->hosts) {
- string_stack_free(dest->hosts);
- dest->hosts = NULL;
- }
+ if (should_copy(dest->hosts != NULL, src->hosts != NULL, prefer_src)) {
+ sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
+ dest->hosts = NULL;
if (src->hosts) {
dest->hosts =
sk_OPENSSL_STRING_deep_copy(src->hosts, OPENSSL_strdup, str_free);
if (dest->hosts == NULL) {
return 0;
}
+ // Copy the host flags if and only if we're copying the host list. Note
+ // this means mechanisms like |X509_STORE_CTX_set_default| cannot be used
+ // to set host flags. E.g. we cannot change the defaults using
+ // |kDefaultParam| below.
dest->hostflags = src->hostflags;
}
}
- if (test_x509_verify_param_copy(email, NULL)) {
+ if (should_copy(dest->email != NULL, src->email != NULL, prefer_src)) {
if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen)) {
return 0;
}
}
- if (test_x509_verify_param_copy(ip, NULL)) {
+ if (should_copy(dest->ip != NULL, src->ip != NULL, prefer_src)) {
if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) {
return 0;
}
}
dest->poison = src->poison;
-
return 1;
}
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
+ const X509_VERIFY_PARAM *src) {
+ // Prefer the destination. That is, this function only changes unset
+ // parameters in |dest|.
+ return x509_verify_param_copy(dest, src, /*prefer_src=*/0);
+}
+
int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
const X509_VERIFY_PARAM *from) {
- unsigned long save_flags = to->inh_flags;
- int ret;
- to->inh_flags |= X509_VP_FLAG_DEFAULT;
- ret = X509_VERIFY_PARAM_inherit(to, from);
- to->inh_flags = save_flags;
- return ret;
+ // Prefer the source. That is, values in |to| are only preserved if they were
+ // unset in |from|.
+ return x509_verify_param_copy(to, from, /*prefer_src=*/1);
}
static int int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src,
@@ -337,17 +253,6 @@ static int int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src,
return 1;
}
-int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) {
- if (param->name) {
- OPENSSL_free(param->name);
- }
- param->name = OPENSSL_strdup(name);
- if (param->name) {
- return 1;
- }
- return 0;
-}
-
int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) {
param->flags |= flags;
return 1;
@@ -359,7 +264,7 @@ int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
return 1;
}
-unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) {
+unsigned long X509_VERIFY_PARAM_get_flags(const X509_VERIFY_PARAM *param) {
return param->flags;
}
@@ -442,10 +347,6 @@ void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
param->hostflags = flags;
}
-char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) {
- return param->peername;
-}
-
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
size_t emaillen) {
if (OPENSSL_memchr(email, '\0', emaillen) != NULL ||
@@ -484,68 +385,45 @@ int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) {
return param->depth;
}
-const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) {
- return param->name;
-}
-
-#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0, 0
-
-// Default verify parameters: these are used for various applications and can
-// be overridden by the user specified table. NB: the 'name' field *must* be
-// in alphabetical order because it will be searched using OBJ_search.
-
-static const X509_VERIFY_PARAM default_table[] = {
- {(char *)"default", // X509 default parameters
- 0, // Check time
- 0, // internal flags
- X509_V_FLAG_TRUSTED_FIRST, // flags
- 0, // purpose
- 0, // trust
- 100, // depth
- NULL, // policies
- vpm_empty_id},
- {(char *)"pkcs7", // S/MIME sign parameters
- 0, // Check time
- 0, // internal flags
- 0, // flags
- X509_PURPOSE_SMIME_SIGN, // purpose
- X509_TRUST_EMAIL, // trust
- -1, // depth
- NULL, // policies
- vpm_empty_id},
- {(char *)"smime_sign", // S/MIME sign parameters
- 0, // Check time
- 0, // internal flags
- 0, // flags
- X509_PURPOSE_SMIME_SIGN, // purpose
- X509_TRUST_EMAIL, // trust
- -1, // depth
- NULL, // policies
- vpm_empty_id},
- {(char *)"ssl_client", // SSL/TLS client parameters
- 0, // Check time
- 0, // internal flags
- 0, // flags
- X509_PURPOSE_SSL_CLIENT, // purpose
- X509_TRUST_SSL_CLIENT, // trust
- -1, // depth
- NULL, // policies
- vpm_empty_id},
- {(char *)"ssl_server", // SSL/TLS server parameters
- 0, // Check time
- 0, // internal flags
- 0, // flags
- X509_PURPOSE_SSL_SERVER, // purpose
- X509_TRUST_SSL_SERVER, // trust
- -1, // depth
- NULL, // policies
- vpm_empty_id}};
+static const X509_VERIFY_PARAM kDefaultParam = {
+ .flags = X509_V_FLAG_TRUSTED_FIRST,
+ .depth = 100,
+};
+
+static const X509_VERIFY_PARAM kSMIMESignParam = {
+ .purpose = X509_PURPOSE_SMIME_SIGN,
+ .trust = X509_TRUST_EMAIL,
+ .depth = -1,
+};
+
+static const X509_VERIFY_PARAM kSSLClientParam = {
+ .purpose = X509_PURPOSE_SSL_CLIENT,
+ .trust = X509_TRUST_SSL_CLIENT,
+ .depth = -1,
+};
+
+static const X509_VERIFY_PARAM kSSLServerParam = {
+ .purpose = X509_PURPOSE_SSL_SERVER,
+ .trust = X509_TRUST_SSL_SERVER,
+ .depth = -1,
+};
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) {
- for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(default_table); i++) {
- if (strcmp(default_table[i].name, name) == 0) {
- return &default_table[i];
- }
+ if (strcmp(name, "default") == 0) {
+ return &kDefaultParam;
+ }
+ if (strcmp(name, "pkcs7") == 0) {
+ // PKCS#7 and S/MIME signing use the same defaults.
+ return &kSMIMESignParam;
+ }
+ if (strcmp(name, "smime_sign") == 0) {
+ return &kSMIMESignParam;
+ }
+ if (strcmp(name, "ssl_client") == 0) {
+ return &kSSLClientParam;
+ }
+ if (strcmp(name, "ssl_server") == 0) {
+ return &kSSLServerParam;
}
return NULL;
}