early-access version 2698

This commit is contained in:
pineappleEA
2022-04-24 22:29:35 +02:00
parent c96f949832
commit caa0c2911b
486 changed files with 37806 additions and 14362 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: by_dir.c,v 1.39 2018/08/05 14:17:12 bcook Exp $ */
/* $OpenBSD: by_dir.c,v 1.41 2021/11/10 14:34:21 schwarze Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.]
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
@@ -67,10 +68,9 @@
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
# include <sys/stat.h>
#include "x509_lcl.h"
typedef struct lookup_dir_hashes_st {
unsigned long hash;
@@ -115,7 +115,7 @@ static X509_LOOKUP_METHOD x509_dir_lookup = {
X509_LOOKUP_METHOD *
X509_LOOKUP_hash_dir(void)
{
return (&x509_dir_lookup);
return &x509_dir_lookup;
}
static int
@@ -139,7 +139,7 @@ dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
ret = add_cert_dir(ld, argp, (int)argl);
break;
}
return (ret);
return ret;
}
static int
@@ -147,15 +147,18 @@ new_dir(X509_LOOKUP *lu)
{
BY_DIR *a;
if ((a = malloc(sizeof(BY_DIR))) == NULL)
return (0);
if ((a = malloc(sizeof(*a))) == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
if ((a->buffer = BUF_MEM_new()) == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
free(a);
return (0);
return 0;
}
a->dirs = NULL;
lu->method_data = (char *)a;
return (1);
return 1;
}
static void
@@ -179,8 +182,7 @@ static void
by_dir_entry_free(BY_DIR_ENTRY *ent)
{
free(ent->dir);
if (ent->hashes)
sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
free(ent);
}
@@ -190,10 +192,8 @@ free_dir(X509_LOOKUP *lu)
BY_DIR *a;
a = (BY_DIR *)lu->method_data;
if (a->dirs != NULL)
sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
if (a->buffer != NULL)
BUF_MEM_free(a->buffer);
sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
BUF_MEM_free(a->buffer);
free(a);
}
@@ -214,6 +214,7 @@ add_cert_dir(BY_DIR *ctx, const char *dir, int type)
do {
if ((*p == ':') || (*p == '\0')) {
BY_DIR_ENTRY *ent;
ss = s;
s = p + 1;
len = p - ss;
@@ -229,20 +230,20 @@ add_cert_dir(BY_DIR *ctx, const char *dir, int type)
continue;
if (ctx->dirs == NULL) {
ctx->dirs = sk_BY_DIR_ENTRY_new_null();
if (!ctx->dirs) {
if (ctx->dirs == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
}
ent = malloc(sizeof(BY_DIR_ENTRY));
if (!ent) {
ent = malloc(sizeof(*ent));
if (ent == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
ent->dir_type = type;
ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
ent->dir = strndup(ss, (size_t)len);
if (!ent->dir || !ent->hashes) {
if (ent->dir == NULL || ent->hashes == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
by_dir_entry_free(ent);
return 0;
@@ -280,7 +281,7 @@ get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
const char *postfix="";
if (name == NULL)
return (0);
return 0;
stmp.type = type;
if (type == X509_LU_X509) {
@@ -310,6 +311,7 @@ get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
BY_DIR_ENTRY *ent;
int idx;
BY_DIR_HASH htmp, *hent;
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
if (!BUF_MEM_grow(b, j)) {
@@ -358,10 +360,7 @@ get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
/* we have added it to the cache so now pull it out again */
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
if (j != -1)
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
else
tmp = NULL;
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
/* If a CRL, update the last file suffix added for this */
@@ -371,16 +370,14 @@ get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
* Look for entry again in case another thread added
* an entry first.
*/
if (!hent) {
if (hent == NULL) {
htmp.hash = h;
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
if (idx >= 0)
hent = sk_BY_DIR_HASH_value(
ent->hashes, idx);
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
}
if (!hent) {
hent = malloc(sizeof(BY_DIR_HASH));
if (!hent) {
if (hent == NULL) {
hent = malloc(sizeof(*hent));
if (hent == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
ok = 0;
@@ -406,17 +403,10 @@ get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
ok = 1;
ret->type = tmp->type;
memcpy(&ret->data, &tmp->data, sizeof(ret->data));
/*
* If we were going to up the reference count,
* we would need to do it on a perl 'type' basis
*/
/* CRYPTO_add(&tmp->data.x509->references,1,
CRYPTO_LOCK_X509);*/
goto finish;
}
}
finish:
if (b != NULL)
BUF_MEM_free(b);
return (ok);
BUF_MEM_free(b);
return ok;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: by_file.c,v 1.21 2017/01/29 17:49:23 beck Exp $ */
/* $OpenBSD: by_file.c,v 1.25 2021/11/10 13:57:42 schwarze Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -64,9 +64,10 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
@@ -86,7 +87,7 @@ static X509_LOOKUP_METHOD x509_file_lookup = {
X509_LOOKUP_METHOD *
X509_LOOKUP_file(void)
{
return (&x509_file_lookup);
return &x509_file_lookup;
}
static int
@@ -114,7 +115,7 @@ by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
}
break;
}
return (ok);
return ok;
}
int
@@ -125,9 +126,7 @@ X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
int i, count = 0;
X509 *x = NULL;
if (file == NULL)
return (1);
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
X509error(ERR_R_SYS_LIB);
@@ -136,7 +135,7 @@ X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
if (type == X509_FILETYPE_PEM) {
for (;;) {
x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
x = PEM_read_bio_X509_AUX(in, NULL, NULL, "");
if (x == NULL) {
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
PEM_R_NO_START_LINE) && (count > 0)) {
@@ -172,7 +171,7 @@ X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
err:
X509_free(x);
BIO_free(in);
return (ret);
return ret;
}
int
@@ -183,9 +182,7 @@ X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
int i, count = 0;
X509_CRL *x = NULL;
if (file == NULL)
return (1);
in = BIO_new(BIO_s_file_internal());
in = BIO_new(BIO_s_file());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
X509error(ERR_R_SYS_LIB);
@@ -194,7 +191,7 @@ X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
if (type == X509_FILETYPE_PEM) {
for (;;) {
x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
x = PEM_read_bio_X509_CRL(in, NULL, NULL, "");
if (x == NULL) {
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
PEM_R_NO_START_LINE) && (count > 0)) {
@@ -228,10 +225,9 @@ X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
goto err;
}
err:
if (x != NULL)
X509_CRL_free(x);
X509_CRL_free(x);
BIO_free(in);
return (ret);
return ret;
}
int
@@ -241,6 +237,7 @@ X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
X509_INFO *itmp;
BIO *in;
int i, count = 0;
if (type != X509_FILETYPE_PEM)
return X509_load_cert_file(ctx, file, type);
in = BIO_new_file(file, "r");
@@ -248,7 +245,7 @@ X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
X509error(ERR_R_SYS_LIB);
return 0;
}
inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
inf = PEM_X509_INFO_read_bio(in, NULL, NULL, "");
BIO_free(in);
if (!inf) {
X509error(ERR_R_PEM_LIB);
@@ -265,6 +262,8 @@ X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
count++;
}
}
if (count == 0)
X509error(X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
sk_X509_INFO_pop_free(inf, X509_INFO_free);
return count;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: by_mem.c,v 1.4 2017/01/29 17:49:23 beck Exp $ */
/* $OpenBSD: by_mem.c,v 1.5 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -68,6 +68,8 @@
#include <openssl/lhash.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
static int by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **);
static X509_LOOKUP_METHOD x509_mem_lookup = {

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ext_dat.h,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: ext_dat.h,v 1.4 2021/11/24 19:22:14 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -72,7 +72,8 @@ extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
extern X509V3_EXT_METHOD v3_addr, v3_asid;
extern const X509V3_EXT_METHOD v3_addr, v3_asid;
extern const X509V3_EXT_METHOD v3_ct_scts[3];
/* This table will be searched using OBJ_bsearch so it *must* kept in
* order of the ext_nid values.
@@ -105,6 +106,10 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
#endif
&v3_sxnet,
&v3_info,
#ifndef OPENSSL_NO_RFC3779
&v3_addr,
&v3_asid,
#endif
#ifndef OPENSSL_NO_OCSP
&v3_ocsp_nonce,
&v3_ocsp_crlid,
@@ -125,6 +130,11 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
&v3_idp,
&v3_alt[2],
&v3_freshest_crl,
#ifndef OPENSSL_NO_CT
&v3_ct_scts[0],
&v3_ct_scts[1],
&v3_ct_scts[2],
#endif
};
/* Number of standard extensions */

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: pcy_cache.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: pcy_cache.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2004.
*/
@@ -60,6 +60,7 @@
#include <openssl/x509v3.h>
#include "pcy_int.h"
#include "x509_lcl.h"
static int policy_data_cmp(const X509_POLICY_DATA * const *a,
const X509_POLICY_DATA * const *b);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: pcy_map.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: pcy_map.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2004.
*/
@@ -60,6 +60,7 @@
#include <openssl/x509v3.h>
#include "pcy_int.h"
#include "x509_lcl.h"
/* Set policy mapping entries in cache.
* Note: this modifies the passed POLICY_MAPPINGS structure

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: pcy_tree.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: pcy_tree.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2004.
*/
@@ -60,6 +60,7 @@
#include <openssl/x509v3.h>
#include "pcy_int.h"
#include "x509_lcl.h"
/* Enable this to print out the complete policy tree at various point during
* evaluation.

1953
externals/libressl/crypto/x509/x509_addr.c vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_alt.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_alt.c,v 1.12 2022/03/26 16:34:21 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@@ -63,6 +63,8 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "x509_internal.h"
static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
@@ -264,15 +266,18 @@ GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
break;
case GEN_EMAIL:
BIO_printf(out, "email:%s", gen->d.ia5->data);
BIO_printf(out, "email:%.*s", gen->d.ia5->length,
gen->d.ia5->data);
break;
case GEN_DNS:
BIO_printf(out, "DNS:%s", gen->d.ia5->data);
BIO_printf(out, "DNS:%.*s", gen->d.ia5->length,
gen->d.ia5->data);
break;
case GEN_URI:
BIO_printf(out, "URI:%s", gen->d.ia5->data);
BIO_printf(out, "URI:%.*s", gen->d.ia5->length,
gen->d.ia5->data);
break;
case GEN_DIRNAME:
@@ -609,8 +614,11 @@ GENERAL_NAME *
v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
{
int type;
uint8_t *bytes = NULL;
char *name, *value;
GENERAL_NAME *ret;
size_t len = 0;
int type;
name = cnf->name;
value = cnf->value;
@@ -640,7 +648,67 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
return NULL;
}
return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
ret = a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
if (ret == NULL)
return NULL;
/*
* Validate what we have for sanity.
*/
if (is_nc) {
struct x509_constraints_name *constraints_name = NULL;
if (!x509_constraints_validate(ret, &constraints_name, NULL)) {
X509V3error(X509V3_R_BAD_OBJECT);
ERR_asprintf_error_data("name=%s", name);
goto err;
}
x509_constraints_name_free(constraints_name);
return ret;
}
type = x509_constraints_general_to_bytes(ret, &bytes, &len);
switch (type) {
case GEN_DNS:
if (!x509_constraints_valid_sandns(bytes, len)) {
X509V3error(X509V3_R_BAD_OBJECT);
ERR_asprintf_error_data("name=%s value='%.*s'", name,
(int)len, bytes);
goto err;
}
break;
case GEN_URI:
if (!x509_constraints_uri_host(bytes, len, NULL)) {
X509V3error(X509V3_R_BAD_OBJECT);
ERR_asprintf_error_data("name=%s value='%.*s'", name,
(int)len, bytes);
goto err;
}
break;
case GEN_EMAIL:
if (!x509_constraints_parse_mailbox(bytes, len, NULL)) {
X509V3error(X509V3_R_BAD_OBJECT);
ERR_asprintf_error_data("name=%s value='%.*s'", name,
(int)len, bytes);
goto err;
}
break;
case GEN_IPADD:
if (len != 4 && len != 16) {
X509V3error(X509V3_R_BAD_IP_ADDRESS);
ERR_asprintf_error_data("name=%s len=%zu", name, len);
goto err;
}
break;
default:
break;
}
return ret;
err:
if (out == NULL)
GENERAL_NAME_free(ret);
return NULL;
}
static int

1145
externals/libressl/crypto/x509/x509_asid.c vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_att.c,v 1.17 2018/05/18 19:21:33 tb Exp $ */
/* $OpenBSD: x509_att.c,v 1.18 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,6 +66,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
int
X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_cmp.c,v 1.35 2019/03/13 20:34:00 tb Exp $ */
/* $OpenBSD: x509_cmp.c,v 1.39 2022/02/24 22:05:06 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -68,6 +68,9 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "evp_locl.h"
#include "x509_lcl.h"
int
X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
{
@@ -140,7 +143,7 @@ X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
int
X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
{
return memcmp(a->sha1_hash, b->sha1_hash, 20);
return memcmp(a->hash, b->hash, X509_CRL_HASH_LEN);
}
#endif
@@ -213,7 +216,7 @@ X509_cmp(const X509 *a, const X509 *b)
X509_check_purpose((X509 *)a, -1, 0);
X509_check_purpose((X509 *)b, -1, 0);
return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN);
}
#endif

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_conf.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_conf.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -66,6 +66,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static int v3_check_critical(const char **value);
static int v3_check_generic(const char **value);
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_constraints.c,v 1.10 2020/09/21 05:41:43 tb Exp $ */
/* $OpenBSD: x509_constraints.c,v 1.26 2022/03/26 16:34:21 tb Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
@@ -36,7 +36,7 @@
#define DOMAIN_PART_MAX_LEN 255
struct x509_constraints_name *
x509_constraints_name_new()
x509_constraints_name_new(void)
{
return (calloc(1, sizeof(struct x509_constraints_name)));
}
@@ -69,9 +69,11 @@ x509_constraints_name_dup(struct x509_constraints_name *name)
new->type = name->type;
new->af = name->af;
new->der_len = name->der_len;
if (name->der_len > 0 && (new->der = malloc(name->der_len)) == NULL)
goto err;
memcpy(new->der, name->der, name->der_len);
if (name->der_len > 0) {
if ((new->der = malloc(name->der_len)) == NULL)
goto err;
memcpy(new->der, name->der, name->der_len);
}
if (name->name != NULL && (new->name = strdup(name->name)) == NULL)
goto err;
if (name->local != NULL && (new->local = strdup(name->local)) == NULL)
@@ -84,9 +86,16 @@ x509_constraints_name_dup(struct x509_constraints_name *name)
}
struct x509_constraints_names *
x509_constraints_names_new()
x509_constraints_names_new(size_t names_max)
{
return (calloc(1, sizeof(struct x509_constraints_names)));
struct x509_constraints_names *new;
if ((new = calloc(1, sizeof(struct x509_constraints_names))) == NULL)
return NULL;
new->names_max = names_max;
return new;
}
void
@@ -114,8 +123,8 @@ int
x509_constraints_names_add(struct x509_constraints_names *names,
struct x509_constraints_name *name)
{
size_t i = names->names_count;
if (names->names_count >= names->names_max)
return 0;
if (names->names_count == names->names_len) {
struct x509_constraints_name **tmp;
if ((tmp = recallocarray(names->names, names->names_len,
@@ -124,7 +133,7 @@ x509_constraints_names_add(struct x509_constraints_names *names,
names->names_len += 32;
names->names = tmp;
}
names->names[i] = name;
names->names[names->names_count] = name;
names->names_count++;
return 1;
}
@@ -139,14 +148,16 @@ x509_constraints_names_dup(struct x509_constraints_names *names)
if (names == NULL)
return NULL;
if ((new = x509_constraints_names_new()) == NULL)
if ((new = x509_constraints_names_new(names->names_max)) == NULL)
goto err;
for (i = 0; i < names->names_count; i++) {
if ((name = x509_constraints_name_dup(names->names[i])) == NULL)
goto err;
if (!x509_constraints_names_add(new, name))
goto err;
}
return new;
err:
x509_constraints_names_free(new);
@@ -158,13 +169,15 @@ x509_constraints_names_dup(struct x509_constraints_names *names)
/*
* Validate that the name contains only a hostname consisting of RFC
* 5890 compliant A-labels (see RFC 6066 section 3). This is more
* permissive to allow for a leading '*' for a SAN DNSname wildcard,
* or a leading '.' for a subdomain based constraint, as well as
* allowing for '_' which is commonly accepted by nonconformant
* DNS implementaitons.
* permissive to allow for a leading '.' for a subdomain based
* constraint, as well as allowing for '_' which is commonly accepted
* by nonconformant DNS implementaitons.
*
* if "wildcards" is set it allows '*' to occur in the string at the end of a
* component.
*/
static int
x509_constraints_valid_domain_internal(uint8_t *name, size_t len)
x509_constraints_valid_domain_internal(uint8_t *name, size_t len, int wildcards)
{
uint8_t prev, c = 0;
int component = 0;
@@ -187,8 +200,8 @@ x509_constraints_valid_domain_internal(uint8_t *name, size_t len)
if (!isalnum(c) && c != '-' && c != '.' && c != '_' && c != '*')
return 0;
/* '*' can only be the first thing. */
if (c == '*' && !first)
/* if it is a '*', fail if not wildcards */
if (!wildcards && c == '*')
return 0;
/* '-' must not start a component or be at the end. */
@@ -210,6 +223,13 @@ x509_constraints_valid_domain_internal(uint8_t *name, size_t len)
component = 0;
continue;
}
/*
* Wildcards can only occur at the end of a component.
* c*.com is valid, c*c.com is not.
*/
if (prev == '*')
return 0;
/* Components must be 63 chars or less. */
if (++component > 63)
return 0;
@@ -222,15 +242,13 @@ x509_constraints_valid_domain(uint8_t *name, size_t len)
{
if (len == 0)
return 0;
if (name[0] == '*') /* wildcard not allowed in a domain name */
return 0;
/*
* A domain may not be less than two characters, so you can't
* have a require subdomain name with less than that.
*/
if (len < 3 && name[0] == '.')
return 0;
return x509_constraints_valid_domain_internal(name, len);
return x509_constraints_valid_domain_internal(name, len, 0);
}
int
@@ -241,15 +259,13 @@ x509_constraints_valid_host(uint8_t *name, size_t len)
if (len == 0)
return 0;
if (name[0] == '*') /* wildcard not allowed in a host name */
return 0;
if (name[0] == '.') /* leading . not allowed in a host name*/
return 0;
if (inet_pton(AF_INET, name, &sin4) == 1)
return 0;
if (inet_pton(AF_INET6, name, &sin6) == 1)
return 0;
return x509_constraints_valid_domain_internal(name, len);
return x509_constraints_valid_domain_internal(name, len, 0);
}
int
@@ -272,7 +288,7 @@ x509_constraints_valid_sandns(uint8_t *name, size_t len)
if (len >= 4 && name[0] == '*' && name[1] != '.')
return 0;
return x509_constraints_valid_domain_internal(name, len);
return x509_constraints_valid_domain_internal(name, len, 1);
}
static inline int
@@ -323,16 +339,16 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len,
if (c == '.')
goto bad;
}
if (wi > DOMAIN_PART_MAX_LEN)
goto bad;
if (accept) {
if (wi >= DOMAIN_PART_MAX_LEN)
goto bad;
working[wi++] = c;
accept = 0;
continue;
}
if (candidate_local != NULL) {
/* We are looking for the domain part */
if (wi > DOMAIN_PART_MAX_LEN)
if (wi >= DOMAIN_PART_MAX_LEN)
goto bad;
working[wi++] = c;
if (i == len - 1) {
@@ -347,7 +363,7 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len,
continue;
}
/* We are looking for the local part */
if (wi > LOCAL_PART_MAX_LEN)
if (wi >= LOCAL_PART_MAX_LEN)
break;
if (quoted) {
@@ -367,12 +383,14 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len,
*/
if (c == 9)
goto bad;
if (wi >= LOCAL_PART_MAX_LEN)
goto bad;
working[wi++] = c;
continue; /* all's good inside our quoted string */
}
if (c == '@') {
if (wi == 0)
goto bad;;
goto bad;
if (candidate_local != NULL)
goto bad;
candidate_local = strdup(working);
@@ -396,6 +414,8 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len,
}
if (!local_part_ok(c))
goto bad;
if (wi >= LOCAL_PART_MAX_LEN)
goto bad;
working[wi++] = c;
}
if (candidate_local == NULL || candidate_domain == NULL)
@@ -404,9 +424,14 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len,
strlen(candidate_domain)))
goto bad;
name->local = candidate_local;
name->name = candidate_domain;
name->type = GEN_EMAIL;
if (name != NULL) {
name->local = candidate_local;
name->name = candidate_domain;
name->type = GEN_EMAIL;
} else {
free(candidate_local);
free(candidate_domain);
}
return 1;
bad:
free(candidate_local);
@@ -420,16 +445,13 @@ x509_constraints_valid_domain_constraint(uint8_t *constraint, size_t len)
if (len == 0)
return 1; /* empty constraints match */
if (constraint[0] == '*') /* wildcard not allowed in a constraint */
return 0;
/*
* A domain may not be less than two characters, so you
* can't match a single domain of less than that
*/
if (len < 3 && constraint[0] == '.')
return 0;
return x509_constraints_valid_domain_internal(constraint, len);
return x509_constraints_valid_domain_internal(constraint, len, 0);
}
/*
@@ -494,7 +516,8 @@ x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostpart)
host = authority;
if (!x509_constraints_valid_host(host, hostlen))
return 0;
*hostpart = strndup(host, hostlen);
if (hostpart != NULL)
*hostpart = strndup(host, hostlen);
return 1;
}
@@ -613,7 +636,11 @@ int
x509_constraints_dirname(uint8_t *dirname, size_t dlen,
uint8_t *constraint, size_t len)
{
if (len != dlen)
/*
* The constraint must be a prefix in DER format, so it can't be
* longer than the name it is checked against.
*/
if (len > dlen)
return 0;
return (memcmp(constraint, dirname, len) == 0);
}
@@ -630,35 +657,45 @@ x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes,
if (name->type == GEN_DNS) {
ASN1_IA5STRING *aname = name->d.dNSName;
*bytes = aname->data;
*len = strlen(aname->data);
*len = aname->length;
return name->type;
}
if (name->type == GEN_EMAIL) {
ASN1_IA5STRING *aname = name->d.rfc822Name;
*bytes = aname->data;
*len = strlen(aname->data);
*len = aname->length;
return name->type;
}
if (name->type == GEN_URI) {
ASN1_IA5STRING *aname = name->d.uniformResourceIdentifier;
*bytes = aname->data;
*len = strlen(aname->data);
*len = aname->length;
return name->type;
}
if (name->type == GEN_DIRNAME) {
X509_NAME *dname = name->d.directoryName;
if (!dname->modified || i2d_X509_NAME(dname, NULL) >= 0) {
*bytes = dname->canon_enc;
*len = dname->canon_enclen;
return name->type;
}
}
if (name->type == GEN_IPADD) {
*bytes = name->d.ip->data;
*len = name->d.ip->length;
return name->type;
}
return 0;
}
@@ -696,11 +733,11 @@ x509_constraints_extract_names(struct x509_constraints_names *names,
*error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
goto err;
}
if ((vname->name = strdup(bytes)) == NULL) {
if ((vname->name = strndup(bytes, len)) == NULL) {
*error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
vname->type=GEN_DNS;
vname->type = GEN_DNS;
include_cn = 0; /* don't use cn from subject */
break;
case GEN_EMAIL:
@@ -724,15 +761,15 @@ x509_constraints_extract_names(struct x509_constraints_names *names,
vname->type = GEN_URI;
break;
case GEN_DIRNAME:
if (len == 0) {
*error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
goto err;
}
if (bytes == NULL || ((vname->der = malloc(len)) ==
NULL)) {
*error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
if (len == 0) {
*error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
goto err;
}
memcpy(vname->der, bytes, len);
vname->der_len = len;
vname->type = GEN_DIRNAME;
@@ -742,8 +779,7 @@ x509_constraints_extract_names(struct x509_constraints_names *names,
vname->af = AF_INET;
if (len == 16)
vname->af = AF_INET6;
if (vname->af != AF_INET && vname->af !=
AF_INET6) {
if (vname->af != AF_INET && vname->af != AF_INET6) {
*error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
goto err;
}
@@ -870,21 +906,34 @@ x509_constraints_extract_names(struct x509_constraints_names *names,
*/
int
x509_constraints_validate(GENERAL_NAME *constraint,
struct x509_constraints_name *name, int *error)
struct x509_constraints_name **out_name, int *out_error)
{
uint8_t *bytes = NULL;
size_t len = 0;
struct x509_constraints_name *name;
int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX;
int name_type;
if (out_name == NULL || *out_name != NULL)
return 0;
if (out_error != NULL)
*out_error = 0;
if ((name = x509_constraints_name_new()) == NULL) {
error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len);
switch (name_type) {
case GEN_DIRNAME:
if (bytes == NULL || (name->der = malloc(len)) == NULL) {
*error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
if (len == 0)
goto err; /* XXX The RFCs are delightfully vague */
if (bytes == NULL || (name->der = malloc(len)) == NULL) {
error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
memcpy(name->der, bytes, len);
name->der_len = len;
name->type = GEN_DIRNAME;
@@ -892,24 +941,31 @@ x509_constraints_validate(GENERAL_NAME *constraint,
case GEN_DNS:
if (!x509_constraints_valid_domain_constraint(bytes, len))
goto err;
if ((name->name = strdup(bytes)) == NULL) {
*error = X509_V_ERR_OUT_OF_MEM;
return 0;
if ((name->name = strndup(bytes, len)) == NULL) {
error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
name->type = GEN_DNS;
break;
case GEN_EMAIL:
if (memchr(bytes, '@', len) != NULL) {
if (len > 0 && memchr(bytes + 1, '@', len - 1) != NULL) {
if (!x509_constraints_parse_mailbox(bytes, len, name))
goto err;
} else {
if (!x509_constraints_valid_domain_constraint(bytes,
len))
goto err;
if ((name->name = strdup(bytes)) == NULL) {
*error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
break;
}
/*
* Mail constraints of the form @domain.com are accepted by
* OpenSSL and Microsoft.
*/
if (len > 0 && bytes[0] == '@') {
bytes++;
len--;
}
if (!x509_constraints_valid_domain_constraint(bytes, len))
goto err;
if ((name->name = strndup(bytes, len)) == NULL) {
error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
name->type = GEN_EMAIL;
break;
@@ -927,15 +983,25 @@ x509_constraints_validate(GENERAL_NAME *constraint,
case GEN_URI:
if (!x509_constraints_valid_domain_constraint(bytes, len))
goto err;
name->name = strdup(bytes);
if ((name->name = strndup(bytes, len)) == NULL) {
error = X509_V_ERR_OUT_OF_MEM;
goto err;
}
name->type = GEN_URI;
break;
default:
break;
}
*out_name = name;
return 1;
err:
*error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX;
x509_constraints_name_free(name);
if (out_error != NULL)
*out_error = error;
return 0;
}
@@ -945,7 +1011,7 @@ x509_constraints_extract_constraints(X509 *cert,
struct x509_constraints_names *excluded,
int *error)
{
struct x509_constraints_name *vname;
struct x509_constraints_name *vname = NULL;
NAME_CONSTRAINTS *nc = cert->nc;
GENERAL_SUBTREE *subtree;
int i;
@@ -960,24 +1026,20 @@ x509_constraints_extract_constraints(X509 *cert,
*error = X509_V_ERR_SUBTREE_MINMAX;
return 0;
}
if ((vname = x509_constraints_name_new()) == NULL) {
*error = X509_V_ERR_OUT_OF_MEM;
if (!x509_constraints_validate(subtree->base, &vname, error))
return 0;
}
if (x509_constraints_validate(subtree->base, vname, error) ==
0) {
x509_constraints_name_free(vname);
return 0;
}
if (vname->type == 0) {
x509_constraints_name_free(vname);
vname = NULL;
continue;
}
if (!x509_constraints_names_add(permitted, vname)) {
x509_constraints_name_free(vname);
vname = NULL;
*error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
vname = NULL;
}
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
@@ -986,24 +1048,20 @@ x509_constraints_extract_constraints(X509 *cert,
*error = X509_V_ERR_SUBTREE_MINMAX;
return 0;
}
if ((vname = x509_constraints_name_new()) == NULL) {
*error = X509_V_ERR_OUT_OF_MEM;
if (!x509_constraints_validate(subtree->base, &vname, error))
return 0;
}
if (x509_constraints_validate(subtree->base, vname, error) ==
0) {
x509_constraints_name_free(vname);
return 0;
}
if (vname->type == 0) {
x509_constraints_name_free(vname);
vname = NULL;
continue;
}
if (!x509_constraints_names_add(excluded, vname)) {
x509_constraints_name_free(vname);
vname = NULL;
*error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
vname = NULL;
}
return 1;
@@ -1115,7 +1173,8 @@ x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth)
goto err;
if (chain_length == 1)
return 1;
if ((names = x509_constraints_names_new()) == NULL) {
if ((names = x509_constraints_names_new(
X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) {
verify_err = X509_V_ERR_OUT_OF_MEM;
goto err;
}
@@ -1128,13 +1187,13 @@ x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth)
if ((cert = sk_X509_value(chain, i)) == NULL)
goto err;
if (cert->nc != NULL) {
if ((permitted =
x509_constraints_names_new()) == NULL) {
if ((permitted = x509_constraints_names_new(
X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
verify_err = X509_V_ERR_OUT_OF_MEM;
goto err;
}
if ((excluded =
x509_constraints_names_new()) == NULL) {
if ((excluded = x509_constraints_names_new(
X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
verify_err = X509_V_ERR_OUT_OF_MEM;
goto err;
}
@@ -1159,10 +1218,6 @@ x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth)
if (!x509_constraints_extract_names(names, cert, 0,
&verify_err))
goto err;
if (names->names_count > X509_VERIFY_MAX_CHAIN_NAMES) {
verify_err = X509_V_ERR_OUT_OF_MEM;
goto err;
}
}
x509_constraints_names_free(names);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_cpols.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_cpols.c,v 1.4 2022/01/14 08:16:13 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -66,6 +66,7 @@
#include <openssl/x509v3.h>
#include "pcy_int.h"
#include "x509_lcl.h"
/* Certificate policies extension support: this one is a bit complex... */
@@ -232,7 +233,6 @@ static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = {
static const ASN1_ADB POLICYQUALINFO_adb = {
.flags = 0,
.offset = offsetof(POLICYQUALINFO, pqualid),
.app_items = 0,
.tbl = POLICYQUALINFO_adbtbl,
.tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE),
.default_tt = &policydefault_tt,
@@ -696,7 +696,8 @@ print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent)
qualinfo = sk_POLICYQUALINFO_value(quals, i);
switch (OBJ_obj2nid(qualinfo->pqualid)) {
case NID_id_qt_cps:
BIO_printf(out, "%*sCPS: %s\n", indent, "",
BIO_printf(out, "%*sCPS: %.*s\n", indent, "",
qualinfo->d.cpsuri->length,
qualinfo->d.cpsuri->data);
break;
@@ -724,8 +725,8 @@ print_notice(BIO *out, USERNOTICE *notice, int indent)
if (notice->noticeref) {
NOTICEREF *ref;
ref = notice->noticeref;
BIO_printf(out, "%*sOrganization: %s\n", indent, "",
ref->organization->data);
BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
ref->organization->length, ref->organization->data);
BIO_printf(out, "%*sNumber%s: ", indent, "",
sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
@@ -741,8 +742,8 @@ print_notice(BIO *out, USERNOTICE *notice, int indent)
BIO_puts(out, "\n");
}
if (notice->exptext)
BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
notice->exptext->data);
BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "",
notice->exptext->length, notice->exptext->data);
}
void

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_crld.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_crld.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -65,6 +65,8 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static void *v2i_crld(const X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_err.c,v 1.15 2020/06/05 16:51:12 jsing Exp $ */
/* $OpenBSD: x509_err.c,v 1.16 2021/11/10 13:57:42 schwarze Exp $ */
/* ====================================================================
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
*
@@ -96,6 +96,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_NO_CERTIFICATE_OR_CRL_FOUND), "no certificate or crl found"},
{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), "no cert set for us to verify"},
{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"},
{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"},

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_ext.c,v 1.12 2018/05/18 19:28:27 tb Exp $ */
/* $OpenBSD: x509_ext.c,v 1.13 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -65,6 +65,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
int
X509_CRL_get_ext_count(const X509_CRL *x)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_genn.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_genn.c,v 1.2 2020/12/08 15:06:42 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -117,16 +117,17 @@ OTHERNAME_free(OTHERNAME *a)
ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it);
}
/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */
static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = {
{
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(EDIPARTYNAME, nameAssigner),
.field_name = "nameAssigner",
.item = &DIRECTORYSTRING_it,
},
{
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
.flags = ASN1_TFLG_EXPLICIT,
.tag = 1,
.offset = offsetof(EDIPARTYNAME, partyName),
.field_name = "partyName",
@@ -324,6 +325,37 @@ GENERAL_NAME_dup(GENERAL_NAME *a)
return ASN1_item_dup(&GENERAL_NAME_it, a);
}
static int
EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
{
int res;
/*
* Shouldn't be possible in a valid GENERAL_NAME, but we handle it
* anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here.
*/
if (a == NULL || b == NULL)
return -1;
if (a->nameAssigner == NULL && b->nameAssigner != NULL)
return -1;
if (a->nameAssigner != NULL && b->nameAssigner == NULL)
return 1;
/* If we get here, both have nameAssigner set or both unset. */
if (a->nameAssigner != NULL) {
res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
if (res != 0)
return res;
}
/*
* partyName is required, so these should never be NULL. We treat it in
* the same way as the a == NULL || b == NULL case above.
*/
if (a->partyName == NULL || b->partyName == NULL)
return -1;
return ASN1_STRING_cmp(a->partyName, b->partyName);
}
/* Returns 0 if they are equal, != 0 otherwise. */
int
GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
@@ -334,8 +366,11 @@ GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
return -1;
switch (a->type) {
case GEN_X400:
result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
break;
case GEN_EDIPARTY:
result = ASN1_TYPE_cmp(a->d.other, b->d.other);
result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName);
break;
case GEN_OTHERNAME:
@@ -384,8 +419,11 @@ GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
{
switch (type) {
case GEN_X400:
a->d.x400Address = value;
break;
case GEN_EDIPARTY:
a->d.other = value;
a->d.ediPartyName = value;
break;
case GEN_OTHERNAME:
@@ -420,8 +458,10 @@ GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
*ptype = a->type;
switch (a->type) {
case GEN_X400:
return a->d.x400Address;
case GEN_EDIPARTY:
return a->d.other;
return a->d.ediPartyName;
case GEN_OTHERNAME:
return a->d.otherName;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_internal.h,v 1.3 2020/09/15 11:55:14 beck Exp $ */
/* $OpenBSD: x509_internal.h,v 1.18 2022/03/14 21:15:49 tb Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
@@ -22,6 +22,8 @@
#include <openssl/x509_verify.h>
#include "x509_lcl.h"
/* Hard limits on structure size and number of signature checks. */
#define X509_VERIFY_MAX_CHAINS 8 /* Max validated chains */
#define X509_VERIFY_MAX_CHAIN_CERTS 32 /* Max depth of a chain */
@@ -51,18 +53,23 @@ struct x509_constraints_name {
struct x509_constraints_names {
struct x509_constraints_name **names;
size_t names_len;
size_t names_count;
size_t names_len;
size_t names_max;
};
struct x509_verify_chain {
STACK_OF(X509) *certs; /* Kept in chain order, includes leaf */
int *cert_errors; /* Verify error for each cert in chain. */
struct x509_constraints_names *names; /* All names from all certs */
};
struct x509_verify_ctx {
X509_STORE_CTX *xsc;
struct x509_verify_chain **chains; /* Validated chains */
STACK_OF(X509) *saved_error_chain;
int saved_error;
int saved_error_depth;
size_t chains_count;
STACK_OF(X509) *roots; /* Trusted roots for this validation */
STACK_OF(X509) *intermediates; /* Intermediates provided by peer */
@@ -72,8 +79,8 @@ struct x509_verify_ctx {
size_t max_depth; /* Max chain depth for validation */
size_t max_sigs; /* Max number of signature checks */
size_t sig_checks; /* Number of signature checks done */
size_t error_depth; /* Depth of last error seen */
int error; /* Last error seen */
size_t error_depth; /* Depth of last error seen */
int error; /* Last error seen */
};
int ASN1_time_tm_clamp_notafter(struct tm *tm);
@@ -85,21 +92,24 @@ int x509_vfy_check_revocation(X509_STORE_CTX *ctx);
int x509_vfy_check_policy(X509_STORE_CTX *ctx);
int x509_vfy_check_trust(X509_STORE_CTX *ctx);
int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx);
void x509v3_cache_extensions(X509 *x);
X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
int x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm,
int notafter);
time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter);
struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc,
STACK_OF(X509) *roots);
struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc);
void x509_constraints_name_clear(struct x509_constraints_name *name);
void x509_constraints_name_free(struct x509_constraints_name *name);
int x509_constraints_names_add(struct x509_constraints_names *names,
struct x509_constraints_name *name);
struct x509_constraints_names *x509_constraints_names_dup(
struct x509_constraints_names *names);
void x509_constraints_names_clear(struct x509_constraints_names *names);
struct x509_constraints_names *x509_constraints_names_new(void);
struct x509_constraints_names *x509_constraints_names_new(size_t names_max);
int x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes,
size_t *len);
void x509_constraints_names_free(struct x509_constraints_names *names);
int x509_constraints_valid_host(uint8_t *name, size_t len);
int x509_constraints_valid_sandns(uint8_t *name, size_t len);
@@ -117,11 +127,14 @@ int x509_constraints_extract_names(struct x509_constraints_names *names,
int x509_constraints_extract_constraints(X509 *cert,
struct x509_constraints_names *permitted,
struct x509_constraints_names *excluded, int *error);
int x509_constraints_validate(GENERAL_NAME *constraint,
struct x509_constraints_name **out_name, int *error);
int x509_constraints_check(struct x509_constraints_names *names,
struct x509_constraints_names *permitted,
struct x509_constraints_names *excluded, int *error);
int x509_constraints_chain(STACK_OF(X509) *chain, int *error,
int *depth);
void x509_verify_cert_info_populate(X509 *cert);
__END_HIDDEN_DECLS

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_issuer_cache.c,v 1.1 2020/09/11 14:30:51 beck Exp $ */
/* $OpenBSD: x509_issuer_cache.c,v 1.2 2020/11/18 17:00:59 tb Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
@@ -77,9 +77,9 @@ x509_issuer_cache_set_max(size_t max)
* Find a previous result of checking if parent signed child
*
* Returns:
* -1 : No entry exists in the cache. signature must be checked.
* 0 : The signature of parent signing child is invalid.
* 1 : The signature of parent signing child is valid.
* -1 : No entry exists in the cache. signature must be checked.
* 0 : The signature of parent signing child is invalid.
* 1 : The signature of parent signing child is valid.
*/
int
x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md)
@@ -98,7 +98,7 @@ x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md)
return -1;
if ((found = RB_FIND(x509_issuer_tree, &x509_issuer_cache,
&candidate)) != NULL) {
TAILQ_REMOVE(&x509_issuer_lru, found, queue);
TAILQ_REMOVE(&x509_issuer_lru, found, queue);
TAILQ_INSERT_HEAD(&x509_issuer_lru, found, queue);
ret = found->valid;
}
@@ -111,7 +111,7 @@ x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md)
* Attempt to add a validation result to the cache.
*
* valid must be:
* 0: The signature of parent signing child is invalid.
* 0: The signature of parent signing child is invalid.
* 1: The signature of parent signing child is valid.
*
* Previously added entries for the same parent and child are *not* replaced.

View File

@@ -56,8 +56,329 @@
*
*/
#ifndef HEADER_X509_LCL_H
#define HEADER_X509_LCL_H
__BEGIN_HIDDEN_DECLS
#define TS_HASH_EVP EVP_sha1()
#define TS_HASH_LEN SHA_DIGEST_LENGTH
#define X509_CERT_HASH_EVP EVP_sha512()
#define X509_CERT_HASH_LEN SHA512_DIGEST_LENGTH
#define X509_CRL_HASH_EVP EVP_sha512()
#define X509_CRL_HASH_LEN SHA512_DIGEST_LENGTH
struct X509_pubkey_st {
X509_ALGOR *algor;
ASN1_BIT_STRING *public_key;
EVP_PKEY *pkey;
};
struct X509_sig_st {
X509_ALGOR *algor;
ASN1_OCTET_STRING *digest;
} /* X509_SIG */;
struct X509_name_entry_st {
ASN1_OBJECT *object;
ASN1_STRING *value;
int set;
int size; /* temp variable */
} /* X509_NAME_ENTRY */;
/* we always keep X509_NAMEs in 2 forms. */
struct X509_name_st {
STACK_OF(X509_NAME_ENTRY) *entries;
int modified; /* true if 'bytes' needs to be built */
#ifndef OPENSSL_NO_BUFFER
BUF_MEM *bytes;
#else
char *bytes;
#endif
/* unsigned long hash; Keep the hash around for lookups */
unsigned char *canon_enc;
int canon_enclen;
} /* X509_NAME */;
struct X509_extension_st {
ASN1_OBJECT *object;
ASN1_BOOLEAN critical;
ASN1_OCTET_STRING *value;
} /* X509_EXTENSION */;
struct x509_attributes_st {
ASN1_OBJECT *object;
int single; /* 0 for a set, 1 for a single item (which is wrong) */
union {
char *ptr;
/* 0 */ STACK_OF(ASN1_TYPE) *set;
/* 1 */ ASN1_TYPE *single;
} value;
} /* X509_ATTRIBUTE */;
struct X509_req_info_st {
ASN1_ENCODING enc;
ASN1_INTEGER *version;
X509_NAME *subject;
X509_PUBKEY *pubkey;
/* d=2 hl=2 l= 0 cons: cont: 00 */
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
} /* X509_REQ_INFO */;
struct X509_req_st {
X509_REQ_INFO *req_info;
X509_ALGOR *sig_alg;
ASN1_BIT_STRING *signature;
int references;
} /* X509_REQ */;
/*
* This stuff is certificate "auxiliary info" it contains details which are
* useful in certificate stores and databases. When used this is tagged onto
* the end of the certificate itself.
*/
struct x509_cert_aux_st {
STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
ASN1_UTF8STRING *alias; /* "friendly name" */
ASN1_OCTET_STRING *keyid; /* key id of private key */
STACK_OF(X509_ALGOR) *other; /* other unspecified info */
} /* X509_CERT_AUX */;
struct x509_cinf_st {
ASN1_INTEGER *version; /* [ 0 ] default of v1 */
ASN1_INTEGER *serialNumber;
X509_ALGOR *signature;
X509_NAME *issuer;
X509_VAL *validity;
X509_NAME *subject;
X509_PUBKEY *key;
ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
ASN1_ENCODING enc;
} /* X509_CINF */;
struct x509_st {
X509_CINF *cert_info;
X509_ALGOR *sig_alg;
ASN1_BIT_STRING *signature;
int valid;
int references;
char *name;
CRYPTO_EX_DATA ex_data;
/* These contain copies of various extension values */
long ex_pathlen;
long ex_pcpathlen;
unsigned long ex_flags;
unsigned long ex_kusage;
unsigned long ex_xkusage;
unsigned long ex_nscert;
ASN1_OCTET_STRING *skid;
AUTHORITY_KEYID *akid;
X509_POLICY_CACHE *policy_cache;
STACK_OF(DIST_POINT) *crldp;
STACK_OF(GENERAL_NAME) *altname;
NAME_CONSTRAINTS *nc;
#ifndef OPENSSL_NO_RFC3779
STACK_OF(IPAddressFamily) *rfc3779_addr;
struct ASIdentifiers_st *rfc3779_asid;
#endif
unsigned char hash[X509_CERT_HASH_LEN];
time_t not_before;
time_t not_after;
X509_CERT_AUX *aux;
} /* X509 */;
struct x509_revoked_st {
ASN1_INTEGER *serialNumber;
ASN1_TIME *revocationDate;
STACK_OF(X509_EXTENSION) /* optional */ *extensions;
/* Set up if indirect CRL */
STACK_OF(GENERAL_NAME) *issuer;
/* Revocation reason */
int reason;
int sequence; /* load sequence */
};
struct X509_crl_info_st {
ASN1_INTEGER *version;
X509_ALGOR *sig_alg;
X509_NAME *issuer;
ASN1_TIME *lastUpdate;
ASN1_TIME *nextUpdate;
STACK_OF(X509_REVOKED) *revoked;
STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
ASN1_ENCODING enc;
} /* X509_CRL_INFO */;
struct X509_crl_st {
/* actual signature */
X509_CRL_INFO *crl;
X509_ALGOR *sig_alg;
ASN1_BIT_STRING *signature;
int references;
int flags;
/* Copies of various extensions */
AUTHORITY_KEYID *akid;
ISSUING_DIST_POINT *idp;
/* Convenient breakdown of IDP */
int idp_flags;
int idp_reasons;
/* CRL and base CRL numbers for delta processing */
ASN1_INTEGER *crl_number;
ASN1_INTEGER *base_crl_number;
unsigned char hash[X509_CRL_HASH_LEN];
STACK_OF(GENERAL_NAMES) *issuers;
const X509_CRL_METHOD *meth;
void *meth_data;
} /* X509_CRL */;
struct pkcs8_priv_key_info_st {
ASN1_INTEGER *version;
X509_ALGOR *pkeyalg;
ASN1_OCTET_STRING *pkey;
STACK_OF(X509_ATTRIBUTE) *attributes;
};
struct x509_object_st {
/* one of the above types */
int type;
union {
X509 *x509;
X509_CRL *crl;
} data;
} /* X509_OBJECT */;
struct x509_lookup_method_st {
const char *name;
int (*new_item)(X509_LOOKUP *ctx);
void (*free)(X509_LOOKUP *ctx);
int (*init)(X509_LOOKUP *ctx);
int (*shutdown)(X509_LOOKUP *ctx);
int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
char **ret);
int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name,
X509_OBJECT *ret);
int (*get_by_issuer_serial)(X509_LOOKUP *ctx, int type, X509_NAME *name,
ASN1_INTEGER *serial,X509_OBJECT *ret);
int (*get_by_fingerprint)(X509_LOOKUP *ctx, int type,
const unsigned char *bytes, int len, X509_OBJECT *ret);
int (*get_by_alias)(X509_LOOKUP *ctx, int type, const char *str,
int len, X509_OBJECT *ret);
} /* X509_LOOKUP_METHOD */;
struct X509_VERIFY_PARAM_st {
char *name;
time_t check_time; /* Time to use */
unsigned long inh_flags; /* Inheritance flags */
unsigned long flags; /* Various verify flags */
int purpose; /* purpose to check untrusted certificates */
int trust; /* trust setting to check */
int depth; /* Verify depth */
STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
X509_VERIFY_PARAM_ID *id; /* opaque ID data */
} /* X509_VERIFY_PARAM */;
/*
* This is used to hold everything. It is used for all certificate
* validation. Once we have a certificate chain, the 'verify'
* function is then called to actually check the cert chain.
*/
struct x509_store_st {
/* The following is a cache of trusted certs */
STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
/* These are external lookup methods */
STACK_OF(X509_LOOKUP) *get_cert_methods;
X509_VERIFY_PARAM *param;
/* Callbacks for various operations */
int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */
int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */
int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */
int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
int (*cleanup)(X509_STORE_CTX *ctx);
CRYPTO_EX_DATA ex_data;
int references;
} /* X509_STORE */;
/* This is the functions plus an instance of the local variables. */
struct x509_lookup_st {
int init; /* have we been started */
X509_LOOKUP_METHOD *method; /* the functions */
char *method_data; /* method data */
X509_STORE *store_ctx; /* who owns us */
} /* X509_LOOKUP */;
/*
* This is used when verifying cert chains. Since the gathering of the cert
* chain can take some time (and has to be 'retried'), this needs to be kept
* and passed around.
*/
struct x509_store_ctx_st {
X509_STORE *store;
int current_method; /* used when looking up certs */
/* The following are set by the caller */
X509 *cert; /* The cert to check */
STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */
STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */
X509_VERIFY_PARAM *param;
void *other_ctx; /* Other info for use with get_issuer() */
/* Callbacks for various operations */
int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */
int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */
int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */
int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
int (*check_policy)(X509_STORE_CTX *ctx);
STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
int (*cleanup)(X509_STORE_CTX *ctx);
/* The following is built up */
int valid; /* if 0, rebuild chain */
int num_untrusted; /* number of untrusted certs in chain */
STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */
X509_POLICY_TREE *tree; /* Valid policy tree */
int explicit_policy; /* Require explicit policy value */
/* When something goes wrong, this is why */
int error_depth;
int error;
X509 *current_cert;
X509 *current_issuer; /* cert currently being tested as valid issuer */
X509_CRL *current_crl; /* current CRL */
int current_crl_score; /* score of current CRL */
unsigned int current_reasons; /* Reason mask */
X509_STORE_CTX *parent; /* For CRL path validation: parent context */
CRYPTO_EX_DATA ex_data;
} /* X509_STORE_CTX */;
int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet);
int name_cmp(const char *name, const char *cmp);
__END_HIDDEN_DECLS
#endif /* !HEADER_X509_LCL_H */

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_lib.c,v 1.2 2020/09/14 11:35:32 beck Exp $ */
/* $OpenBSD: x509_lib.c,v 1.3 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -64,6 +64,7 @@
#include <openssl/x509v3.h>
#include "ext_dat.h"
#include "x509_lcl.h"
static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_lu.c,v 1.30 2018/08/24 19:21:09 tb Exp $ */
/* $OpenBSD: x509_lu.c,v 1.55 2022/01/14 07:53:45 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -57,6 +57,7 @@
*/
#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
@@ -64,27 +65,24 @@
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static void X509_OBJECT_dec_ref_count(X509_OBJECT *a);
X509_LOOKUP *
X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
{
X509_LOOKUP *ret;
X509_LOOKUP *lu;
ret = malloc(sizeof(X509_LOOKUP));
if (ret == NULL)
return NULL;
ret->init = 0;
ret->skip = 0;
ret->method = method;
ret->method_data = NULL;
ret->store_ctx = NULL;
if ((method->new_item != NULL) && !method->new_item(ret)) {
free(ret);
if ((lu = calloc(1, sizeof(*lu))) == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return NULL;
}
return ret;
lu->method = method;
if (method->new_item != NULL && !method->new_item(lu)) {
free(lu);
return NULL;
}
return lu;
}
void
@@ -92,8 +90,8 @@ X509_LOOKUP_free(X509_LOOKUP *ctx)
{
if (ctx == NULL)
return;
if ((ctx->method != NULL) && (ctx->method->free != NULL))
(*ctx->method->free)(ctx);
if (ctx->method != NULL && ctx->method->free != NULL)
ctx->method->free(ctx);
free(ctx);
}
@@ -102,10 +100,9 @@ X509_LOOKUP_init(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
return 0;
if (ctx->method->init != NULL)
return ctx->method->init(ctx);
else
if (ctx->method->init == NULL)
return 1;
return ctx->method->init(ctx);
}
int
@@ -113,10 +110,9 @@ X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
return 0;
if (ctx->method->shutdown != NULL)
return ctx->method->shutdown(ctx);
else
if (ctx->method->shutdown == NULL)
return 1;
return ctx->method->shutdown(ctx);
}
int
@@ -125,48 +121,44 @@ X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
{
if (ctx->method == NULL)
return -1;
if (ctx->method->ctrl != NULL)
return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
else
if (ctx->method->ctrl == NULL)
return 1;
return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
}
int
X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, X509_NAME *name,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
return X509_LU_FAIL;
if (ctx->skip)
if (ctx->method == NULL || ctx->method->get_by_subject == NULL)
return 0;
return ctx->method->get_by_subject(ctx, type, name, ret);
}
int
X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
ASN1_INTEGER *serial, X509_OBJECT *ret)
X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
X509_NAME *name, ASN1_INTEGER *serial, X509_OBJECT *ret)
{
if ((ctx->method == NULL) ||
(ctx->method->get_by_issuer_serial == NULL))
return X509_LU_FAIL;
if (ctx->method == NULL || ctx->method->get_by_issuer_serial == NULL)
return 0;
return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
}
int
X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
const unsigned char *bytes, int len, X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
return X509_LU_FAIL;
if (ctx->method == NULL || ctx->method->get_by_fingerprint == NULL)
return 0;
return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
}
int
X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, const char *str, int len,
X509_OBJECT *ret)
X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str,
int len, X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
return X509_LU_FAIL;
if (ctx->method == NULL || ctx->method->get_by_alias == NULL)
return 0;
return ctx->method->get_by_alias(ctx, type, str, len, ret);
}
@@ -175,273 +167,267 @@ x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
{
int ret;
ret = ((*a)->type - (*b)->type);
if (ret)
if ((ret = (*a)->type - (*b)->type) != 0)
return ret;
switch ((*a)->type) {
case X509_LU_X509:
ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
break;
return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
case X509_LU_CRL:
ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
break;
default:
/* abort(); */
return 0;
return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
}
return ret;
return 0;
}
X509_STORE *
X509_STORE_new(void)
{
X509_STORE *ret;
X509_STORE *store;
if ((ret = malloc(sizeof(X509_STORE))) == NULL)
return NULL;
ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
ret->cache = 1;
ret->get_cert_methods = sk_X509_LOOKUP_new_null();
ret->verify = 0;
ret->verify_cb = 0;
if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
if ((store = calloc(1, sizeof(*store))) == NULL)
goto err;
ret->get_issuer = 0;
ret->check_issued = 0;
ret->check_revocation = 0;
ret->get_crl = 0;
ret->check_crl = 0;
ret->cert_crl = 0;
ret->lookup_certs = 0;
ret->lookup_crls = 0;
ret->cleanup = 0;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
if ((store->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
goto err;
if ((store->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
goto err;
if ((store->param = X509_VERIFY_PARAM_new()) == NULL)
goto err;
ret->references = 1;
return ret;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, store,
&store->ex_data))
goto err;
store->references = 1;
return store;
err:
X509error(ERR_R_MALLOC_FAILURE);
X509_STORE_free(store);
err:
X509_VERIFY_PARAM_free(ret->param);
sk_X509_LOOKUP_free(ret->get_cert_methods);
sk_X509_OBJECT_free(ret->objs);
free(ret);
return NULL;
}
static void
X509_OBJECT *
X509_OBJECT_new(void)
{
X509_OBJECT *obj;
if ((obj = calloc(1, sizeof(*obj))) == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return NULL;
}
obj->type = X509_LU_NONE;
return obj;
}
void
X509_OBJECT_free(X509_OBJECT *a)
{
X509_OBJECT_free_contents(a);
if (a == NULL)
return;
switch (a->type) {
case X509_LU_X509:
X509_free(a->data.x509);
break;
case X509_LU_CRL:
X509_CRL_free(a->data.crl);
break;
}
free(a);
}
void
X509_STORE_free(X509_STORE *vfy)
X509_STORE_free(X509_STORE *store)
{
int i;
STACK_OF(X509_LOOKUP) *sk;
X509_LOOKUP *lu;
int i;
if (vfy == NULL)
if (store == NULL)
return;
i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);
if (i > 0)
if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0)
return;
sk = vfy->get_cert_methods;
sk = store->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
lu = sk_X509_LOOKUP_value(sk, i);
X509_LOOKUP_shutdown(lu);
X509_LOOKUP_free(lu);
}
sk_X509_LOOKUP_free(sk);
sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
X509_VERIFY_PARAM_free(vfy->param);
free(vfy);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data);
X509_VERIFY_PARAM_free(store->param);
free(store);
}
int
X509_STORE_up_ref(X509_STORE *x)
X509_STORE_up_ref(X509_STORE *store)
{
int refs = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_STORE);
return (refs > 1) ? 1 : 0;
return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1;
}
X509_LOOKUP *
X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
X509_STORE_add_lookup(X509_STORE *store, X509_LOOKUP_METHOD *method)
{
int i;
STACK_OF(X509_LOOKUP) *sk;
X509_LOOKUP *lu;
int i;
sk = v->get_cert_methods;
sk = store->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
lu = sk_X509_LOOKUP_value(sk, i);
if (m == lu->method) {
if (method == lu->method) {
return lu;
}
}
/* a new one */
lu = X509_LOOKUP_new(m);
if (lu == NULL)
if ((lu = X509_LOOKUP_new(method)) == NULL)
return NULL;
lu->store_ctx = store;
if (sk_X509_LOOKUP_push(store->get_cert_methods, lu) <= 0) {
X509error(ERR_R_MALLOC_FAILURE);
X509_LOOKUP_free(lu);
return NULL;
else {
lu->store_ctx = v;
if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
return lu;
else {
X509_LOOKUP_free(lu);
return NULL;
}
}
return lu;
}
X509_OBJECT *
X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
X509_NAME *name)
{
X509_OBJECT *obj;
if ((obj = X509_OBJECT_new()) == NULL)
return NULL;
if (!X509_STORE_CTX_get_by_subject(vs, type, name, obj)) {
X509_OBJECT_free(obj);
return NULL;
}
return obj;
}
int
X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
X509_OBJECT *ret)
X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
X509_NAME *name, X509_OBJECT *ret)
{
X509_STORE *ctx = vs->ctx;
X509_STORE *ctx = vs->store;
X509_LOOKUP *lu;
X509_OBJECT stmp, *tmp;
int i, j;
int i;
if (ctx == NULL)
return 0;
memset(&stmp, 0, sizeof(stmp));
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (tmp == NULL || type == X509_LU_CRL) {
for (i = vs->current_method;
i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
if (j < 0) {
vs->current_method = j;
return j;
} else if (j) {
if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) {
tmp = &stmp;
break;
}
}
vs->current_method = 0;
if (tmp == NULL)
return 0;
}
/* if (ret->data.ptr != NULL)
X509_OBJECT_free_contents(ret); */
if (!X509_OBJECT_up_ref_count(tmp))
return 0;
ret->type = tmp->type;
ret->data.ptr = tmp->data.ptr;
X509_OBJECT_up_ref_count(ret);
*ret = *tmp;
return 1;
}
/* Add obj to the store. Takes ownership of obj. */
static int
X509_STORE_add_object(X509_STORE *store, X509_OBJECT *obj)
{
int ret = 0;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
if (X509_OBJECT_retrieve_match(store->objs, obj) != NULL) {
/* Object is already present in the store. That's fine. */
ret = 1;
goto out;
}
if (sk_X509_OBJECT_push(store->objs, obj) <= 0) {
X509error(ERR_R_MALLOC_FAILURE);
goto out;
}
obj = NULL;
ret = 1;
out:
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_free(obj);
return ret;
}
int
X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
X509_STORE_add_cert(X509_STORE *store, X509 *x)
{
X509_OBJECT *obj;
int ret = 1;
if (x == NULL)
return 0;
obj = malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
if ((obj = X509_OBJECT_new()) == NULL)
return 0;
if (!X509_up_ref(x)) {
X509_OBJECT_free(obj);
return 0;
}
obj->type = X509_LU_X509;
obj->data.x509 = x;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_up_ref_count(obj);
if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
X509error(X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
} else {
if (sk_X509_OBJECT_push(ctx->objs, obj) == 0) {
X509error(ERR_R_MALLOC_FAILURE);
ret = 0;
}
}
if (ret == 0)
X509_OBJECT_dec_ref_count(obj);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (ret == 0) {
obj->data.x509 = NULL; /* owned by the caller */
X509_OBJECT_free(obj);
}
return ret;
return X509_STORE_add_object(store, obj);
}
int
X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
X509_STORE_add_crl(X509_STORE *store, X509_CRL *x)
{
X509_OBJECT *obj;
int ret = 1;
if (x == NULL)
return 0;
obj = malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
if ((obj = X509_OBJECT_new()) == NULL)
return 0;
if (!X509_CRL_up_ref(x)) {
X509_OBJECT_free(obj);
return 0;
}
obj->type = X509_LU_CRL;
obj->data.crl = x;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_up_ref_count(obj);
if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
X509error(X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
} else {
if (sk_X509_OBJECT_push(ctx->objs, obj) == 0) {
X509error(ERR_R_MALLOC_FAILURE);
ret = 0;
}
}
if (ret == 0)
X509_OBJECT_dec_ref_count(obj);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (ret == 0) {
obj->data.crl = NULL; /* owned by the caller */
X509_OBJECT_free(obj);
}
return ret;
}
static void
X509_OBJECT_dec_ref_count(X509_OBJECT *a)
{
switch (a->type) {
case X509_LU_X509:
CRYPTO_add(&a->data.x509->references, -1, CRYPTO_LOCK_X509);
break;
case X509_LU_CRL:
CRYPTO_add(&a->data.crl->references, -1, CRYPTO_LOCK_X509_CRL);
break;
}
return X509_STORE_add_object(store, obj);
}
int
@@ -456,28 +442,15 @@ X509_OBJECT_up_ref_count(X509_OBJECT *a)
return 1;
}
int
X509_LOOKUP_TYPE
X509_OBJECT_get_type(const X509_OBJECT *a)
{
return a->type;
}
void
X509_OBJECT_free_contents(X509_OBJECT *a)
{
switch (a->type) {
case X509_LU_X509:
X509_free(a->data.x509);
break;
case X509_LU_CRL:
X509_CRL_free(a->data.crl);
break;
}
}
static int
x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name,
int *pnmatch)
x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
X509_NAME *name, int *pnmatch)
{
X509_OBJECT stmp;
X509 x509_s;
@@ -499,7 +472,6 @@ x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name,
crl_info_s.issuer = name;
break;
default:
/* abort(); */
return -1;
}
@@ -507,6 +479,7 @@ x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name,
if (idx >= 0 && pnmatch) {
int tidx;
const X509_OBJECT *tobj, *pstmp;
*pnmatch = 1;
pstmp = &stmp;
for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
@@ -520,13 +493,14 @@ x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name,
}
int
X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name)
X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
X509_NAME *name)
{
return x509_object_idx_cnt(h, type, name, NULL);
}
X509_OBJECT *
X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
X509_NAME *name)
{
int idx;
@@ -553,99 +527,117 @@ X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo)
return NULL;
}
STACK_OF(X509) *
X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
static STACK_OF(X509) *
X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name)
{
int i, idx, cnt;
STACK_OF(X509) *sk;
X509 *x;
STACK_OF(X509) *sk = NULL;
X509 *x = NULL;
X509_OBJECT *obj;
int i, idx, cnt;
sk = sk_X509_new_null();
if (sk == NULL)
return NULL;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0) {
/* Nothing found in cache: do lookup to possibly add new
* objects to cache
*/
X509_OBJECT xobj;
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
sk_X509_free(sk);
return NULL;
}
X509_OBJECT_free_contents(&xobj);
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = x509_object_idx_cnt(ctx->ctx->objs,
X509_LU_X509, nm, &cnt);
if (idx < 0) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
sk_X509_free(sk);
return NULL;
}
}
idx = x509_object_idx_cnt(store->objs, X509_LU_X509, name, &cnt);
if (idx < 0)
goto err;
if ((sk = sk_X509_new_null()) == NULL)
goto err;
for (i = 0; i < cnt; i++, idx++) {
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
obj = sk_X509_OBJECT_value(store->objs, idx);
x = obj->data.x509;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
if (!sk_X509_push(sk, x)) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_free(x);
sk_X509_pop_free(sk, X509_free);
return NULL;
if (!X509_up_ref(x)) {
x = NULL;
goto err;
}
if (!sk_X509_push(sk, x))
goto err;
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return sk;
err:
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
sk_X509_pop_free(sk, X509_free);
X509_free(x);
return NULL;
}
STACK_OF(X509) *
X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name)
{
X509_STORE *store = ctx->store;
STACK_OF(X509) *sk;
X509_OBJECT *obj;
if (store == NULL)
return NULL;
if ((sk = X509_get1_certs_from_cache(store, name)) != NULL)
return sk;
/* Nothing found: do lookup to possibly add new objects to cache. */
obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name);
if (obj == NULL)
return NULL;
X509_OBJECT_free(obj);
return X509_get1_certs_from_cache(store, name);
}
STACK_OF(X509_CRL) *
X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name)
{
X509_STORE *store = ctx->store;
STACK_OF(X509_CRL) *sk = NULL;
X509_CRL *x = NULL;
X509_OBJECT *obj = NULL;
int i, idx, cnt;
STACK_OF(X509_CRL) *sk;
X509_CRL *x;
X509_OBJECT *obj, xobj;
sk = sk_X509_CRL_new_null();
if (sk == NULL)
if (store == NULL)
return 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
*/
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
sk_X509_CRL_free(sk);
/* Always do lookup to possibly add new CRLs to cache */
obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_CRL, name);
if (obj == NULL)
return NULL;
}
X509_OBJECT_free_contents(&xobj);
X509_OBJECT_free(obj);
obj = NULL;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
if (idx < 0) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
sk_X509_CRL_free(sk);
return NULL;
}
idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, name, &cnt);
if (idx < 0)
goto err;
if ((sk = sk_X509_CRL_new_null()) == NULL)
goto err;
for (i = 0; i < cnt; i++, idx++) {
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
obj = sk_X509_OBJECT_value(store->objs, idx);
x = obj->data.crl;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
if (!sk_X509_CRL_push(sk, x)) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_CRL_free(x);
sk_X509_CRL_pop_free(sk, X509_CRL_free);
return NULL;
if (!X509_CRL_up_ref(x)) {
x = NULL;
goto err;
}
if (!sk_X509_CRL_push(sk, x))
goto err;
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return sk;
err:
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_CRL_free(x);
sk_X509_CRL_pop_free(sk, X509_CRL_free);
return NULL;
}
X509_OBJECT *
@@ -688,44 +680,52 @@ X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
* -1 some other error.
*/
int
X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x)
{
X509_NAME *xn;
X509_OBJECT obj, *pobj;
int i, ok, idx, ret;
X509_OBJECT *obj, *pobj;
X509 *issuer = NULL;
int i, idx, ret;
*out_issuer = NULL;
*issuer = NULL;
xn = X509_get_issuer_name(x);
ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
if (ok != X509_LU_X509) {
if (ok == X509_LU_RETRY) {
X509_OBJECT_free_contents(&obj);
X509error(X509_R_SHOULD_RETRY);
return -1;
} else if (ok != X509_LU_FAIL) {
X509_OBJECT_free_contents(&obj);
/* not good :-(, break anyway */
return -1;
}
obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn);
if (obj == NULL)
return 0;
if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) {
X509_OBJECT_free(obj);
return 0;
}
if (!X509_up_ref(issuer)) {
X509_OBJECT_free(obj);
return -1;
}
/* If certificate matches all OK */
if (ctx->check_issued(ctx, x, obj.data.x509)) {
if (x509_check_cert_time(ctx, obj.data.x509, 1)) {
*issuer = obj.data.x509;
if (ctx->check_issued(ctx, x, issuer)) {
if (x509_check_cert_time(ctx, issuer, -1)) {
*out_issuer = issuer;
X509_OBJECT_free(obj);
return 1;
}
}
X509_OBJECT_free_contents(&obj);
X509_free(issuer);
issuer = NULL;
X509_OBJECT_free(obj);
obj = NULL;
if (ctx->store == NULL)
return 0;
/* Else find index of first cert accepted by 'check_issued' */
ret = 0;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
idx = X509_OBJECT_idx_by_subject(ctx->store->objs, X509_LU_X509, xn);
if (idx != -1) /* should be true as we've had at least one match */ {
/* Look through all matching certs for suitable issuer */
for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
for (i = idx; i < sk_X509_OBJECT_num(ctx->store->objs); i++) {
pobj = sk_X509_OBJECT_value(ctx->store->objs, i);
/* See if we've run past the matches */
if (pobj->type != X509_LU_X509)
break;
@@ -733,22 +733,28 @@ X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
X509_get_subject_name(pobj->data.x509)))
break;
if (ctx->check_issued(ctx, x, pobj->data.x509)) {
*issuer = pobj->data.x509;
ret = 1;
issuer = pobj->data.x509;
/*
* If times check, exit with match,
* otherwise keep looking. Leave last
* match in issuer so we return nearest
* match if no certificate time is OK.
*/
if (x509_check_cert_time(ctx, *issuer, 1))
if (x509_check_cert_time(ctx, issuer, -1))
break;
}
}
}
ret = 0;
if (issuer != NULL) {
if (!X509_up_ref(issuer)) {
ret = -1;
} else {
*out_issuer = issuer;
ret = 1;
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (*issuer)
CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
return ret;
}
@@ -808,8 +814,25 @@ X509_STORE_get0_param(X509_STORE *ctx)
}
void
X509_STORE_set_verify_cb(X509_STORE *ctx,
int (*verify_cb)(int, X509_STORE_CTX *))
X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify)
{
ctx->verify_cb = verify_cb;
store->verify = verify;
}
X509_STORE_CTX_verify_fn
X509_STORE_get_verify(X509_STORE *store)
{
return store->verify;
}
void
X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb)
{
store->verify_cb = verify_cb;
}
X509_STORE_CTX_verify_cb
X509_STORE_get_verify_cb(X509_STORE *store)
{
return store->verify_cb;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_ncons.c,v 1.4 2020/09/16 18:12:06 beck Exp $ */
/* $OpenBSD: x509_ncons.c,v 1.5 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@@ -64,6 +64,8 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_obj.c,v 1.18 2018/05/18 18:19:31 tb Exp $ */
/* $OpenBSD: x509_obj.c,v 1.19 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -65,6 +65,8 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
char *
X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_ocsp.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_ocsp.c,v 1.2 2022/01/07 09:45:52 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -69,6 +69,8 @@
#include <openssl/ocsp.h>
#include <openssl/x509v3.h>
#include "ocsp_local.h"
/* OCSP extensions and a couple of CRL entry extensions
*/

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_pci.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* $OpenBSD: x509_pci.c,v 1.2 2021/08/24 15:23:03 tb Exp $ */
/* Contributed to the OpenSSL Project 2004
* by Richard Levitte (richard@levitte.org)
*/
@@ -77,7 +77,8 @@ i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, BIO *out,
i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
BIO_puts(out, "\n");
if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
BIO_printf(out, "%*sPolicy Text: %.*s\n", indent, "",
pci->proxyPolicy->policy->length,
pci->proxyPolicy->policy->data);
return 1;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_prn.c,v 1.1 2020/06/04 15:19:32 jsing Exp $ */
/* $OpenBSD: x509_prn.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -62,6 +62,8 @@
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
/* Extension printing routines */
static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_purp.c,v 1.2 2020/09/13 15:06:17 beck Exp $ */
/* $OpenBSD: x509_purp.c,v 1.13 2021/11/04 23:52:34 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
@@ -65,6 +65,9 @@
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include "x509_internal.h"
#include "x509_lcl.h"
#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
#define ku_reject(x, usage) \
(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
@@ -132,6 +135,8 @@ X509_check_purpose(X509 *x, int id, int ca)
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
if (x->ex_flags & EXFLAG_INVALID)
return -1;
}
if (id == -1)
return 1;
@@ -293,11 +298,7 @@ xptable_free(X509_PURPOSE *p)
void
X509_PURPOSE_cleanup(void)
{
unsigned int i;
sk_X509_PURPOSE_pop_free(xptable, xptable_free);
for(i = 0; i < X509_PURPOSE_COUNT; i++)
xptable_free(xstandard + i);
xptable = NULL;
}
@@ -368,6 +369,10 @@ X509_supported_extension(X509_EXTENSION *ex)
NID_basic_constraints, /* 87 */
NID_certificate_policies, /* 89 */
NID_ext_key_usage, /* 126 */
#ifndef OPENSSL_NO_RFC3779
NID_sbgp_ipAddrBlock, /* 290 */
NID_sbgp_autonomousSysNum, /* 291 */
#endif
NID_policy_constraints, /* 401 */
NID_proxyCertInfo, /* 663 */
NID_name_constraints, /* 666 */
@@ -421,7 +426,12 @@ setup_crldp(X509 *x)
{
int i;
x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL);
if (x->crldp == NULL && i != -1) {
x->ex_flags |= EXFLAG_INVALID;
return;
}
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
}
@@ -440,16 +450,14 @@ x509v3_cache_extensions(X509 *x)
if (x->ex_flags & EXFLAG_SET)
return;
#ifndef OPENSSL_NO_SHA
X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
#endif
X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL);
/* V1 should mean no extensions ... */
if (!X509_get_version(x))
x->ex_flags |= EXFLAG_V1;
/* Handle basic constraints */
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) {
if (bs->ca)
x->ex_flags |= EXFLAG_CA;
if (bs->pathlen) {
@@ -463,10 +471,12 @@ x509v3_cache_extensions(X509 *x)
x->ex_pathlen = -1;
BASIC_CONSTRAINTS_free(bs);
x->ex_flags |= EXFLAG_BCONS;
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
}
/* Handle proxy certificates */
if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &i, NULL))) {
if (x->ex_flags & EXFLAG_CA ||
X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 ||
X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
@@ -485,10 +495,12 @@ x509v3_cache_extensions(X509 *x)
x->ex_pcpathlen = -1;
PROXY_CERT_INFO_EXTENSION_free(pci);
x->ex_flags |= EXFLAG_PROXY;
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
}
/* Handle key usage */
if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL))) {
if (usage->length > 0) {
x->ex_kusage = usage->data[0];
if (usage->length > 1)
@@ -497,9 +509,12 @@ x509v3_cache_extensions(X509 *x)
x->ex_kusage = 0;
x->ex_flags |= EXFLAG_KUSAGE;
ASN1_BIT_STRING_free(usage);
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
}
x->ex_xkusage = 0;
if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL))) {
x->ex_flags |= EXFLAG_XKUSAGE;
for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
@@ -535,22 +550,34 @@ x509v3_cache_extensions(X509 *x)
case NID_dvcs:
x->ex_xkusage |= XKU_DVCS;
break;
case NID_anyExtendedKeyUsage:
x->ex_xkusage |= XKU_ANYEKU;
break;
}
}
sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
}
if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL))) {
if (ns->length > 0)
x->ex_nscert = ns->data[0];
else
x->ex_nscert = 0;
x->ex_flags |= EXFLAG_NSCERT;
ASN1_BIT_STRING_free(ns);
} else if (i != -1) {
x->ex_flags |= EXFLAG_INVALID;
}
x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL);
if (x->skid == NULL && i != -1)
x->ex_flags |= EXFLAG_INVALID;
x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL);
if (x->akid == NULL && i != -1)
x->ex_flags |= EXFLAG_INVALID;
/* Does subject name match issuer? */
if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
@@ -561,12 +588,23 @@ x509v3_cache_extensions(X509 *x)
x->ex_flags |= EXFLAG_SS;
}
x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &i, NULL);
if (x->altname == NULL && i != -1)
x->ex_flags |= EXFLAG_INVALID;
x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
if (!x->nc && (i != -1))
x->ex_flags |= EXFLAG_INVALID;
setup_crldp(x);
#ifndef OPENSSL_NO_RFC3779
x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
if (x->rfc3779_addr == NULL && i != -1)
x->ex_flags |= EXFLAG_INVALID;
x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL);
if (x->rfc3779_asid == NULL && i != -1)
x->ex_flags |= EXFLAG_INVALID;
#endif
for (i = 0; i < X509_get_ext_count(x); i++) {
ex = X509_get_ext(x, i);
if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) ==
@@ -579,6 +617,9 @@ x509v3_cache_extensions(X509 *x)
break;
}
}
x509_verify_cert_info_populate(x);
x->ex_flags |= EXFLAG_SET;
}
@@ -626,6 +667,8 @@ X509_check_ca(X509 *x)
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
if (x->ex_flags & EXFLAG_INVALID)
return X509_V_ERR_UNSPECIFIED;
}
return check_ca(x);
@@ -836,8 +879,20 @@ X509_check_issued(X509 *issuer, X509 *subject)
if (X509_NAME_cmp(X509_get_subject_name(issuer),
X509_get_issuer_name(subject)))
return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
x509v3_cache_extensions(issuer);
x509v3_cache_extensions(subject);
if (!(issuer->ex_flags & EXFLAG_SET)) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(issuer);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
if (issuer->ex_flags & EXFLAG_INVALID)
return X509_V_ERR_UNSPECIFIED;
if (!(subject->ex_flags & EXFLAG_SET)) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(subject);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
if (subject->ex_flags & EXFLAG_INVALID)
return X509_V_ERR_UNSPECIFIED;
if (subject->akid) {
int ret = X509_check_akid(issuer, subject->akid);
@@ -891,3 +946,39 @@ X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
}
return X509_V_OK;
}
uint32_t
X509_get_extension_flags(X509 *x)
{
/* Call for side-effect of computing hash and caching extensions */
if (X509_check_purpose(x, -1, -1) != 1)
return 0;
return x->ex_flags;
}
uint32_t
X509_get_key_usage(X509 *x)
{
/* Call for side-effect of computing hash and caching extensions */
if (X509_check_purpose(x, -1, -1) != 1)
return 0;
if (x->ex_flags & EXFLAG_KUSAGE)
return x->ex_kusage;
return UINT32_MAX;
}
uint32_t
X509_get_extended_key_usage(X509 *x)
{
/* Call for side-effect of computing hash and caching extensions */
if (X509_check_purpose(x, -1, -1) != 1)
return 0;
if (x->ex_flags & EXFLAG_XKUSAGE)
return x->ex_xkusage;
return UINT32_MAX;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_r2x.c,v 1.11 2017/01/29 17:49:23 beck Exp $ */
/* $OpenBSD: x509_r2x.c,v 1.13 2021/11/03 14:36:21 schwarze Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,12 +66,15 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
X509 *
X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
{
X509 *ret = NULL;
X509_CINF *xi = NULL;
X509_NAME *xn;
EVP_PKEY *pubkey;
if ((ret = X509_new()) == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
@@ -86,14 +89,12 @@ X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
goto err;
if (!ASN1_INTEGER_set(xi->version, 2))
goto err;
/* xi->extensions=ri->attributes; <- bad, should not ever be done
ri->attributes=NULL; */
}
xn = X509_REQ_get_subject_name(r);
if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
if (X509_set_subject_name(ret, xn) == 0)
goto err;
if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
if (X509_set_issuer_name(ret, xn) == 0)
goto err;
if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
@@ -102,14 +103,16 @@ X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
(long)60 * 60 * 24 * days) == NULL)
goto err;
X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
if ((pubkey = X509_REQ_get0_pubkey(r)) == NULL)
goto err;
if (!X509_set_pubkey(ret, pubkey))
goto err;
if (!X509_sign(ret, pkey, EVP_md5()))
goto err;
if (0) {
return ret;
err:
X509_free(ret);
ret = NULL;
}
return (ret);
X509_free(ret);
return NULL;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_req.c,v 1.21 2018/05/13 06:48:00 tb Exp $ */
/* $OpenBSD: x509_req.c,v 1.28 2022/01/22 00:34:48 inoguchi Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -70,6 +70,9 @@
#include <openssl/pem.h>
#include <openssl/x509.h>
#include "evp_locl.h"
#include "x509_lcl.h"
X509_REQ *
X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
@@ -121,13 +124,23 @@ X509_REQ_get_pubkey(X509_REQ *req)
return (X509_PUBKEY_get(req->req_info->pubkey));
}
EVP_PKEY *
X509_REQ_get0_pubkey(X509_REQ *req)
{
if (req == NULL || req->req_info == NULL)
return NULL;
return X509_PUBKEY_get0(req->req_info->pubkey);
}
int
X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
{
EVP_PKEY *xk = NULL;
int ok = 0;
xk = X509_REQ_get_pubkey(x);
if ((xk = X509_REQ_get0_pubkey(x)) == NULL)
return 0;
switch (EVP_PKEY_cmp(xk, k)) {
case 1:
ok = 1;
@@ -155,7 +168,6 @@ X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
X509error(X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
return (ok);
}
@@ -202,66 +214,43 @@ X509_REQ_get_extensions(X509_REQ *req)
int idx, *pnid;
const unsigned char *p;
if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
return (NULL);
if (req == NULL || req->req_info == NULL || ext_nids == NULL)
return NULL;
for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
if (idx == -1)
continue;
attr = X509_REQ_get_attr(req, idx);
if (attr->single)
ext = attr->value.single;
else if (sk_ASN1_TYPE_num(attr->value.set))
ext = sk_ASN1_TYPE_value(attr->value.set, 0);
ext = X509_ATTRIBUTE_get0_type(attr, 0);
break;
}
if (!ext || (ext->type != V_ASN1_SEQUENCE))
if (ext == NULL || ext->type != V_ASN1_SEQUENCE)
return NULL;
p = ext->value.sequence->data;
return (STACK_OF(X509_EXTENSION) *)ASN1_item_d2i(NULL, &p,
ext->value.sequence->length, &X509_EXTENSIONS_it);
return d2i_X509_EXTENSIONS(NULL, &p, ext->value.sequence->length);
}
/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
* in case we want to create a non standard one.
/*
* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
* in case we want to create a non-standard one.
*/
int
X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
int nid)
{
ASN1_TYPE *at = NULL;
X509_ATTRIBUTE *attr = NULL;
unsigned char *ext = NULL;
int extlen;
int rv;
if (!(at = ASN1_TYPE_new()) ||
!(at->value.sequence = ASN1_STRING_new()))
goto err;
extlen = i2d_X509_EXTENSIONS(exts, &ext);
if (extlen <= 0)
return 0;
at->type = V_ASN1_SEQUENCE;
/* Generate encoding of extensions */
at->value.sequence->length = ASN1_item_i2d((ASN1_VALUE *)exts,
&at->value.sequence->data, &X509_EXTENSIONS_it);
if (!(attr = X509_ATTRIBUTE_new()))
goto err;
if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
goto err;
if (!sk_ASN1_TYPE_push(attr->value.set, at))
goto err;
at = NULL;
attr->single = 0;
attr->object = OBJ_nid2obj(nid);
if (!req->req_info->attributes) {
if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
goto err;
}
if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
goto err;
return 1;
rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen);
free(ext);
err:
X509_ATTRIBUTE_free(attr);
ASN1_TYPE_free(at);
return 0;
return rv;
}
/* This is the normal usage: use the "official" OID */
@@ -341,3 +330,10 @@ X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type,
return 1;
return 0;
}
int
i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
{
req->req_info->enc.modified = 1;
return i2d_X509_REQ_INFO(req->req_info, pp);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_set.c,v 1.17 2018/08/24 19:55:58 tb Exp $ */
/* $OpenBSD: x509_set.c,v 1.20 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -63,6 +63,8 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
const STACK_OF(X509_EXTENSION) *
X509_get0_extensions(const X509 *x)
{
@@ -216,3 +218,9 @@ X509_get_signature_type(const X509 *x)
{
return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm));
}
X509_PUBKEY *
X509_get_X509_PUBKEY(const X509 *x)
{
return x->cert_info->key;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_skey.c,v 1.1 2020/06/04 15:19:32 jsing Exp $ */
/* $OpenBSD: x509_skey.c,v 1.2 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -62,6 +62,8 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, char *str);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_trs.c,v 1.23 2018/05/18 18:40:38 tb Exp $ */
/* $OpenBSD: x509_trs.c,v 1.25 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -62,6 +62,8 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static int tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b);
static void trtable_free(X509_TRUST *p);
@@ -265,10 +267,6 @@ trtable_free(X509_TRUST *p)
void
X509_TRUST_cleanup(void)
{
unsigned int i;
for (i = 0; i < X509_TRUST_COUNT; i++)
trtable_free(trstandard + i);
sk_X509_TRUST_pop_free(trtable, trtable_free);
trtable = NULL;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_v3.c,v 1.17 2018/05/19 10:54:40 tb Exp $ */
/* $OpenBSD: x509_v3.c,v 1.18 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,6 +66,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
int
X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_vfy.c,v 1.81 2020/09/26 02:06:28 deraadt Exp $ */
/* $OpenBSD: x509_vfy.c,v 1.101 2022/01/22 00:36:46 inoguchi Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -76,8 +76,6 @@
#include "asn1_locl.h"
#include "vpm_int.h"
#include "x509_internal.h"
#include "x509_lcl.h"
#include "x509_internal.h"
/* CRL score values */
@@ -240,12 +238,13 @@ x509_vfy_check_id(X509_STORE_CTX *ctx) {
* Oooooooh..
*/
static int
X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad, int *out_ok)
{
X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
int bad_chain = 0;
X509_VERIFY_PARAM *param = ctx->param;
int depth, i, ok = 0;
int ok = 0, ret = 0;
int depth, i;
int num, j, retry, trust;
int (*cb) (int xok, X509_STORE_CTX *xctx);
STACK_OF(X509) *sktmp = NULL;
@@ -263,7 +262,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
goto end;
}
X509_up_ref(ctx->cert);
ctx->last_untrusted = 1;
ctx->num_untrusted = 1;
/* We use a temporary STACK so we can chop and hack at it */
if (ctx->untrusted != NULL &&
@@ -337,7 +336,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
}
X509_up_ref(xtmp);
(void)sk_X509_delete_ptr(sktmp, xtmp);
ctx->last_untrusted++;
ctx->num_untrusted++;
x = xtmp;
num++;
/*
@@ -395,7 +394,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
X509_free(x);
x = xtmp;
(void)sk_X509_set(ctx->chain, i - 1, x);
ctx->last_untrusted = 0;
ctx->num_untrusted = 0;
}
} else {
/*
@@ -403,7 +402,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
* certificate for later use
*/
chain_ss = sk_X509_pop(ctx->chain);
ctx->last_untrusted--;
ctx->num_untrusted--;
num--;
j--;
x = sk_X509_value(ctx->chain, num - 1);
@@ -477,7 +476,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
X509_free(xtmp);
num--;
}
ctx->last_untrusted = sk_X509_num(ctx->chain);
ctx->num_untrusted = sk_X509_num(ctx->chain);
retry = 1;
break;
}
@@ -492,7 +491,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
*/
if (trust != X509_TRUST_TRUSTED && !bad_chain) {
if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
if (ctx->last_untrusted >= num)
if (ctx->num_untrusted >= num)
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
else
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
@@ -505,7 +504,7 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
goto end;
}
num++;
ctx->last_untrusted = num;
ctx->num_untrusted = num;
ctx->current_cert = chain_ss;
ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
chain_ss = NULL;
@@ -517,11 +516,15 @@ X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
if (!ok)
goto end;
}
ret = 1;
end:
sk_X509_free(sktmp);
X509_free(chain_ss);
*bad = bad_chain;
return ok;
*out_ok = ok;
return ret;
}
static int
@@ -531,8 +534,7 @@ X509_verify_cert_legacy(X509_STORE_CTX *ctx)
ctx->error = X509_V_OK; /* Initialize to OK */
ok = X509_verify_cert_legacy_build_chain(ctx, &bad_chain);
if (!ok)
if (!X509_verify_cert_legacy_build_chain(ctx, &bad_chain, &ok))
goto end;
/* We have the chain complete: now we need to check its purpose */
@@ -545,6 +547,16 @@ X509_verify_cert_legacy(X509_STORE_CTX *ctx)
if (!ok)
goto end;
#ifndef OPENSSL_NO_RFC3779
ok = X509v3_asid_validate_path(ctx);
if (!ok)
goto end;
ok = X509v3_addr_validate_path(ctx);
if (!ok)
goto end;
#endif
ok = check_id(ctx);
if (!ok)
goto end;
@@ -630,60 +642,13 @@ X509_verify_cert(X509_STORE_CTX *ctx)
/* Use the modern multi-chain verifier from x509_verify_cert */
/* Find our trusted roots */
ctx->error = X509_V_ERR_OUT_OF_MEM;
if (ctx->get_issuer == get_issuer_sk) {
/*
* We are using the trusted stack method. so
* the roots are in the aptly named "ctx->other_ctx"
* pointer. (It could have been called "al")
*/
if ((roots = X509_chain_up_ref(ctx->other_ctx)) == NULL)
return -1;
} else {
/*
* We have a X509_STORE and need to pull out the roots.
* Don't look Ethel...
*/
STACK_OF(X509_OBJECT) *objs;
size_t i, good = 1;
if ((roots = sk_X509_new_null()) == NULL)
return -1;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
if ((objs = X509_STORE_get0_objects(ctx->ctx)) == NULL)
good = 0;
for (i = 0; good && i < sk_X509_OBJECT_num(objs); i++) {
X509_OBJECT *obj;
X509 *root;
obj = sk_X509_OBJECT_value(objs, i);
if (obj->type != X509_LU_X509)
continue;
root = obj->data.x509;
if (X509_up_ref(root) == 0)
good = 0;
if (sk_X509_push(roots, root) == 0) {
X509_free(root);
good = 0;
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (!good) {
sk_X509_pop_free(roots, X509_free);
return -1;
}
}
if ((vctx = x509_verify_ctx_new_from_xsc(ctx, roots)) != NULL) {
if ((vctx = x509_verify_ctx_new_from_xsc(ctx)) != NULL) {
ctx->error = X509_V_OK; /* Initialize to OK */
chain_count = x509_verify(vctx, NULL, NULL);
}
x509_verify_ctx_free(vctx);
sk_X509_pop_free(roots, X509_free);
x509_verify_ctx_free(vctx);
/* if we succeed we have a chain in ctx->chain */
return (chain_count > 0 && ctx->chain != NULL);
@@ -784,7 +749,7 @@ x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx)
}
/* Check all untrusted certificates */
for (i = 0; i < ctx->last_untrusted; i++) {
for (i = 0; i < ctx->num_untrusted; i++) {
int ret;
x = sk_X509_value(ctx->chain, i);
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
@@ -910,7 +875,8 @@ check_name_constraints(X509_STORE_CTX *ctx)
/* Given a certificate try and find an exact match in the store */
static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
static X509 *
lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
{
STACK_OF(X509) *certs;
X509 *xtmp = NULL;
@@ -937,7 +903,17 @@ static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
return xtmp;
}
static int check_trust(X509_STORE_CTX *ctx)
X509 *
x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
{
if (ctx->lookup_certs == NULL || ctx->store == NULL ||
ctx->store->objs == NULL)
return NULL;
return lookup_cert_match(ctx, x);
}
static int
check_trust(X509_STORE_CTX *ctx)
{
size_t i;
int ok;
@@ -946,7 +922,7 @@ static int check_trust(X509_STORE_CTX *ctx)
cb = ctx->verify_cb;
/* Check all trusted certificates in chain */
for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
for (i = ctx->num_untrusted; i < sk_X509_num(ctx->chain); i++) {
x = sk_X509_value(ctx->chain, i);
ok = X509_check_trust(x, ctx->param->trust, 0);
@@ -972,14 +948,14 @@ static int check_trust(X509_STORE_CTX *ctx)
*/
if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
X509 *mx;
if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
if (ctx->num_untrusted < (int)sk_X509_num(ctx->chain))
return X509_TRUST_TRUSTED;
x = sk_X509_value(ctx->chain, 0);
mx = lookup_cert_match(ctx, x);
if (mx) {
(void)sk_X509_set(ctx->chain, 0, mx);
X509_free(x);
ctx->last_untrusted = 0;
ctx->num_untrusted = 0;
return X509_TRUST_TRUSTED;
}
}
@@ -991,7 +967,8 @@ static int check_trust(X509_STORE_CTX *ctx)
return X509_TRUST_UNTRUSTED;
}
int x509_vfy_check_trust(X509_STORE_CTX *ctx)
int
x509_vfy_check_trust(X509_STORE_CTX *ctx)
{
return check_trust(ctx);
}
@@ -1103,17 +1080,17 @@ err:
static int
check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
{
time_t *ptime = NULL;
time_t *ptime;
int i;
if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
return (1);
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
if (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;
i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
if (i == 0) {
@@ -1438,7 +1415,7 @@ check_crl_path(X509_STORE_CTX *ctx, X509 *x)
/* Don't allow recursive CRL path validation */
if (ctx->parent)
return 0;
if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) {
if (!X509_STORE_CTX_init(&crl_ctx, ctx->store, x, ctx->untrusted)) {
ret = -1;
goto err;
}
@@ -1794,6 +1771,11 @@ x509_vfy_check_policy(X509_STORE_CTX *ctx)
if (ctx->parent)
return 1;
/* X509_policy_check always allocates a new tree. */
X509_policy_tree_free(ctx->tree);
ctx->tree = NULL;
ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
ctx->param->policies, ctx->param->flags);
if (ret == 0) {
@@ -1861,6 +1843,18 @@ verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err)
return ctx->verify_cb(0, ctx);
}
/* Mimic OpenSSL '0 for failure' ick */
static int
time_t_bogocmp(time_t a, time_t b)
{
if (a == -1 || b == -1)
return 0;
if (a <= b)
return -1;
return 1;
}
/*
* Check certificate validity times.
*
@@ -1872,17 +1866,21 @@ verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err)
int
x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
{
time_t *ptime;
time_t ptime;
int i;
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
ptime = ctx->param->check_time;
else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
return 1;
else
ptime = NULL;
ptime = time(NULL);
if (x->ex_flags & EXFLAG_SET)
i = time_t_bogocmp(x->not_before, ptime);
else
i = X509_cmp_time(X509_get_notBefore(x), &ptime);
i = X509_cmp_time(X509_get_notBefore(x), ptime);
if (i >= 0 && depth < 0)
return 0;
if (i == 0 && !verify_cb_cert(ctx, x, depth,
@@ -1892,7 +1890,11 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
X509_V_ERR_CERT_NOT_YET_VALID))
return 0;
i = X509_cmp_time_internal(X509_get_notAfter(x), ptime, 1);
if (x->ex_flags & EXFLAG_SET)
i = time_t_bogocmp(x->not_after, ptime);
else
i = X509_cmp_time_internal(X509_get_notAfter(x), &ptime, 1);
if (i <= 0 && depth < 0)
return 0;
if (i == 0 && !verify_cb_cert(ctx, x, depth,
@@ -1901,11 +1903,12 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
if (i < 0 && !verify_cb_cert(ctx, x, depth,
X509_V_ERR_CERT_HAS_EXPIRED))
return 0;
return 1;
}
static int
internal_verify(X509_STORE_CTX *ctx)
x509_vfy_internal_verify(X509_STORE_CTX *ctx, int chain_verified)
{
int n = sk_X509_num(ctx->chain) - 1;
X509 *xi = sk_X509_value(ctx->chain, n);
@@ -1941,8 +1944,8 @@ internal_verify(X509_STORE_CTX *ctx)
* certificate and its depth (rather than the depth of
* the subject).
*/
if (xs != xi ||
(ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
if (!chain_verified && ( xs != xi ||
(ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
EVP_PKEY *pkey;
if ((pkey = X509_get_pubkey(xi)) == NULL) {
if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n,
@@ -1959,7 +1962,7 @@ internal_verify(X509_STORE_CTX *ctx)
}
check_cert:
/* Calls verify callback as needed */
if (!x509_check_cert_time(ctx, xs, n))
if (!chain_verified && !x509_check_cert_time(ctx, xs, n))
return 0;
/*
@@ -1980,6 +1983,22 @@ check_cert:
return 1;
}
static int
internal_verify(X509_STORE_CTX *ctx)
{
return x509_vfy_internal_verify(ctx, 0);
}
/*
* Internal verify, but with a chain where the verification
* math has already been performed.
*/
int
x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx)
{
return x509_vfy_internal_verify(ctx, 1);
}
int
X509_cmp_current_time(const ASN1_TIME *ctm)
{
@@ -2000,30 +2019,23 @@ X509_cmp_current_time(const ASN1_TIME *ctm)
* 0 on error.
*/
static int
X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int clamp_notafter)
X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int is_notafter)
{
time_t compare;
struct tm tm1, tm2;
int ret = 0;
time_t compare, cert_time;
if (cmp_time == NULL)
compare = time(NULL);
else
compare = *cmp_time;
memset(&tm1, 0, sizeof(tm1));
if ((cert_time = x509_verify_asn1_time_to_time_t(ctm, is_notafter)) ==
-1)
return 0; /* invalid time */
if (!x509_verify_asn1_time_to_tm(ctm, &tm1, clamp_notafter))
goto out; /* invalid time */
if (cert_time <= compare)
return -1; /* 0 is used for error, so map same to less than */
if (gmtime_r(&compare, &tm2) == NULL)
goto out;
ret = ASN1_time_tm_cmp(&tm1, &tm2);
if (ret == 0)
ret = -1; /* 0 is used for error, so map same to less than */
out:
return (ret);
return 1;
}
int
@@ -2067,17 +2079,15 @@ X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
return 1;
for (i = 0; i < sk_X509_num(chain); i++) {
ktmp = X509_get_pubkey(sk_X509_value(chain, i));
ktmp = X509_get0_pubkey(sk_X509_value(chain, i));
if (ktmp == NULL) {
X509error(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
return 0;
}
if (!EVP_PKEY_missing_parameters(ktmp))
break;
else {
EVP_PKEY_free(ktmp);
else
ktmp = NULL;
}
}
if (ktmp == NULL) {
X509error(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
@@ -2086,14 +2096,15 @@ X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
/* first, populate the other certs */
for (j = i - 1; j >= 0; j--) {
ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
EVP_PKEY_copy_parameters(ktmp2, ktmp);
EVP_PKEY_free(ktmp2);
if ((ktmp2 = X509_get0_pubkey(sk_X509_value(chain, j))) == NULL)
return 0;
if (!EVP_PKEY_copy_parameters(ktmp2, ktmp))
return 0;
}
if (pkey != NULL)
EVP_PKEY_copy_parameters(pkey, ktmp);
EVP_PKEY_free(ktmp);
if (!EVP_PKEY_copy_parameters(pkey, ktmp))
return 0;
return 1;
}
@@ -2137,12 +2148,24 @@ X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
return ctx->error_depth;
}
void
X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth)
{
ctx->error_depth = depth;
}
X509 *
X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
{
return ctx->current_cert;
}
void
X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x)
{
ctx->current_cert = x;
}
STACK_OF(X509) *
X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
{
@@ -2192,7 +2215,7 @@ X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
X509_STORE *
X509_STORE_CTX_get0_store(X509_STORE_CTX *xs)
{
return xs->ctx;
return xs->store;
}
void
@@ -2332,7 +2355,7 @@ X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
* may fail should go last to make sure 'ctx' is as consistent as
* possible even on early exits.
*/
ctx->ctx = store;
ctx->store = store;
ctx->cert = x509;
ctx->untrusted = chain;
@@ -2482,6 +2505,12 @@ X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
X509_VERIFY_PARAM_set_time(ctx->param, t);
}
int
(*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *)
{
return ctx->verify_cb;
}
void
X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
int (*verify_cb)(int, X509_STORE_CTX *))
@@ -2489,6 +2518,18 @@ X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
ctx->verify_cb = verify_cb;
}
int
(*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *)
{
return ctx->verify;
}
void
X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, int (*verify)(X509_STORE_CTX *))
{
ctx->verify = verify;
}
X509 *
X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
{
@@ -2507,6 +2548,13 @@ X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
ctx->untrusted = sk;
}
void
X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
{
sk_X509_pop_free(ctx->chain, X509_free);
ctx->chain = sk;
}
X509_POLICY_TREE *
X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
{
@@ -2519,6 +2567,12 @@ X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
return ctx->explicit_policy;
}
int
X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
{
return ctx->num_untrusted;
}
int
X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509_vpm.c,v 1.22 2020/09/14 08:10:04 beck Exp $ */
/* $OpenBSD: x509_vpm.c,v 1.28 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2004.
*/
@@ -67,6 +67,7 @@
#include <openssl/x509v3.h>
#include "vpm_int.h"
#include "x509_lcl.h"
/* X509_VERIFY_PARAM functions */
@@ -172,6 +173,7 @@ x509_verify_param_zero(X509_VERIFY_PARAM *param)
X509_VERIFY_PARAM_ID *paramid;
if (!param)
return;
free(param->name);
param->name = NULL;
param->purpose = 0;
param->trust = 0;
@@ -207,7 +209,7 @@ X509_VERIFY_PARAM_new(void)
param = calloc(1, sizeof(X509_VERIFY_PARAM));
if (param == NULL)
return NULL;
paramid = calloc (1, sizeof(X509_VERIFY_PARAM_ID));
paramid = calloc(1, sizeof(X509_VERIFY_PARAM_ID));
if (paramid == NULL) {
free(param);
return NULL;
@@ -227,7 +229,8 @@ X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
free(param);
}
/* This function determines how parameters are "inherited" from one structure
/*
* 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
@@ -596,6 +599,7 @@ static const X509_VERIFY_PARAM_ID _empty_id = { NULL };
static const X509_VERIFY_PARAM default_table[] = {
{
.name = "default",
.flags = X509_V_FLAG_TRUSTED_FIRST,
.depth = 100,
.trust = 0, /* XXX This is not the default trust value */
.id = vpm_empty_id
@@ -673,8 +677,8 @@ X509_VERIFY_PARAM_get_count(void)
return num;
}
const
X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
const X509_VERIFY_PARAM *
X509_VERIFY_PARAM_get0(int id)
{
int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
if (id < num)
@@ -682,8 +686,8 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
return sk_X509_VERIFY_PARAM_value(param_table, id - num);
}
const
X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
const X509_VERIFY_PARAM *
X509_VERIFY_PARAM_lookup(const char *name)
{
X509_VERIFY_PARAM pm;
unsigned int i, limit;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509cset.c,v 1.14 2018/02/22 17:01:44 jsing Exp $ */
/* $OpenBSD: x509cset.c,v 1.16 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
@@ -63,8 +63,10 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
int
X509_CRL_up_ref(X509_CRL *x)
X509_CRL_up_ref(X509_CRL *x)
{
int refs = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
return (refs > 1) ? 1 : 0;
@@ -208,3 +210,10 @@ X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
}
return (in != NULL);
}
int
i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp)
{
crl->crl->enc.modified = 1;
return i2d_X509_CRL_INFO(crl->crl, pp);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509name.c,v 1.26 2018/05/30 15:35:45 tb Exp $ */
/* $OpenBSD: x509name.c,v 1.27 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,6 +66,8 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
int
X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509rset.c,v 1.7 2018/08/24 19:55:58 tb Exp $ */
/* $OpenBSD: x509rset.c,v 1.9 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -63,11 +63,14 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
int
X509_REQ_set_version(X509_REQ *x, long version)
{
if (x == NULL)
return (0);
x->req_info->enc.modified = 1;
return (ASN1_INTEGER_set(x->req_info->version, version));
}
@@ -82,6 +85,7 @@ X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
{
if ((x == NULL) || (x->req_info == NULL))
return (0);
x->req_info->enc.modified = 1;
return (X509_NAME_set(&x->req_info->subject, name));
}
@@ -96,5 +100,6 @@ X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
{
if ((x == NULL) || (x->req_info == NULL))
return (0);
x->req_info->enc.modified = 1;
return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x509type.c,v 1.13 2018/05/30 15:59:33 tb Exp $ */
/* $OpenBSD: x509type.c,v 1.15 2021/12/12 21:30:14 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -62,6 +62,9 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "evp_locl.h"
#include "x509_lcl.h"
int
X509_certificate_type(const X509 *x, const EVP_PKEY *pkey)
{

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_all.c,v 1.23 2016/12/30 15:24:51 jsing Exp $ */
/* $OpenBSD: x_all.c,v 1.25 2021/12/03 16:46:50 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -73,6 +73,8 @@
#include <openssl/rsa.h>
#endif
#include "x509_lcl.h"
X509 *
d2i_X509_bio(BIO *bp, X509 **x509)
{
@@ -217,31 +219,6 @@ i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(&RSAPublicKey_it, fp, rsa);
}
RSA *
d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
{
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
}
int
i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
{
return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa);
}
int
i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
{
return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa);
}
RSA *
d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
{
return ASN1_d2i_fp((void *(*)(void))RSA_new,
(D2I_OF(void))d2i_RSA_PUBKEY, fp, (void **)rsa);
}
#endif
#ifndef OPENSSL_NO_DSA
@@ -268,30 +245,6 @@ i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
{
return ASN1_item_i2d_fp(&DSAPrivateKey_it, fp, dsa);
}
DSA *
d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
{
return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
}
int
i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
{
return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa);
}
DSA *
d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
{
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
}
int
i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
{
return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa);
}
#endif
#ifndef OPENSSL_NO_EC
@@ -318,29 +271,6 @@ i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
}
EC_KEY *
d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
{
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
}
int
i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
{
return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
}
EC_KEY *
d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
{
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
}
int
i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
}
#endif
X509_SIG *
@@ -421,30 +351,6 @@ i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
}
EVP_PKEY *
d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
{
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
}
int
i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
}
int
i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
}
EVP_PKEY *
d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
{
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
}
int
i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
{