summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/x509
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/x509')
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_err.c1
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_lu.c2
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_obj.c26
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_vfy.c121
-rw-r--r--Cryptlib/OpenSSL/crypto/x509/x509_vpm.c19
5 files changed, 108 insertions, 61 deletions
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_err.c b/Cryptlib/OpenSSL/crypto/x509/x509_err.c
index 43cde18e..1e779fef 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_err.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_err.c
@@ -151,6 +151,7 @@ static ERR_STRING_DATA X509_str_reasons[] = {
{ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"},
{ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"},
{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"},
+ {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"},
{ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"},
{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
"no cert set for us to verify"},
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_lu.c b/Cryptlib/OpenSSL/crypto/x509/x509_lu.c
index b0d65390..50120a4d 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_lu.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_lu.c
@@ -536,8 +536,6 @@ STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
X509_OBJECT *obj, xobj;
sk = sk_X509_CRL_new_null();
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
- /* Check cache first */
- idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
/*
* Always do lookup to possibly add new CRLs to cache
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_obj.c b/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
index d317f3af..3de3ac72 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
@@ -63,6 +63,13 @@
#include <openssl/x509.h>
#include <openssl/buffer.h>
+/*
+ * Limit to ensure we don't overflow: much greater than
+ * anything enountered in practice.
+ */
+
+#define NAME_ONELINE_MAX (1024 * 1024)
+
char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
{
X509_NAME_ENTRY *ne;
@@ -86,6 +93,8 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
goto err;
b->data[0] = '\0';
len = 200;
+ } else if (len == 0) {
+ return NULL;
}
if (a == NULL) {
if (b) {
@@ -110,6 +119,10 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
type = ne->value->type;
num = ne->value->length;
+ if (num > NAME_ONELINE_MAX) {
+ X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+ goto end;
+ }
q = ne->value->data;
#ifdef CHARSET_EBCDIC
if (type == V_ASN1_GENERALSTRING ||
@@ -117,8 +130,9 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
type == V_ASN1_PRINTABLESTRING ||
type == V_ASN1_TELETEXSTRING ||
type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) {
- ascii2ebcdic(ebcdic_buf, q, (num > sizeof ebcdic_buf)
- ? sizeof ebcdic_buf : num);
+ if (num > (int)sizeof(ebcdic_buf))
+ num = sizeof(ebcdic_buf);
+ ascii2ebcdic(ebcdic_buf, q, num);
q = ebcdic_buf;
}
#endif
@@ -154,6 +168,10 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
lold = l;
l += 1 + l1 + 1 + l2;
+ if (l > NAME_ONELINE_MAX) {
+ X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+ goto end;
+ }
if (b != NULL) {
if (!BUF_MEM_grow(b, l + 1))
goto err;
@@ -206,7 +224,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
return (p);
err:
X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
- if (b != NULL)
- BUF_MEM_free(b);
+ end:
+ BUF_MEM_free(b);
return (NULL);
}
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c b/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
index c085c134..25e8a89f 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_vfy.c
@@ -194,6 +194,9 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
int num, j, retry;
int (*cb) (int xok, X509_STORE_CTX *xctx);
STACK_OF(X509) *sktmp = NULL;
+ int trust = X509_TRUST_UNTRUSTED;
+ int err;
+
if (ctx->cert == NULL) {
X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
return -1;
@@ -216,7 +219,8 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (((ctx->chain = sk_X509_new_null()) == NULL) ||
(!sk_X509_push(ctx->chain, ctx->cert))) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- goto end;
+ ok = -1;
+ goto err;
}
CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
ctx->last_untrusted = 1;
@@ -225,7 +229,8 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (ctx->untrusted != NULL
&& (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- goto end;
+ ok = -1;
+ goto err;
}
num = sk_X509_num(ctx->chain);
@@ -249,7 +254,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
ok = ctx->get_issuer(&xtmp, ctx, x);
if (ok < 0)
- return ok;
+ goto err;
/*
* If successful for now free up cert so it will be picked up
* again later.
@@ -266,7 +271,8 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (xtmp != NULL) {
if (!sk_X509_push(ctx->chain, xtmp)) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- goto end;
+ ok = -1;
+ goto err;
}
CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
(void)sk_X509_delete_ptr(sktmp, xtmp);
@@ -314,7 +320,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
bad_chain = 1;
ok = cb(0, ctx);
if (!ok)
- goto end;
+ goto err;
} else {
/*
* We have a match: replace certificate with store
@@ -347,24 +353,26 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
ok = ctx->get_issuer(&xtmp, ctx, x);
if (ok < 0)
- return ok;
+ goto err;
if (ok == 0)
break;
x = xtmp;
if (!sk_X509_push(ctx->chain, x)) {
X509_free(xtmp);
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- return 0;
+ ok = -1;
+ goto err;
}
num++;
}
/* we now have our chain, lets check it... */
- i = check_trust(ctx);
+ if ((trust = check_trust(ctx)) == X509_TRUST_REJECTED) {
+ /* Callback already issued */
+ ok = 0;
+ goto err;
+ }
- /* If explicitly rejected error */
- if (i == X509_TRUST_REJECTED)
- goto end;
/*
* If it's not explicitly trusted then check if there is an alternative
* chain that could be used. We only do this if we haven't already
@@ -372,14 +380,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
* chain checking
*/
retry = 0;
- if (i != X509_TRUST_TRUSTED
+ if (trust != X509_TRUST_TRUSTED
&& !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
&& !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
while (j-- > 1) {
xtmp2 = sk_X509_value(ctx->chain, j - 1);
ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
if (ok < 0)
- goto end;
+ goto err;
/* Check if we found an alternate chain */
if (ok > 0) {
/*
@@ -409,7 +417,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
* self signed certificate in which case we've indicated an error already
* and set bad_chain == 1
*/
- if (i != X509_TRUST_TRUSTED && !bad_chain) {
+ if (trust != X509_TRUST_TRUSTED && !bad_chain) {
if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
if (ctx->last_untrusted >= num)
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
@@ -430,26 +438,26 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
bad_chain = 1;
ok = cb(0, ctx);
if (!ok)
- goto end;
+ goto err;
}
/* We have the chain complete: now we need to check its purpose */
ok = check_chain_extensions(ctx);
if (!ok)
- goto end;
+ goto err;
/* Check name constraints */
ok = check_name_constraints(ctx);
if (!ok)
- goto end;
+ goto err;
ok = check_id(ctx);
if (!ok)
- goto end;
+ goto err;
/* We may as well copy down any DSA parameters that are required */
X509_get_pubkey_parameters(NULL, ctx->chain);
@@ -461,16 +469,16 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
ok = ctx->check_revocation(ctx);
if (!ok)
- goto end;
+ goto err;
- i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
- ctx->param->flags);
- if (i != X509_V_OK) {
- ctx->error = i;
+ err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
+ ctx->param->flags);
+ if (err != X509_V_OK) {
+ ctx->error = err;
ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
ok = cb(0, ctx);
if (!ok)
- goto end;
+ goto err;
}
/* At this point, we have a chain and need to verify it */
@@ -479,25 +487,28 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
else
ok = internal_verify(ctx);
if (!ok)
- goto end;
+ goto err;
#ifndef OPENSSL_NO_RFC3779
/* RFC 3779 path validation, now that CRL check has been done */
ok = v3_asid_validate_path(ctx);
if (!ok)
- goto end;
+ goto err;
ok = v3_addr_validate_path(ctx);
if (!ok)
- goto end;
+ goto err;
#endif
/* If we get this far evaluate policies */
if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
ok = ctx->check_policy(ctx);
if (!ok)
- goto end;
+ goto err;
if (0) {
- end:
+ err:
+ /* Ensure we return an error */
+ if (ok > 0)
+ ok = 0;
X509_get_pubkey_parameters(NULL, ctx->chain);
}
if (sktmp != NULL)
@@ -752,6 +763,10 @@ static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
int n = sk_OPENSSL_STRING_num(id->hosts);
char *name;
+ if (id->peername != NULL) {
+ OPENSSL_free(id->peername);
+ id->peername = NULL;
+ }
for (i = 0; i < n; ++i) {
name = sk_OPENSSL_STRING_value(id->hosts, i);
if (X509_check_host(x, name, 0, id->hostflags, &id->peername) > 0)
@@ -935,6 +950,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
ctx->current_crl = crl;
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+ return 1;
else
ptime = NULL;
@@ -1653,15 +1670,13 @@ static int check_policy(X509_STORE_CTX *ctx)
static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
{
-#ifdef OPENSSL_SYS_UEFI
- /* Bypass Certificate Time Checking for UEFI version. */
- return 1;
-#else
time_t *ptime;
int i;
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+ return 1;
else
ptime = NULL;
@@ -1696,7 +1711,6 @@ static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
}
return 1;
-#endif
}
static int internal_verify(X509_STORE_CTX *ctx)
@@ -2283,9 +2297,10 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
ctx->current_reasons = 0;
ctx->tree = NULL;
ctx->parent = NULL;
+ /* Zero ex_data to make sure we're cleanup-safe */
+ memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
ctx->param = X509_VERIFY_PARAM_new();
-
if (!ctx->param) {
X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
return 0;
@@ -2294,7 +2309,6 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
/*
* Inherit callbacks and flags from X509_STORE if not set use defaults.
*/
-
if (store)
ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
else
@@ -2302,6 +2316,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
if (store) {
ctx->verify_cb = store->verify_cb;
+ /* Seems to always be 0 in OpenSSL, else must be idempotent */
ctx->cleanup = store->cleanup;
} else
ctx->cleanup = 0;
@@ -2312,7 +2327,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
if (ret == 0) {
X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
- return 0;
+ goto err;
}
if (store && store->check_issued)
@@ -2367,19 +2382,18 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
ctx->check_policy = check_policy;
+ if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
+ &ctx->ex_data))
+ return 1;
+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+
+ err:
/*
- * This memset() can't make any sense anyway, so it's removed. As
- * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
- * corresponding "new" here and remove this bogus initialisation.
+ * On error clean up allocated storage, if the store context was not
+ * allocated with X509_STORE_CTX_new() this is our last chance to do so.
*/
- /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
- if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
- &(ctx->ex_data))) {
- OPENSSL_free(ctx);
- X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- return 1;
+ X509_STORE_CTX_cleanup(ctx);
+ return 0;
}
/*
@@ -2395,8 +2409,17 @@ void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
{
- if (ctx->cleanup)
+ /*
+ * We need to be idempotent because, unfortunately, free() also calls
+ * cleanup(), so the natural call sequence new(), init(), cleanup(), free()
+ * calls cleanup() for the same object twice! Thus we must zero the
+ * pointers below after they're freed!
+ */
+ /* Seems to always be 0 in OpenSSL, do this at most once. */
+ if (ctx->cleanup != NULL) {
ctx->cleanup(ctx);
+ ctx->cleanup = NULL;
+ }
if (ctx->param != NULL) {
if (ctx->parent == NULL)
X509_VERIFY_PARAM_free(ctx->param);
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c b/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c
index 1ea0c69f..1ac15a88 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_vpm.c
@@ -94,11 +94,11 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
* Refuse names with embedded NUL bytes, except perhaps as final byte.
* XXX: Do we need to push an error onto the error stack?
*/
- if (namelen == 0)
+ if (namelen == 0 || name == NULL)
namelen = name ? strlen(name) : 0;
else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen))
return 0;
- if (name && name[namelen - 1] == '\0')
+ if (namelen > 0 && name[namelen - 1] == '\0')
--namelen;
if (mode == SET_HOST && id->hosts) {
@@ -155,6 +155,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
}
if (paramid->peername)
OPENSSL_free(paramid->peername);
+ paramid->peername = NULL;
if (paramid->email) {
OPENSSL_free(paramid->email);
paramid->email = NULL;
@@ -165,7 +166,6 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
paramid->ip = NULL;
paramid->iplen = 0;
}
-
}
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
@@ -176,13 +176,20 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
param = OPENSSL_malloc(sizeof *param);
if (!param)
return NULL;
- paramid = OPENSSL_malloc(sizeof *paramid);
+ memset(param, 0, sizeof(*param));
+
+ paramid = OPENSSL_malloc(sizeof(*paramid));
if (!paramid) {
OPENSSL_free(param);
return NULL;
}
- memset(param, 0, sizeof *param);
- memset(paramid, 0, sizeof *paramid);
+ memset(paramid, 0, sizeof(*paramid));
+ /* Exotic platforms may have non-zero bit representation of NULL */
+ paramid->hosts = NULL;
+ paramid->peername = NULL;
+ paramid->email = NULL;
+ paramid->ip = NULL;
+
param->id = paramid;
x509_verify_param_zero(param);
return param;