From eb8dd9dca1228af0cd132f515509051ecfabf6f6 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Mon, 14 Apr 2025 17:32:06 +0000 Subject: This commit was manufactured by cvs2git to create tag 'tb_20250414'. --- src/lib/libcrypto/x509/by_dir.c | 407 ----- src/lib/libcrypto/x509/by_file.c | 262 --- src/lib/libcrypto/x509/by_mem.c | 136 -- src/lib/libcrypto/x509/x509.h | 1041 ----------- src/lib/libcrypto/x509/x509_addr.c | 2074 ---------------------- src/lib/libcrypto/x509/x509_akey.c | 245 --- src/lib/libcrypto/x509/x509_akeya.c | 129 -- src/lib/libcrypto/x509/x509_alt.c | 799 --------- src/lib/libcrypto/x509/x509_asid.c | 1255 -------------- src/lib/libcrypto/x509/x509_att.c | 377 ---- src/lib/libcrypto/x509/x509_bcons.c | 212 --- src/lib/libcrypto/x509/x509_bitst.c | 240 --- src/lib/libcrypto/x509/x509_cmp.c | 429 ----- src/lib/libcrypto/x509/x509_conf.c | 456 ----- src/lib/libcrypto/x509/x509_constraints.c | 1294 -------------- src/lib/libcrypto/x509/x509_cpols.c | 773 --------- src/lib/libcrypto/x509/x509_crld.c | 852 --------- src/lib/libcrypto/x509/x509_d2.c | 131 -- src/lib/libcrypto/x509/x509_def.c | 103 -- src/lib/libcrypto/x509/x509_err.c | 215 --- src/lib/libcrypto/x509/x509_ext.c | 258 --- src/lib/libcrypto/x509/x509_extku.c | 236 --- src/lib/libcrypto/x509/x509_genn.c | 541 ------ src/lib/libcrypto/x509/x509_ia5.c | 268 --- src/lib/libcrypto/x509/x509_info.c | 331 ---- src/lib/libcrypto/x509/x509_int.c | 136 -- src/lib/libcrypto/x509/x509_internal.h | 141 -- src/lib/libcrypto/x509/x509_issuer_cache.c | 193 --- src/lib/libcrypto/x509/x509_issuer_cache.h | 48 - src/lib/libcrypto/x509/x509_lib.c | 374 ---- src/lib/libcrypto/x509/x509_local.h | 503 ------ src/lib/libcrypto/x509/x509_lu.c | 883 ---------- src/lib/libcrypto/x509/x509_ncons.c | 569 ------ src/lib/libcrypto/x509/x509_obj.c | 198 --- src/lib/libcrypto/x509/x509_ocsp.c | 424 ----- src/lib/libcrypto/x509/x509_pcons.c | 205 --- src/lib/libcrypto/x509/x509_pku.c | 165 -- src/lib/libcrypto/x509/x509_pmaps.c | 247 --- src/lib/libcrypto/x509/x509_policy.c | 1018 ----------- src/lib/libcrypto/x509/x509_prn.c | 231 --- src/lib/libcrypto/x509/x509_purp.c | 930 ---------- src/lib/libcrypto/x509/x509_r2x.c | 117 -- src/lib/libcrypto/x509/x509_req.c | 320 ---- src/lib/libcrypto/x509/x509_set.c | 268 --- src/lib/libcrypto/x509/x509_siginfo.c | 113 -- src/lib/libcrypto/x509/x509_skey.c | 171 -- src/lib/libcrypto/x509/x509_trs.c | 173 -- src/lib/libcrypto/x509/x509_txt.c | 196 --- src/lib/libcrypto/x509/x509_utl.c | 1494 ---------------- src/lib/libcrypto/x509/x509_v3.c | 295 ---- src/lib/libcrypto/x509/x509_verify.c | 1288 -------------- src/lib/libcrypto/x509/x509_verify.h | 43 - src/lib/libcrypto/x509/x509_vfy.c | 2602 ---------------------------- src/lib/libcrypto/x509/x509_vfy.h | 463 ----- src/lib/libcrypto/x509/x509_vpm.c | 743 -------- src/lib/libcrypto/x509/x509cset.c | 238 --- src/lib/libcrypto/x509/x509name.c | 452 ----- src/lib/libcrypto/x509/x509rset.c | 113 -- src/lib/libcrypto/x509/x509spki.c | 136 -- src/lib/libcrypto/x509/x509type.c | 136 -- src/lib/libcrypto/x509/x509v3.h | 1041 ----------- src/lib/libcrypto/x509/x_all.c | 536 ------ 62 files changed, 30267 deletions(-) delete mode 100644 src/lib/libcrypto/x509/by_dir.c delete mode 100644 src/lib/libcrypto/x509/by_file.c delete mode 100644 src/lib/libcrypto/x509/by_mem.c delete mode 100644 src/lib/libcrypto/x509/x509.h delete mode 100644 src/lib/libcrypto/x509/x509_addr.c delete mode 100644 src/lib/libcrypto/x509/x509_akey.c delete mode 100644 src/lib/libcrypto/x509/x509_akeya.c delete mode 100644 src/lib/libcrypto/x509/x509_alt.c delete mode 100644 src/lib/libcrypto/x509/x509_asid.c delete mode 100644 src/lib/libcrypto/x509/x509_att.c delete mode 100644 src/lib/libcrypto/x509/x509_bcons.c delete mode 100644 src/lib/libcrypto/x509/x509_bitst.c delete mode 100644 src/lib/libcrypto/x509/x509_cmp.c delete mode 100644 src/lib/libcrypto/x509/x509_conf.c delete mode 100644 src/lib/libcrypto/x509/x509_constraints.c delete mode 100644 src/lib/libcrypto/x509/x509_cpols.c delete mode 100644 src/lib/libcrypto/x509/x509_crld.c delete mode 100644 src/lib/libcrypto/x509/x509_d2.c delete mode 100644 src/lib/libcrypto/x509/x509_def.c delete mode 100644 src/lib/libcrypto/x509/x509_err.c delete mode 100644 src/lib/libcrypto/x509/x509_ext.c delete mode 100644 src/lib/libcrypto/x509/x509_extku.c delete mode 100644 src/lib/libcrypto/x509/x509_genn.c delete mode 100644 src/lib/libcrypto/x509/x509_ia5.c delete mode 100644 src/lib/libcrypto/x509/x509_info.c delete mode 100644 src/lib/libcrypto/x509/x509_int.c delete mode 100644 src/lib/libcrypto/x509/x509_internal.h delete mode 100644 src/lib/libcrypto/x509/x509_issuer_cache.c delete mode 100644 src/lib/libcrypto/x509/x509_issuer_cache.h delete mode 100644 src/lib/libcrypto/x509/x509_lib.c delete mode 100644 src/lib/libcrypto/x509/x509_local.h delete mode 100644 src/lib/libcrypto/x509/x509_lu.c delete mode 100644 src/lib/libcrypto/x509/x509_ncons.c delete mode 100644 src/lib/libcrypto/x509/x509_obj.c delete mode 100644 src/lib/libcrypto/x509/x509_ocsp.c delete mode 100644 src/lib/libcrypto/x509/x509_pcons.c delete mode 100644 src/lib/libcrypto/x509/x509_pku.c delete mode 100644 src/lib/libcrypto/x509/x509_pmaps.c delete mode 100644 src/lib/libcrypto/x509/x509_policy.c delete mode 100644 src/lib/libcrypto/x509/x509_prn.c delete mode 100644 src/lib/libcrypto/x509/x509_purp.c delete mode 100644 src/lib/libcrypto/x509/x509_r2x.c delete mode 100644 src/lib/libcrypto/x509/x509_req.c delete mode 100644 src/lib/libcrypto/x509/x509_set.c delete mode 100644 src/lib/libcrypto/x509/x509_siginfo.c delete mode 100644 src/lib/libcrypto/x509/x509_skey.c delete mode 100644 src/lib/libcrypto/x509/x509_trs.c delete mode 100644 src/lib/libcrypto/x509/x509_txt.c delete mode 100644 src/lib/libcrypto/x509/x509_utl.c delete mode 100644 src/lib/libcrypto/x509/x509_v3.c delete mode 100644 src/lib/libcrypto/x509/x509_verify.c delete mode 100644 src/lib/libcrypto/x509/x509_verify.h delete mode 100644 src/lib/libcrypto/x509/x509_vfy.c delete mode 100644 src/lib/libcrypto/x509/x509_vfy.h delete mode 100644 src/lib/libcrypto/x509/x509_vpm.c delete mode 100644 src/lib/libcrypto/x509/x509cset.c delete mode 100644 src/lib/libcrypto/x509/x509name.c delete mode 100644 src/lib/libcrypto/x509/x509rset.c delete mode 100644 src/lib/libcrypto/x509/x509spki.c delete mode 100644 src/lib/libcrypto/x509/x509type.c delete mode 100644 src/lib/libcrypto/x509/x509v3.h delete mode 100644 src/lib/libcrypto/x509/x_all.c (limited to 'src/lib/libcrypto/x509') diff --git a/src/lib/libcrypto/x509/by_dir.c b/src/lib/libcrypto/x509/by_dir.c deleted file mode 100644 index 2b2733a04b..0000000000 --- a/src/lib/libcrypto/x509/by_dir.c +++ /dev/null @@ -1,407 +0,0 @@ -/* $OpenBSD: by_dir.c,v 1.48 2024/08/31 10:19:17 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "x509_local.h" - -typedef struct lookup_dir_hashes_st { - unsigned long hash; - int suffix; -} BY_DIR_HASH; - -typedef struct lookup_dir_entry_st { - char *dir; - int dir_type; - STACK_OF(BY_DIR_HASH) *hashes; -} BY_DIR_ENTRY; - -typedef struct lookup_dir_st { - BUF_MEM *buffer; - STACK_OF(BY_DIR_ENTRY) *dirs; -} BY_DIR; - -DECLARE_STACK_OF(BY_DIR_HASH) -DECLARE_STACK_OF(BY_DIR_ENTRY) - -static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **ret); -static int new_dir(X509_LOOKUP *lu); -static void free_dir(X509_LOOKUP *lu); -static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); -static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, - X509_OBJECT *ret); - -static const X509_LOOKUP_METHOD x509_dir_lookup = { - .name = "Load certs from files in a directory", - .new_item = new_dir, - .free = free_dir, - .ctrl = dir_ctrl, - .get_by_subject = get_cert_by_subject, -}; - -const X509_LOOKUP_METHOD * -X509_LOOKUP_hash_dir(void) -{ - return &x509_dir_lookup; -} -LCRYPTO_ALIAS(X509_LOOKUP_hash_dir); - -static int -dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **retp) -{ - BY_DIR *ld = ctx->method_data; - int ret = 0; - - switch (cmd) { - case X509_L_ADD_DIR: - if (argl == X509_FILETYPE_DEFAULT) { - ret = add_cert_dir(ld, X509_get_default_cert_dir(), - X509_FILETYPE_PEM); - if (!ret) { - X509error(X509_R_LOADING_CERT_DIR); - } - } else - ret = add_cert_dir(ld, argp, (int)argl); - break; - } - return ret; -} - -static int -new_dir(X509_LOOKUP *lu) -{ - BY_DIR *a; - - 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; - } - a->dirs = NULL; - lu->method_data = a; - return 1; -} - -static void -by_dir_hash_free(BY_DIR_HASH *hash) -{ - free(hash); -} - -static int -by_dir_hash_cmp(const BY_DIR_HASH * const *a, - const BY_DIR_HASH * const *b) -{ - if ((*a)->hash > (*b)->hash) - return 1; - if ((*a)->hash < (*b)->hash) - return -1; - return 0; -} - -static void -by_dir_entry_free(BY_DIR_ENTRY *ent) -{ - free(ent->dir); - sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); - free(ent); -} - -static void -free_dir(X509_LOOKUP *lu) -{ - BY_DIR *a; - - a = lu->method_data; - sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); - BUF_MEM_free(a->buffer); - free(a); -} - -static int -add_cert_dir(BY_DIR *ctx, const char *dir, int type) -{ - int j; - const char *s, *ss, *p; - ptrdiff_t len; - - if (dir == NULL || !*dir) { - X509error(X509_R_INVALID_DIRECTORY); - return 0; - } - - s = dir; - p = s; - do { - if ((*p == ':') || (*p == '\0')) { - BY_DIR_ENTRY *ent; - - ss = s; - s = p + 1; - len = p - ss; - if (len == 0) - continue; - for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { - ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); - if (strlen(ent->dir) == (size_t)len && - strncmp(ent->dir, ss, (size_t)len) == 0) - break; - } - if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) - continue; - if (ctx->dirs == NULL) { - ctx->dirs = sk_BY_DIR_ENTRY_new_null(); - if (ctx->dirs == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - return 0; - } - } - 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 == NULL || ent->hashes == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - by_dir_entry_free(ent); - return 0; - } - if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { - X509error(ERR_R_MALLOC_FAILURE); - by_dir_entry_free(ent); - return 0; - } - } - } while (*p++ != '\0'); - return 1; -} - -static int -get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - BY_DIR *ctx; - union { - struct { - X509 st_x509; - X509_CINF st_x509_cinf; - } x509; - struct { - X509_CRL st_crl; - X509_CRL_INFO st_crl_info; - } crl; - } data; - int ok = 0; - int i, j, k; - unsigned long h; - BUF_MEM *b = NULL; - X509_OBJECT stmp, *tmp; - const char *postfix=""; - - if (name == NULL) - return 0; - - stmp.type = type; - if (type == X509_LU_X509) { - data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; - data.x509.st_x509_cinf.subject = name; - stmp.data.x509 = &data.x509.st_x509; - postfix=""; - } else if (type == X509_LU_CRL) { - data.crl.st_crl.crl = &data.crl.st_crl_info; - data.crl.st_crl_info.issuer = name; - stmp.data.crl = &data.crl.st_crl; - postfix="r"; - } else { - X509error(X509_R_WRONG_LOOKUP_TYPE); - goto finish; - } - - if ((b = BUF_MEM_new()) == NULL) { - X509error(ERR_R_BUF_LIB); - goto finish; - } - - ctx = xl->method_data; - - h = X509_NAME_hash(name); - for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { - 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)) { - X509error(ERR_R_MALLOC_FAILURE); - goto finish; - } - if (type == X509_LU_CRL) { - htmp.hash = h; - CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); - idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); - if (idx >= 0) { - hent = sk_BY_DIR_HASH_value(ent->hashes, idx); - k = hent->suffix; - } else { - hent = NULL; - k = 0; - } - CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); - } else { - k = 0; - hent = NULL; - } - for (;;) { - (void) snprintf(b->data, b->max, "%s/%08lx.%s%d", - ent->dir, h, postfix, k); - /* - * Found one. Attempt to load it. This could fail for - * any number of reasons from the file can't be opened, - * the file contains garbage, etc. Clear the error stack - * to avoid exposing the lower level error. These all - * boil down to "we could not find CA/CRL". - */ - if (type == X509_LU_X509) { - if ((X509_load_cert_file(xl, b->data, - ent->dir_type)) == 0) { - ERR_clear_error(); - break; - } - } else if (type == X509_LU_CRL) { - if ((X509_load_crl_file(xl, b->data, - ent->dir_type)) == 0) { - ERR_clear_error(); - break; - } - } - /* The lack of a CA or CRL will be caught higher up. */ - k++; - } - - /* 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); - 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 */ - if (type == X509_LU_CRL) { - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - /* - * Look for entry again in case another thread added - * an entry first. - */ - if (hent == NULL) { - htmp.hash = h; - idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); - hent = sk_BY_DIR_HASH_value(ent->hashes, idx); - } - if (hent == NULL) { - hent = malloc(sizeof(*hent)); - if (hent == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - ok = 0; - goto finish; - } - hent->hash = h; - hent->suffix = k; - if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { - X509error(ERR_R_MALLOC_FAILURE); - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - free(hent); - ok = 0; - goto finish; - } - } else if (hent->suffix < k) - hent->suffix = k; - - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - - } - - if (tmp != NULL) { - ok = 1; - ret->type = tmp->type; - memcpy(&ret->data, &tmp->data, sizeof(ret->data)); - goto finish; - } - } -finish: - BUF_MEM_free(b); - return ok; -} diff --git a/src/lib/libcrypto/x509/by_file.c b/src/lib/libcrypto/x509/by_file.c deleted file mode 100644 index 9b0fd2542c..0000000000 --- a/src/lib/libcrypto/x509/by_file.c +++ /dev/null @@ -1,262 +0,0 @@ -/* $OpenBSD: by_file.c,v 1.31 2024/08/31 10:19:17 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret); - -static const X509_LOOKUP_METHOD x509_file_lookup = { - .name = "Load file into cache", - .new_item = NULL, - .free = NULL, - .ctrl = by_file_ctrl, - .get_by_subject = NULL, -}; - -const X509_LOOKUP_METHOD * -X509_LOOKUP_file(void) -{ - return &x509_file_lookup; -} -LCRYPTO_ALIAS(X509_LOOKUP_file); - -static int -by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **ret) -{ - const char *file = argp; - int type = argl; - - if (cmd != X509_L_FILE_LOAD) - return 0; - - if (argl == X509_FILETYPE_DEFAULT) { - file = X509_get_default_cert_file(); - type = X509_FILETYPE_PEM; - } - if (X509_load_cert_crl_file(ctx, file, type) != 0) - return 1; - if (argl == X509_FILETYPE_DEFAULT) - X509error(X509_R_LOADING_DEFAULTS); - - return 0; -} - -int -X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) -{ - int ret = 0; - BIO *in = NULL; - int i, count = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file()); - - if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509error(ERR_R_SYS_LIB); - goto err; - } - - if (type == X509_FILETYPE_PEM) { - for (;;) { - 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)) { - ERR_clear_error(); - break; - } else { - X509error(ERR_R_PEM_LIB); - goto err; - } - } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - count++; - X509_free(x); - x = NULL; - } - ret = count; - } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_bio(in, NULL); - if (x == NULL) { - X509error(ERR_R_ASN1_LIB); - goto err; - } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; - } else { - X509error(X509_R_BAD_X509_FILETYPE); - goto err; - } -err: - X509_free(x); - BIO_free(in); - return ret; -} -LCRYPTO_ALIAS(X509_load_cert_file); - -int -X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) -{ - int ret = 0; - BIO *in = NULL; - int i, count = 0; - X509_CRL *x = NULL; - - in = BIO_new(BIO_s_file()); - - if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509error(ERR_R_SYS_LIB); - goto err; - } - - if (type == X509_FILETYPE_PEM) { - for (;;) { - 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)) { - ERR_clear_error(); - break; - } else { - X509error(ERR_R_PEM_LIB); - goto err; - } - } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - count++; - X509_CRL_free(x); - x = NULL; - } - ret = count; - } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_CRL_bio(in, NULL); - if (x == NULL) { - X509error(ERR_R_ASN1_LIB); - goto err; - } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; - } else { - X509error(X509_R_BAD_X509_FILETYPE); - goto err; - } -err: - X509_CRL_free(x); - BIO_free(in); - return ret; -} -LCRYPTO_ALIAS(X509_load_crl_file); - -int -X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) -{ - STACK_OF(X509_INFO) *inf; - 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"); - if (!in) { - X509error(ERR_R_SYS_LIB); - return 0; - } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); - BIO_free(in); - if (!inf) { - X509error(ERR_R_PEM_LIB); - return 0; - } - for (i = 0; i < sk_X509_INFO_num(inf); i++) { - itmp = sk_X509_INFO_value(inf, i); - if (itmp->x509) { - X509_STORE_add_cert(ctx->store_ctx, itmp->x509); - count++; - } - if (itmp->crl) { - X509_STORE_add_crl(ctx->store_ctx, itmp->crl); - count++; - } - } - if (count == 0) - X509error(X509_R_NO_CERTIFICATE_OR_CRL_FOUND); - sk_X509_INFO_pop_free(inf, X509_INFO_free); - return count; -} -LCRYPTO_ALIAS(X509_load_cert_crl_file); diff --git a/src/lib/libcrypto/x509/by_mem.c b/src/lib/libcrypto/x509/by_mem.c deleted file mode 100644 index 71afefa8a4..0000000000 --- a/src/lib/libcrypto/x509/by_mem.c +++ /dev/null @@ -1,136 +0,0 @@ -/* $OpenBSD: by_mem.c,v 1.10 2024/08/31 10:19:17 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "x509_local.h" - -static int by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **); - -static const X509_LOOKUP_METHOD x509_mem_lookup = { - .name = "Load cert from memory", - .new_item = NULL, - .free = NULL, - .ctrl = by_mem_ctrl, - .get_by_subject = NULL, -}; - -const X509_LOOKUP_METHOD * -X509_LOOKUP_mem(void) -{ - return (&x509_mem_lookup); -} -LCRYPTO_ALIAS(X509_LOOKUP_mem); - -static int -by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf, - long type, char **ret) -{ - STACK_OF(X509_INFO) *inf = NULL; - const struct iovec *iov; - X509_INFO *itmp; - BIO *in = NULL; - int i, count = 0, ok = 0; - - iov = (const struct iovec *)buf; - - if (!(cmd == X509_L_MEM && type == X509_FILETYPE_PEM)) - goto done; - - if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL) - goto done; - - if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) - goto done; - - for (i = 0; i < sk_X509_INFO_num(inf); i++) { - itmp = sk_X509_INFO_value(inf, i); - if (itmp->x509) { - ok = X509_STORE_add_cert(lu->store_ctx, itmp->x509); - if (!ok) - goto done; - count++; - } - if (itmp->crl) { - ok = X509_STORE_add_crl(lu->store_ctx, itmp->crl); - if (!ok) - goto done; - count++; - } - } - - ok = count != 0; - done: - if (count == 0) - X509error(ERR_R_PEM_LIB); - if (inf != NULL) - sk_X509_INFO_pop_free(inf, X509_INFO_free); - if (in != NULL) - BIO_free(in); - return (ok); -} diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h deleted file mode 100644 index a198b23202..0000000000 --- a/src/lib/libcrypto/x509/x509.h +++ /dev/null @@ -1,1041 +0,0 @@ -/* $OpenBSD: x509.h,v 1.121 2025/03/09 15:17:22 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#ifndef HEADER_X509_H -#define HEADER_X509_H - -#include - -#include -#ifndef OPENSSL_NO_BIO -#include -#endif -#ifndef OPENSSL_NO_BUFFER -#include -#endif -#ifndef OPENSSL_NO_DH -#include -#endif -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_EC -#include -#endif -#ifndef OPENSSL_NO_EVP -#include -#endif -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_SHA -#include -#endif -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define X509_FILETYPE_PEM 1 -#define X509_FILETYPE_ASN1 2 -#define X509_FILETYPE_DEFAULT 3 - -#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 -#define X509v3_KU_NON_REPUDIATION 0x0040 -#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 -#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 -#define X509v3_KU_KEY_AGREEMENT 0x0008 -#define X509v3_KU_KEY_CERT_SIGN 0x0004 -#define X509v3_KU_CRL_SIGN 0x0002 -#define X509v3_KU_ENCIPHER_ONLY 0x0001 -#define X509v3_KU_DECIPHER_ONLY 0x8000 -#define X509v3_KU_UNDEF 0xffff - -struct X509_algor_st { - ASN1_OBJECT *algorithm; - ASN1_TYPE *parameter; -} /* X509_ALGOR */; - -typedef STACK_OF(X509_ALGOR) X509_ALGORS; - -typedef struct X509_val_st X509_VAL; - -typedef struct X509_sig_st X509_SIG; - -typedef struct X509_name_entry_st X509_NAME_ENTRY; - -DECLARE_STACK_OF(X509_NAME_ENTRY) - -DECLARE_STACK_OF(X509_NAME) - -typedef struct X509_extension_st X509_EXTENSION; - -typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; - -DECLARE_STACK_OF(X509_EXTENSION) - -typedef struct x509_attributes_st X509_ATTRIBUTE; - -DECLARE_STACK_OF(X509_ATTRIBUTE) - -typedef struct X509_req_info_st X509_REQ_INFO; - -typedef struct X509_req_st X509_REQ; - -typedef struct x509_cinf_st X509_CINF; - -DECLARE_STACK_OF(X509) - -#define X509_TRUST_COMPAT 1 -#define X509_TRUST_SSL_CLIENT 2 -#define X509_TRUST_SSL_SERVER 3 -#define X509_TRUST_EMAIL 4 -#define X509_TRUST_OBJECT_SIGN 5 -#define X509_TRUST_OCSP_SIGN 6 -#define X509_TRUST_OCSP_REQUEST 7 -#define X509_TRUST_TSA 8 - -/* Keep these up to date! */ -#define X509_TRUST_MIN 1 -#define X509_TRUST_MAX 8 - -/* Flags for X509_print_ex() */ - -#define X509_FLAG_COMPAT 0 -#define X509_FLAG_NO_HEADER 1L -#define X509_FLAG_NO_VERSION (1L << 1) -#define X509_FLAG_NO_SERIAL (1L << 2) -#define X509_FLAG_NO_SIGNAME (1L << 3) -#define X509_FLAG_NO_ISSUER (1L << 4) -#define X509_FLAG_NO_VALIDITY (1L << 5) -#define X509_FLAG_NO_SUBJECT (1L << 6) -#define X509_FLAG_NO_PUBKEY (1L << 7) -#define X509_FLAG_NO_EXTENSIONS (1L << 8) -#define X509_FLAG_NO_SIGDUMP (1L << 9) -#define X509_FLAG_NO_AUX (1L << 10) -#define X509_FLAG_NO_ATTRIBUTES (1L << 11) - -/* Flags specific to X509_NAME_print_ex() */ - -/* The field separator information */ - -#define XN_FLAG_SEP_MASK (0xf << 16) - -#define XN_FLAG_COMPAT 0 /* Traditional SSLeay: use old X509_NAME_print */ -#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) /* RFC2253 ,+ */ -#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) /* ,+ spaced: more readable */ -#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) /* ;+ spaced */ -#define XN_FLAG_SEP_MULTILINE (4 << 16) /* One line per field */ - -#define XN_FLAG_DN_REV (1 << 20) /* Reverse DN order */ - -/* How the field name is shown */ - -#define XN_FLAG_FN_MASK (0x3 << 21) - -#define XN_FLAG_FN_SN 0 /* Object short name */ -#define XN_FLAG_FN_LN (1 << 21) /* Object long name */ -#define XN_FLAG_FN_OID (2 << 21) /* Always use OIDs */ -#define XN_FLAG_FN_NONE (3 << 21) /* No field names */ - -#define XN_FLAG_SPC_EQ (1 << 23) /* Put spaces round '=' */ - -/* This determines if we dump fields we don't recognise: - * RFC2253 requires this. - */ - -#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) - -#define XN_FLAG_FN_ALIGN (1 << 25) /* Align field names to 20 characters */ - -/* Complete set of RFC2253 flags */ - -#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ - XN_FLAG_SEP_COMMA_PLUS | \ - XN_FLAG_DN_REV | \ - XN_FLAG_FN_SN | \ - XN_FLAG_DUMP_UNKNOWN_FIELDS) - -/* readable oneline form */ - -#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ - ASN1_STRFLGS_ESC_QUOTE | \ - XN_FLAG_SEP_CPLUS_SPC | \ - XN_FLAG_SPC_EQ | \ - XN_FLAG_FN_SN) - -/* readable multiline form */ - -#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB | \ - XN_FLAG_SEP_MULTILINE | \ - XN_FLAG_SPC_EQ | \ - XN_FLAG_FN_LN | \ - XN_FLAG_FN_ALIGN) - -DECLARE_STACK_OF(X509_REVOKED) - -typedef struct X509_crl_info_st X509_CRL_INFO; - -DECLARE_STACK_OF(X509_CRL) - -typedef struct private_key_st { - int version; - /* The PKCS#8 data types */ - X509_ALGOR *enc_algor; - ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ - - /* When decrypted, the following will not be NULL */ - EVP_PKEY *dec_pkey; - - /* used to encrypt and decrypt */ - int key_length; - char *key_data; - int key_free; /* true if we should auto free key_data */ - - /* expanded version of 'enc_algor' */ - EVP_CIPHER_INFO cipher; - - int references; -} X509_PKEY; - -#ifndef OPENSSL_NO_EVP -typedef struct X509_info_st { - X509 *x509; - X509_CRL *crl; - X509_PKEY *x_pkey; - - EVP_CIPHER_INFO enc_cipher; - int enc_len; - char *enc_data; - - int references; -} X509_INFO; - -DECLARE_STACK_OF(X509_INFO) -#endif - -/* The next 2 structures and their 8 routines were sent to me by - * Pat Richard and are used to manipulate - * Netscapes spki structures - useful if you are writing a CA web page - */ -typedef struct Netscape_spkac_st { - X509_PUBKEY *pubkey; - ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ -} NETSCAPE_SPKAC; - -typedef struct Netscape_spki_st { - NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ - X509_ALGOR *sig_algor; - ASN1_BIT_STRING *signature; -} NETSCAPE_SPKI; - -typedef struct PBEPARAM_st { - ASN1_OCTET_STRING *salt; - ASN1_INTEGER *iter; -} PBEPARAM; - -#ifdef __cplusplus -} -#endif - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define X509_extract_key(x) X509_get_pubkey(x) /*****/ -#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) -#define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) - -int X509_CRL_up_ref(X509_CRL *x); -int X509_CRL_get_signature_nid(const X509_CRL *crl); - -int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp); - -const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); -long X509_CRL_get_version(const X509_CRL *crl); -const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); -const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); -ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl); -ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl); -X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); -STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); -void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg); - -const X509_ALGOR *X509_CRL_get0_tbs_sigalg(const X509_CRL *crl); - -int X509_REQ_get_signature_nid(const X509_REQ *req); - -void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg); - -X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x); - -const char *X509_verify_cert_error_string(long n); - -#ifndef OPENSSL_NO_EVP -int X509_verify(X509 *a, EVP_PKEY *r); - -int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); -int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); -int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); - -NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); -char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); -EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); -int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); - -int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); - -int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); -int X509_signature_print(BIO *bp, const X509_ALGOR *alg, - const ASN1_STRING *sig); - -int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); -int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); -int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); -int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); -int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); -int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); -int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); - -int X509_pubkey_digest(const X509 *data,const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_digest(const X509 *data,const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, - unsigned char *md, unsigned int *len); -#endif - -X509 *d2i_X509_fp(FILE *fp, X509 **x509); -int i2d_X509_fp(FILE *fp,X509 *x509); -X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); -int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); -X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); -int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); -#ifndef OPENSSL_NO_RSA -RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); -int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); -RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); -int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); -RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); -int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); -#endif -#ifndef OPENSSL_NO_DSA -DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); -int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); -DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); -int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); -#endif -#ifndef OPENSSL_NO_EC -EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); -int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); -EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); -int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); -#endif -X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); -int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, - PKCS8_PRIV_KEY_INFO **p8inf); -int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); -int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); -int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); -int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); - -#ifndef OPENSSL_NO_BIO -X509 *d2i_X509_bio(BIO *bp,X509 **x509); -int i2d_X509_bio(BIO *bp,X509 *x509); -X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); -int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); -X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); -int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); -#ifndef OPENSSL_NO_RSA -RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); -int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); -RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); -int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); -RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); -int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); -#endif -#ifndef OPENSSL_NO_DSA -DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); -int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); -DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); -int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); -#endif -#ifndef OPENSSL_NO_EC -EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); -int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); -EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); -int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); -#endif -X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); -int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, - PKCS8_PRIV_KEY_INFO **p8inf); -int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); -int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); -int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); -int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); -#endif - -X509 *X509_dup(X509 *x509); -X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); -X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); -X509_CRL *X509_CRL_dup(X509_CRL *crl); -X509_REQ *X509_REQ_dup(X509_REQ *req); -X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); -int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval); -void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval, - const X509_ALGOR *algor); -int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); - -X509_NAME *X509_NAME_dup(X509_NAME *xn); -int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, size_t *pderlen); -X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); - -int X509_cmp_time(const ASN1_TIME *s, time_t *t); -int X509_cmp_current_time(const ASN1_TIME *s); -ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); -ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, - int offset_day, long offset_sec, time_t *t); -ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); - -const char * X509_get_default_cert_area(void ); -const char * X509_get_default_cert_dir(void ); -const char * X509_get_default_cert_file(void ); -const char * X509_get_default_cert_dir_env(void ); -const char * X509_get_default_cert_file_env(void ); -const char * X509_get_default_private_dir(void ); - -X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); -X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); - -X509_ALGOR *X509_ALGOR_new(void); -void X509_ALGOR_free(X509_ALGOR *a); -X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **a, const unsigned char **in, long len); -int i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **out); -extern const ASN1_ITEM X509_ALGOR_it; -X509_ALGORS *d2i_X509_ALGORS(X509_ALGORS **a, const unsigned char **in, long len); -int i2d_X509_ALGORS(X509_ALGORS *a, unsigned char **out); -extern const ASN1_ITEM X509_ALGORS_it; -X509_VAL *X509_VAL_new(void); -void X509_VAL_free(X509_VAL *a); -X509_VAL *d2i_X509_VAL(X509_VAL **a, const unsigned char **in, long len); -int i2d_X509_VAL(X509_VAL *a, unsigned char **out); -extern const ASN1_ITEM X509_VAL_it; - -X509_PUBKEY *X509_PUBKEY_new(void); -void X509_PUBKEY_free(X509_PUBKEY *a); -X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **a, const unsigned char **in, long len); -int i2d_X509_PUBKEY(X509_PUBKEY *a, unsigned char **out); -extern const ASN1_ITEM X509_PUBKEY_it; - -int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); -EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); -EVP_PKEY * X509_PUBKEY_get0(X509_PUBKEY *key); -int X509_get_pubkey_parameters(EVP_PKEY *pkey, - STACK_OF(X509) *chain); -int i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp); -EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, - long length); -#ifndef OPENSSL_NO_RSA -int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp); -RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, - long length); -#endif -#ifndef OPENSSL_NO_DSA -int i2d_DSA_PUBKEY(DSA *a,unsigned char **pp); -DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, - long length); -#endif -#ifndef OPENSSL_NO_EC -int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); -EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, - long length); -#endif - -X509_SIG *X509_SIG_new(void); -void X509_SIG_free(X509_SIG *a); -X509_SIG *d2i_X509_SIG(X509_SIG **a, const unsigned char **in, long len); -int i2d_X509_SIG(X509_SIG *a, unsigned char **out); -extern const ASN1_ITEM X509_SIG_it; -void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg, - const ASN1_OCTET_STRING **pdigest); -void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, - ASN1_OCTET_STRING **pdigest); - -X509_REQ_INFO *X509_REQ_INFO_new(void); -void X509_REQ_INFO_free(X509_REQ_INFO *a); -X509_REQ_INFO *d2i_X509_REQ_INFO(X509_REQ_INFO **a, const unsigned char **in, long len); -int i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out); -extern const ASN1_ITEM X509_REQ_INFO_it; -X509_REQ *X509_REQ_new(void); -void X509_REQ_free(X509_REQ *a); -X509_REQ *d2i_X509_REQ(X509_REQ **a, const unsigned char **in, long len); -int i2d_X509_REQ(X509_REQ *a, unsigned char **out); -extern const ASN1_ITEM X509_REQ_it; - -X509_ATTRIBUTE *X509_ATTRIBUTE_new(void); -void X509_ATTRIBUTE_free(X509_ATTRIBUTE *a); -X509_ATTRIBUTE *d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **a, const unsigned char **in, long len); -int i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a, unsigned char **out); -extern const ASN1_ITEM X509_ATTRIBUTE_it; -X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); - -X509_EXTENSION *X509_EXTENSION_new(void); -void X509_EXTENSION_free(X509_EXTENSION *a); -X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **a, const unsigned char **in, long len); -int i2d_X509_EXTENSION(X509_EXTENSION *a, unsigned char **out); -extern const ASN1_ITEM X509_EXTENSION_it; -X509_EXTENSIONS *d2i_X509_EXTENSIONS(X509_EXTENSIONS **a, const unsigned char **in, long len); -int i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out); -extern const ASN1_ITEM X509_EXTENSIONS_it; - -X509_NAME_ENTRY *X509_NAME_ENTRY_new(void); -void X509_NAME_ENTRY_free(X509_NAME_ENTRY *a); -X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len); -int i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out); -extern const ASN1_ITEM X509_NAME_ENTRY_it; - -X509_NAME *X509_NAME_new(void); -void X509_NAME_free(X509_NAME *a); -X509_NAME *d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len); -int i2d_X509_NAME(X509_NAME *a, unsigned char **out); -extern const ASN1_ITEM X509_NAME_it; - -int X509_NAME_set(X509_NAME **xn, X509_NAME *name); - -X509_CINF *X509_CINF_new(void); -void X509_CINF_free(X509_CINF *a); -X509_CINF *d2i_X509_CINF(X509_CINF **a, const unsigned char **in, long len); -int i2d_X509_CINF(X509_CINF *a, unsigned char **out); -extern const ASN1_ITEM X509_CINF_it; - -X509 *X509_new(void); -void X509_free(X509 *a); -X509 *d2i_X509(X509 **a, const unsigned char **in, long len); -int i2d_X509(X509 *a, unsigned char **out); -extern const ASN1_ITEM X509_it; - -int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int X509_set_ex_data(X509 *r, int idx, void *arg); -void *X509_get_ex_data(X509 *r, int idx); -int i2d_X509_AUX(X509 *a,unsigned char **pp); -X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); - -int i2d_re_X509_tbs(X509 *x, unsigned char **pp); - -/* Flags returned by X509_get_signature_info(): valid and suitable for TLS. */ -#define X509_SIG_INFO_VALID 1 -#define X509_SIG_INFO_TLS 2 -int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, - uint32_t *flags); - -void X509_get0_signature(const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg, const X509 *x); -int X509_get_signature_nid(const X509 *x); - -int X509_alias_set1(X509 *x, const unsigned char *name, int len); -int X509_keyid_set1(X509 *x, const unsigned char *id, int len); -unsigned char *X509_alias_get0(X509 *x, int *len); -unsigned char *X509_keyid_get0(X509 *x, int *len); -int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj); -int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj); -void X509_trust_clear(X509 *x); -void X509_reject_clear(X509 *x); - -X509_REVOKED *X509_REVOKED_new(void); -void X509_REVOKED_free(X509_REVOKED *a); -X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *a); -X509_REVOKED *d2i_X509_REVOKED(X509_REVOKED **a, const unsigned char **in, long len); -int i2d_X509_REVOKED(X509_REVOKED *a, unsigned char **out); -extern const ASN1_ITEM X509_REVOKED_it; - -X509_CRL_INFO *X509_CRL_INFO_new(void); -void X509_CRL_INFO_free(X509_CRL_INFO *a); -X509_CRL_INFO *d2i_X509_CRL_INFO(X509_CRL_INFO **a, const unsigned char **in, long len); -int i2d_X509_CRL_INFO(X509_CRL_INFO *a, unsigned char **out); -extern const ASN1_ITEM X509_CRL_INFO_it; - -X509_CRL *X509_CRL_new(void); -void X509_CRL_free(X509_CRL *a); -X509_CRL *d2i_X509_CRL(X509_CRL **a, const unsigned char **in, long len); -int i2d_X509_CRL(X509_CRL *a, unsigned char **out); -extern const ASN1_ITEM X509_CRL_it; - -int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); -int X509_CRL_get0_by_serial(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial); -int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); - -X509_PKEY * X509_PKEY_new(void ); -void X509_PKEY_free(X509_PKEY *a); - -NETSCAPE_SPKI *NETSCAPE_SPKI_new(void); -void NETSCAPE_SPKI_free(NETSCAPE_SPKI *a); -NETSCAPE_SPKI *d2i_NETSCAPE_SPKI(NETSCAPE_SPKI **a, const unsigned char **in, long len); -int i2d_NETSCAPE_SPKI(NETSCAPE_SPKI *a, unsigned char **out); -extern const ASN1_ITEM NETSCAPE_SPKI_it; -NETSCAPE_SPKAC *NETSCAPE_SPKAC_new(void); -void NETSCAPE_SPKAC_free(NETSCAPE_SPKAC *a); -NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **a, const unsigned char **in, long len); -int i2d_NETSCAPE_SPKAC(NETSCAPE_SPKAC *a, unsigned char **out); -extern const ASN1_ITEM NETSCAPE_SPKAC_it; - -#ifndef OPENSSL_NO_EVP -X509_INFO * X509_INFO_new(void); -void X509_INFO_free(X509_INFO *a); -char * X509_NAME_oneline(const X509_NAME *a, char *buf, int size); - -int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, - unsigned char *md,unsigned int *len); - -int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, - ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); - -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, - void *data, EVP_PKEY *pkey, const EVP_MD *type); -int ASN1_item_sign_ctx(const ASN1_ITEM *it, - X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx); -#endif - -const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); -void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **issuerUID, - const ASN1_BIT_STRING **subjectUID); -const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); -int X509_set_version(X509 *x, long version); -long X509_get_version(const X509 *x); -int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); -ASN1_INTEGER * X509_get_serialNumber(X509 *x); -const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); -int X509_set_issuer_name(X509 *x, X509_NAME *name); -X509_NAME * X509_get_issuer_name(const X509 *a); -int X509_set_subject_name(X509 *x, X509_NAME *name); -X509_NAME * X509_get_subject_name(const X509 *a); -int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); -int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); -int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); -int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); -const ASN1_TIME *X509_get0_notBefore(const X509 *x); -ASN1_TIME *X509_getm_notBefore(const X509 *x); -const ASN1_TIME *X509_get0_notAfter(const X509 *x); -ASN1_TIME *X509_getm_notAfter(const X509 *x); -int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); -EVP_PKEY * X509_get_pubkey(X509 *x); -EVP_PKEY * X509_get0_pubkey(const X509 *x); -ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); -int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey); -int X509_get_signature_type(const X509 *x); - -#define X509_get_notBefore X509_getm_notBefore -#define X509_get_notAfter X509_getm_notAfter - -int X509_REQ_set_version(X509_REQ *x,long version); -long X509_REQ_get_version(const X509_REQ *x); -int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); -X509_NAME *X509_REQ_get_subject_name(const X509_REQ *x); -int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); -EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); -int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); -EVP_PKEY * X509_REQ_get0_pubkey(X509_REQ *req); -int X509_REQ_extension_nid(int nid); -STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); -int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, - int nid); -int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); -int X509_REQ_get_attr_count(const X509_REQ *req); -int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, - int lastpos); -int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, - int lastpos); -X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); -X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); -int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); -int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, - const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len); -int X509_REQ_add1_attr_by_NID(X509_REQ *req, - int nid, int type, - const unsigned char *bytes, int len); -int X509_REQ_add1_attr_by_txt(X509_REQ *req, - const char *attrname, int type, - const unsigned char *bytes, int len); - -int X509_CRL_set_version(X509_CRL *x, long version); -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); -int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); -int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); -int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); -int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); -int X509_CRL_sort(X509_CRL *crl); - -const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *x); -const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); -const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); -int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); -int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); - -int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); - -int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); - -int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); -unsigned long X509_issuer_and_serial_hash(X509 *a); - -int X509_issuer_name_cmp(const X509 *a, const X509 *b); -unsigned long X509_issuer_name_hash(X509 *a); - -int X509_subject_name_cmp(const X509 *a, const X509 *b); -unsigned long X509_subject_name_hash(X509 *x); - -#ifndef OPENSSL_NO_MD5 -unsigned long X509_issuer_name_hash_old(X509 *a); -unsigned long X509_subject_name_hash_old(X509 *x); -#endif - -int X509_cmp(const X509 *a, const X509 *b); -int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); -unsigned long X509_NAME_hash(X509_NAME *x); -unsigned long X509_NAME_hash_old(X509_NAME *x); - -int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); -int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); -int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); -int X509_print_fp(FILE *bp,X509 *x); -int X509_CRL_print_fp(FILE *bp,X509_CRL *x); -int X509_REQ_print_fp(FILE *bp,X509_REQ *req); -int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, - unsigned long flags); - -#ifndef OPENSSL_NO_BIO -int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, - unsigned long flags); -int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); -int X509_print(BIO *bp,X509 *x); -int X509_ocspid_print(BIO *bp,X509 *x); -int X509_CRL_print(BIO *bp,X509_CRL *x); -int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); -int X509_REQ_print(BIO *bp,X509_REQ *req); -#endif - -int X509_NAME_entry_count(const X509_NAME *name); -int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, - char *buf,int len); -int X509_NAME_get_text_by_OBJ(X509_NAME *name, - const ASN1_OBJECT *obj, char *buf,int len); - -/* NOTE: you should be passing -1, not 0 as lastpos. The functions that use - * lastpos, search after that position on. */ -int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, - int lastpos); -int X509_NAME_get_index_by_OBJ(const X509_NAME *name, - const ASN1_OBJECT *obj, int lastpos); -X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc); -X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); -int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, - int loc, int set); -int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, - int type, const unsigned char *bytes, int len, int loc, int set); -int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, - const unsigned char *bytes, int len, int loc, int set); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, - const char *field, int type, const unsigned char *bytes, int len); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, - int type, const unsigned char *bytes, int len); -int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, - const unsigned char *bytes, int len, int loc, int set); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, - const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len); -int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, - const ASN1_OBJECT *obj); -int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, - const unsigned char *bytes, int len); -ASN1_OBJECT * X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); -ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); -int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); - -int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); -int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, - int nid, int lastpos); -int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, - const ASN1_OBJECT *obj, int lastpos); -int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, - int crit, int lastpos); -X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); -X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); -STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, - X509_EXTENSION *ex, int loc); - -int X509_get_ext_count(const X509 *x); -int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); -int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, - int lastpos); -int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos); -X509_EXTENSION *X509_get_ext(const X509 *x, int loc); -X509_EXTENSION *X509_delete_ext(X509 *x, int loc); -int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); -void * X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); -int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, - unsigned long flags); - -int X509_CRL_get_ext_count(const X509_CRL *x); -int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, - int lastpos); -int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, - const ASN1_OBJECT *obj, int lastpos); -int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, - int lastpos); -X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); -X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); -int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); -void * X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, - int *idx); -int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, - int crit, unsigned long flags); - -int X509_REVOKED_get_ext_count(const X509_REVOKED *x); -int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, - int lastpos); -int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, - const ASN1_OBJECT *obj, int lastpos); -int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, - int crit, int lastpos); -X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc); -X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); -int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, - int loc); -void * X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, - int *crit, int *idx); -int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, - int crit, unsigned long flags); - -X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, - int nid, int crit, ASN1_OCTET_STRING *data); -X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, - const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data); -int X509_EXTENSION_set_object(X509_EXTENSION *ex, - const ASN1_OBJECT *obj); -int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); -int X509_EXTENSION_set_data(X509_EXTENSION *ex, - ASN1_OCTET_STRING *data); -ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); -ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); -int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); - -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, - int atrtype, const void *data, int len); -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, - const ASN1_OBJECT *obj, int atrtype, const void *data, int len); -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, - const char *atrname, int type, const unsigned char *bytes, int len); -int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); -int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); -void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, - int atrtype, void *data); -int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); -ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); -ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); - -int X509_verify_cert(X509_STORE_CTX *ctx); - -/* lookup a cert from a X509 STACK */ -X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, - ASN1_INTEGER *serial); -X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); - -extern const ASN1_ITEM PBEPARAM_it; - -/* PKCS#8 utilities */ - -PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void); -void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a); -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, const unsigned char **in, long len); -int i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **out); -extern const ASN1_ITEM PKCS8_PRIV_KEY_INFO_it; - -EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); - -int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, - int ptype, void *pval, unsigned char *penc, int penclen); -int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, const unsigned char **pk, - int *ppklen, const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8); - -const STACK_OF(X509_ATTRIBUTE) *PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); -int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, - const unsigned char *bytes, int len); - -int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype, - void *pval, unsigned char *penc, int penclen); -int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, - int *ppklen, X509_ALGOR **pa, X509_PUBKEY *pub); - -int X509_up_ref(X509 *x); -STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); - -void ERR_load_X509_strings(void); - -/* Error codes for the X509 functions. */ - -/* Function codes. */ -#define X509_F_ADD_CERT_DIR 100 -#define X509_F_BY_FILE_CTRL 101 -#define X509_F_CHECK_POLICY 145 -#define X509_F_DIR_CTRL 102 -#define X509_F_GET_CERT_BY_SUBJECT 103 -#define X509_F_NETSCAPE_SPKI_B64_DECODE 129 -#define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 -#define X509_F_X509AT_ADD1_ATTR 135 -#define X509_F_X509V3_ADD_EXT 104 -#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 -#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 -#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 -#define X509_F_X509_ATTRIBUTE_GET0_DATA 139 -#define X509_F_X509_ATTRIBUTE_SET1_DATA 138 -#define X509_F_X509_CHECK_PRIVATE_KEY 128 -#define X509_F_X509_CRL_PRINT_FP 147 -#define X509_F_X509_EXTENSION_CREATE_BY_NID 108 -#define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 -#define X509_F_X509_GET_PUBKEY_PARAMETERS 110 -#define X509_F_X509_LOAD_CERT_CRL_FILE 132 -#define X509_F_X509_LOAD_CERT_FILE 111 -#define X509_F_X509_LOAD_CRL_FILE 112 -#define X509_F_X509_NAME_ADD_ENTRY 113 -#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 -#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 -#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 -#define X509_F_X509_NAME_ONELINE 116 -#define X509_F_X509_NAME_PRINT 117 -#define X509_F_X509_PRINT_EX_FP 118 -#define X509_F_X509_PUBKEY_GET 119 -#define X509_F_X509_PUBKEY_SET 120 -#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 -#define X509_F_X509_REQ_PRINT_EX 121 -#define X509_F_X509_REQ_PRINT_FP 122 -#define X509_F_X509_REQ_TO_X509 123 -#define X509_F_X509_STORE_ADD_CERT 124 -#define X509_F_X509_STORE_ADD_CRL 125 -#define X509_F_X509_STORE_CTX_GET1_ISSUER 146 -#define X509_F_X509_STORE_CTX_INIT 143 -#define X509_F_X509_STORE_CTX_NEW 142 -#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 -#define X509_F_X509_TO_X509_REQ 126 -#define X509_F_X509_TRUST_ADD 133 -#define X509_F_X509_TRUST_SET 141 -#define X509_F_X509_VERIFY_CERT 127 - -/* Reason codes. */ -#define X509_R_BAD_X509_FILETYPE 100 -#define X509_R_BASE64_DECODE_ERROR 118 -#define X509_R_CANT_CHECK_DH_KEY 114 -#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 -#define X509_R_ERR_ASN1_LIB 102 -#define X509_R_INVALID_DIRECTORY 113 -#define X509_R_INVALID_FIELD_NAME 119 -#define X509_R_INVALID_TRUST 123 -#define X509_R_INVALID_VERSION 137 -#define X509_R_KEY_TYPE_MISMATCH 115 -#define X509_R_KEY_VALUES_MISMATCH 116 -#define X509_R_LOADING_CERT_DIR 103 -#define X509_R_LOADING_DEFAULTS 104 -#define X509_R_METHOD_NOT_SUPPORTED 124 -#define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136 -#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 -#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 -#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 -#define X509_R_SHOULD_RETRY 106 -#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 -#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 -#define X509_R_UNKNOWN_KEY_TYPE 117 -#define X509_R_UNKNOWN_NID 109 -#define X509_R_UNKNOWN_PURPOSE_ID 121 -#define X509_R_UNKNOWN_TRUST_ID 120 -#define X509_R_UNSUPPORTED_ALGORITHM 111 -#define X509_R_WRONG_LOOKUP_TYPE 112 -#define X509_R_WRONG_TYPE 122 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c deleted file mode 100644 index 2208cc434e..0000000000 --- a/src/lib/libcrypto/x509/x509_addr.c +++ /dev/null @@ -1,2074 +0,0 @@ -/* $OpenBSD: x509_addr.c,v 1.93 2024/07/13 15:08:58 tb Exp $ */ -/* - * Contributed to the OpenSSL Project by the American Registry for - * Internet Numbers ("ARIN"). - */ -/* ==================================================================== - * Copyright (c) 2006-2016 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - */ - -/* - * Implementation of RFC 3779 section 2.2. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "asn1_local.h" -#include "bytestring.h" -#include "x509_local.h" - -#ifndef OPENSSL_NO_RFC3779 - -/* - * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. - */ - -static const ASN1_TEMPLATE IPAddressRange_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressRange, min), - .field_name = "min", - .item = &ASN1_BIT_STRING_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressRange, max), - .field_name = "max", - .item = &ASN1_BIT_STRING_it, - }, -}; - -const ASN1_ITEM IPAddressRange_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = IPAddressRange_seq_tt, - .tcount = sizeof(IPAddressRange_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(IPAddressRange), - .sname = "IPAddressRange", -}; -LCRYPTO_ALIAS(IPAddressRange_it); - -static const ASN1_TEMPLATE IPAddressOrRange_ch_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressOrRange, u.addressPrefix), - .field_name = "u.addressPrefix", - .item = &ASN1_BIT_STRING_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressOrRange, u.addressRange), - .field_name = "u.addressRange", - .item = &IPAddressRange_it, - }, -}; - -const ASN1_ITEM IPAddressOrRange_it = { - .itype = ASN1_ITYPE_CHOICE, - .utype = offsetof(IPAddressOrRange, type), - .templates = IPAddressOrRange_ch_tt, - .tcount = sizeof(IPAddressOrRange_ch_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(IPAddressOrRange), - .sname = "IPAddressOrRange", -}; -LCRYPTO_ALIAS(IPAddressOrRange_it); - -static const ASN1_TEMPLATE IPAddressChoice_ch_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressChoice, u.inherit), - .field_name = "u.inherit", - .item = &ASN1_NULL_it, - }, - { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = offsetof(IPAddressChoice, u.addressesOrRanges), - .field_name = "u.addressesOrRanges", - .item = &IPAddressOrRange_it, - }, -}; - -const ASN1_ITEM IPAddressChoice_it = { - .itype = ASN1_ITYPE_CHOICE, - .utype = offsetof(IPAddressChoice, type), - .templates = IPAddressChoice_ch_tt, - .tcount = sizeof(IPAddressChoice_ch_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(IPAddressChoice), - .sname = "IPAddressChoice", -}; -LCRYPTO_ALIAS(IPAddressChoice_it); - -static const ASN1_TEMPLATE IPAddressFamily_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressFamily, addressFamily), - .field_name = "addressFamily", - .item = &ASN1_OCTET_STRING_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(IPAddressFamily, ipAddressChoice), - .field_name = "ipAddressChoice", - .item = &IPAddressChoice_it, - }, -}; - -const ASN1_ITEM IPAddressFamily_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = IPAddressFamily_seq_tt, - .tcount = sizeof(IPAddressFamily_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(IPAddressFamily), - .sname = "IPAddressFamily", -}; -LCRYPTO_ALIAS(IPAddressFamily_it); - -static const ASN1_TEMPLATE IPAddrBlocks_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "IPAddrBlocks", - .item = &IPAddressFamily_it, -}; - -static const ASN1_ITEM IPAddrBlocks_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &IPAddrBlocks_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "IPAddrBlocks", -}; - -IPAddressRange * -d2i_IPAddressRange(IPAddressRange **a, const unsigned char **in, long len) -{ - return (IPAddressRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &IPAddressRange_it); -} -LCRYPTO_ALIAS(d2i_IPAddressRange); - -int -i2d_IPAddressRange(IPAddressRange *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressRange_it); -} -LCRYPTO_ALIAS(i2d_IPAddressRange); - -IPAddressRange * -IPAddressRange_new(void) -{ - return (IPAddressRange *)ASN1_item_new(&IPAddressRange_it); -} -LCRYPTO_ALIAS(IPAddressRange_new); - -void -IPAddressRange_free(IPAddressRange *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &IPAddressRange_it); -} -LCRYPTO_ALIAS(IPAddressRange_free); - -IPAddressOrRange * -d2i_IPAddressOrRange(IPAddressOrRange **a, const unsigned char **in, long len) -{ - return (IPAddressOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &IPAddressOrRange_it); -} -LCRYPTO_ALIAS(d2i_IPAddressOrRange); - -int -i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressOrRange_it); -} -LCRYPTO_ALIAS(i2d_IPAddressOrRange); - -IPAddressOrRange * -IPAddressOrRange_new(void) -{ - return (IPAddressOrRange *)ASN1_item_new(&IPAddressOrRange_it); -} -LCRYPTO_ALIAS(IPAddressOrRange_new); - -void -IPAddressOrRange_free(IPAddressOrRange *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &IPAddressOrRange_it); -} -LCRYPTO_ALIAS(IPAddressOrRange_free); - -IPAddressChoice * -d2i_IPAddressChoice(IPAddressChoice **a, const unsigned char **in, long len) -{ - return (IPAddressChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &IPAddressChoice_it); -} -LCRYPTO_ALIAS(d2i_IPAddressChoice); - -int -i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressChoice_it); -} -LCRYPTO_ALIAS(i2d_IPAddressChoice); - -IPAddressChoice * -IPAddressChoice_new(void) -{ - return (IPAddressChoice *)ASN1_item_new(&IPAddressChoice_it); -} -LCRYPTO_ALIAS(IPAddressChoice_new); - -void -IPAddressChoice_free(IPAddressChoice *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &IPAddressChoice_it); -} -LCRYPTO_ALIAS(IPAddressChoice_free); - -IPAddressFamily * -d2i_IPAddressFamily(IPAddressFamily **a, const unsigned char **in, long len) -{ - return (IPAddressFamily *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &IPAddressFamily_it); -} -LCRYPTO_ALIAS(d2i_IPAddressFamily); - -int -i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressFamily_it); -} -LCRYPTO_ALIAS(i2d_IPAddressFamily); - -IPAddressFamily * -IPAddressFamily_new(void) -{ - return (IPAddressFamily *)ASN1_item_new(&IPAddressFamily_it); -} -LCRYPTO_ALIAS(IPAddressFamily_new); - -void -IPAddressFamily_free(IPAddressFamily *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &IPAddressFamily_it); -} -LCRYPTO_ALIAS(IPAddressFamily_free); - -/* - * Convenience accessors for IPAddressFamily. - */ - -static int -IPAddressFamily_type(IPAddressFamily *af) -{ - /* XXX - can af->ipAddressChoice == NULL actually happen? */ - if (af == NULL || af->ipAddressChoice == NULL) - return -1; - - switch (af->ipAddressChoice->type) { - case IPAddressChoice_inherit: - case IPAddressChoice_addressesOrRanges: - return af->ipAddressChoice->type; - default: - return -1; - } -} - -static IPAddressOrRanges * -IPAddressFamily_addressesOrRanges(IPAddressFamily *af) -{ - if (IPAddressFamily_type(af) == IPAddressChoice_addressesOrRanges) - return af->ipAddressChoice->u.addressesOrRanges; - - return NULL; -} - -static ASN1_NULL * -IPAddressFamily_inheritance(IPAddressFamily *af) -{ - if (IPAddressFamily_type(af) == IPAddressChoice_inherit) - return af->ipAddressChoice->u.inherit; - - return NULL; -} - -static int -IPAddressFamily_set_inheritance(IPAddressFamily *af) -{ - if (IPAddressFamily_addressesOrRanges(af) != NULL) - return 0; - - if (IPAddressFamily_inheritance(af) != NULL) - return 1; - - if ((af->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) - return 0; - af->ipAddressChoice->type = IPAddressChoice_inherit; - - return 1; -} - -/* - * How much buffer space do we need for a raw address? - */ -#define ADDR_RAW_BUF_LEN 16 - -/* - * What's the address length associated with this AFI? - */ -static int -length_from_afi(const unsigned afi, int *length) -{ - switch (afi) { - case IANA_AFI_IPV4: - *length = 4; - return 1; - case IANA_AFI_IPV6: - *length = 16; - return 1; - default: - *length = 0; - return 0; - } -} - -/* - * Get AFI and optional SAFI from an IPAddressFamily. All three out arguments - * are optional; if |out_safi| is non-NULL, |safi_is_set| must be non-NULL. - */ -static int -IPAddressFamily_afi_safi(const IPAddressFamily *af, uint16_t *out_afi, - uint8_t *out_safi, int *safi_is_set) -{ - CBS cbs; - uint16_t afi; - uint8_t safi = 0; - int got_safi = 0; - - if (out_afi != NULL) - *out_afi = 0; - if (out_safi != NULL) { - *out_safi = 0; - *safi_is_set = 0; - } - - CBS_init(&cbs, af->addressFamily->data, af->addressFamily->length); - - if (!CBS_get_u16(&cbs, &afi)) - return 0; - - if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6) - return 0; - - /* Fetch the optional SAFI. */ - if (CBS_len(&cbs) != 0) { - if (!CBS_get_u8(&cbs, &safi)) - return 0; - got_safi = 1; - } - - /* If there's anything left, it's garbage. */ - if (CBS_len(&cbs) != 0) - return 0; - - /* XXX - error on reserved AFI/SAFI? */ - - if (out_afi != NULL) - *out_afi = afi; - - if (out_safi != NULL) { - *out_safi = safi; - *safi_is_set = got_safi; - } - - return 1; -} - -static int -IPAddressFamily_afi(const IPAddressFamily *af, uint16_t *out_afi) -{ - return IPAddressFamily_afi_safi(af, out_afi, NULL, NULL); -} - -static int -IPAddressFamily_afi_is_valid(const IPAddressFamily *af) -{ - return IPAddressFamily_afi_safi(af, NULL, NULL, NULL); -} - -static int -IPAddressFamily_afi_length(const IPAddressFamily *af, int *out_length) -{ - uint16_t afi; - - *out_length = 0; - - if (!IPAddressFamily_afi(af, &afi)) - return 0; - - return length_from_afi(afi, out_length); -} - -#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) - -/* - * Sort comparison function for a sequence of IPAddressFamily. - * - * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about - * the ordering: I can read it as meaning that IPv6 without a SAFI - * comes before IPv4 with a SAFI, which seems pretty weird. The - * examples in appendix B suggest that the author intended the - * null-SAFI rule to apply only within a single AFI, which is what I - * would have expected and is what the following code implements. - */ -static int -IPAddressFamily_cmp(const IPAddressFamily *const *a_, - const IPAddressFamily *const *b_) -{ - const ASN1_OCTET_STRING *a = (*a_)->addressFamily; - const ASN1_OCTET_STRING *b = (*b_)->addressFamily; - int len, cmp; - - len = MINIMUM(a->length, b->length); - - if ((cmp = memcmp(a->data, b->data, len)) != 0) - return cmp; - - return a->length - b->length; -} - -static IPAddressFamily * -IPAddressFamily_find_in_parent(IPAddrBlocks *parent, IPAddressFamily *child_af) -{ - int index; - - (void)sk_IPAddressFamily_set_cmp_func(parent, IPAddressFamily_cmp); - - if ((index = sk_IPAddressFamily_find(parent, child_af)) < 0) - return NULL; - - return sk_IPAddressFamily_value(parent, index); -} - -/* - * Extract the AFI from an IPAddressFamily. - * - * This is public API. It uses the reserved AFI 0 as an in-band error - * while it doesn't care about the reserved AFI 65535... - */ -unsigned int -X509v3_addr_get_afi(const IPAddressFamily *af) -{ - uint16_t afi; - - /* - * XXX are these NULL checks really sensible? If af is non-NULL, it - * should have both addressFamily and ipAddressChoice... - */ - if (af == NULL || af->addressFamily == NULL || - af->addressFamily->data == NULL) - return 0; - - if (!IPAddressFamily_afi(af, &afi)) - return 0; - - return afi; -} -LCRYPTO_ALIAS(X509v3_addr_get_afi); - -/* - * Expand the bitstring form (RFC 3779, section 2.1.2) of an address into - * a raw byte array. At the moment this is coded for simplicity, not speed. - * - * Unused bits in the last octet of |bs| and all bits in subsequent bytes - * of |addr| are set to 0 or 1 depending on whether |fill| is 0 or not. - */ -static int -addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length, - uint8_t fill) -{ - if (bs->length < 0 || bs->length > length) - return 0; - - if (fill != 0) - fill = 0xff; - - if (bs->length > 0) { - /* XXX - shouldn't this check ASN1_STRING_FLAG_BITS_LEFT? */ - uint8_t unused_bits = bs->flags & 7; - uint8_t mask = (1 << unused_bits) - 1; - - memcpy(addr, bs->data, bs->length); - - if (fill == 0) - addr[bs->length - 1] &= ~mask; - else - addr[bs->length - 1] |= mask; - } - - memset(addr + bs->length, fill, length - bs->length); - - return 1; -} - -/* - * Extract the prefix length from a bitstring: 8 * length - unused bits. - */ -#define addr_prefix_len(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) - -/* - * i2r handler for one address bitstring. - */ -static int -i2r_address(BIO *out, const unsigned afi, const unsigned char fill, - const ASN1_BIT_STRING *bs) -{ - unsigned char addr[ADDR_RAW_BUF_LEN]; - int i, n; - - if (bs->length < 0) - return 0; - switch (afi) { - case IANA_AFI_IPV4: - if (!addr_expand(addr, bs, 4, fill)) - return 0; - BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], - addr[3]); - break; - case IANA_AFI_IPV6: - if (!addr_expand(addr, bs, 16, fill)) - return 0; - for (n = 16; - n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; n -= 2) - continue; - for (i = 0; i < n; i += 2) - BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], - (i < 14 ? ":" : "")); - if (i < 16) - BIO_puts(out, ":"); - if (i == 0) - BIO_puts(out, ":"); - break; - default: - for (i = 0; i < bs->length; i++) - BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), - bs->data[i]); - BIO_printf(out, "[%d]", (int)(bs->flags & 7)); - break; - } - return 1; -} - -/* - * i2r handler for a sequence of addresses and ranges. - */ -static int -i2r_IPAddressOrRanges(BIO *out, const int indent, - const IPAddressOrRanges *aors, const unsigned afi) -{ - const IPAddressOrRange *aor; - const ASN1_BIT_STRING *prefix; - const IPAddressRange *range; - int i; - - for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { - aor = sk_IPAddressOrRange_value(aors, i); - - BIO_printf(out, "%*s", indent, ""); - - switch (aor->type) { - case IPAddressOrRange_addressPrefix: - prefix = aor->u.addressPrefix; - - if (!i2r_address(out, afi, 0x00, prefix)) - return 0; - BIO_printf(out, "/%d\n", addr_prefix_len(prefix)); - continue; - case IPAddressOrRange_addressRange: - range = aor->u.addressRange; - - if (!i2r_address(out, afi, 0x00, range->min)) - return 0; - BIO_puts(out, "-"); - if (!i2r_address(out, afi, 0xff, range->max)) - return 0; - BIO_puts(out, "\n"); - continue; - } - } - - return 1; -} - -/* - * i2r handler for an IPAddrBlocks extension. - */ -static int -i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out, - int indent) -{ - const IPAddrBlocks *addr = ext; - IPAddressFamily *af; - uint16_t afi; - uint8_t safi; - int i, safi_is_set; - - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - af = sk_IPAddressFamily_value(addr, i); - - if (!IPAddressFamily_afi_safi(af, &afi, &safi, &safi_is_set)) - goto print_addresses; - - switch (afi) { - case IANA_AFI_IPV4: - BIO_printf(out, "%*sIPv4", indent, ""); - break; - case IANA_AFI_IPV6: - BIO_printf(out, "%*sIPv6", indent, ""); - break; - default: - BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); - break; - } - if (safi_is_set) { - switch (safi) { - case 1: - BIO_puts(out, " (Unicast)"); - break; - case 2: - BIO_puts(out, " (Multicast)"); - break; - case 3: - BIO_puts(out, " (Unicast/Multicast)"); - break; - case 4: - BIO_puts(out, " (MPLS)"); - break; - case 64: - BIO_puts(out, " (Tunnel)"); - break; - case 65: - BIO_puts(out, " (VPLS)"); - break; - case 66: - BIO_puts(out, " (BGP MDT)"); - break; - case 128: - BIO_puts(out, " (MPLS-labeled VPN)"); - break; - default: - BIO_printf(out, " (Unknown SAFI %u)", safi); - break; - } - } - - print_addresses: - switch (IPAddressFamily_type(af)) { - case IPAddressChoice_inherit: - BIO_puts(out, ": inherit\n"); - break; - case IPAddressChoice_addressesOrRanges: - BIO_puts(out, ":\n"); - if (!i2r_IPAddressOrRanges(out, indent + 2, - IPAddressFamily_addressesOrRanges(af), afi)) - return 0; - break; - /* XXX - how should we handle -1 here? */ - } - } - return 1; -} - -/* - * Sort comparison function for a sequence of IPAddressOrRange - * elements. - * - * There's no sane answer we can give if addr_expand() fails, and an - * assertion failure on externally supplied data is seriously uncool, - * so we just arbitrarily declare that if given invalid inputs this - * function returns -1. If this messes up your preferred sort order - * for garbage input, tough noogies. - */ -static int -IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b, - const int length) -{ - unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; - int prefix_len_a = 0, prefix_len_b = 0; - int r; - - switch (a->type) { - case IPAddressOrRange_addressPrefix: - if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) - return -1; - prefix_len_a = addr_prefix_len(a->u.addressPrefix); - break; - case IPAddressOrRange_addressRange: - if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) - return -1; - prefix_len_a = length * 8; - break; - } - - switch (b->type) { - case IPAddressOrRange_addressPrefix: - if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) - return -1; - prefix_len_b = addr_prefix_len(b->u.addressPrefix); - break; - case IPAddressOrRange_addressRange: - if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) - return -1; - prefix_len_b = length * 8; - break; - } - - if ((r = memcmp(addr_a, addr_b, length)) != 0) - return r; - else - return prefix_len_a - prefix_len_b; -} - -/* - * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() - * comparison routines are only allowed two arguments. - */ -static int -v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, - const IPAddressOrRange *const *b) -{ - return IPAddressOrRange_cmp(*a, *b, 4); -} - -/* - * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() - * comparison routines are only allowed two arguments. - */ -static int -v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, - const IPAddressOrRange *const *b) -{ - return IPAddressOrRange_cmp(*a, *b, 16); -} - -/* - * Calculate whether a range collapses to a prefix. - * See last paragraph of RFC 3779 2.2.3.7. - * - * It's the caller's responsibility to ensure that min <= max. - */ -static int -range_should_be_prefix(const unsigned char *min, const unsigned char *max, - const int length) -{ - unsigned char mask; - int i, j; - - for (i = 0; i < length && min[i] == max[i]; i++) - continue; - for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xff; j--) - continue; - if (i < j) - return -1; - if (i > j) - return i * 8; - mask = min[i] ^ max[i]; - switch (mask) { - case 0x01: - j = 7; - break; - case 0x03: - j = 6; - break; - case 0x07: - j = 5; - break; - case 0x0f: - j = 4; - break; - case 0x1f: - j = 3; - break; - case 0x3f: - j = 2; - break; - case 0x7f: - j = 1; - break; - default: - return -1; - } - if ((min[i] & mask) != 0 || (max[i] & mask) != mask) - return -1; - else - return i * 8 + j; -} - -/* - * Fill IPAddressOrRange with bit string encoding of a prefix - RFC 3779, 2.1.1. - */ -static int -make_addressPrefix(IPAddressOrRange **out_aor, uint8_t *addr, uint32_t afi, - int prefix_len) -{ - IPAddressOrRange *aor = NULL; - int afi_len, num_bits, num_octets; - uint8_t unused_bits; - - if (prefix_len < 0) - goto err; - - if (!length_from_afi(afi, &afi_len)) - goto err; - if (prefix_len > 8 * afi_len) - goto err; - - num_octets = (prefix_len + 7) / 8; - num_bits = prefix_len % 8; - - unused_bits = 0; - if (num_bits > 0) - unused_bits = 8 - num_bits; - - if ((aor = IPAddressOrRange_new()) == NULL) - goto err; - - aor->type = IPAddressOrRange_addressPrefix; - - if ((aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) - goto err; - if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, num_octets)) - goto err; - if (!asn1_abs_set_unused_bits(aor->u.addressPrefix, unused_bits)) - goto err; - - *out_aor = aor; - return 1; - - err: - IPAddressOrRange_free(aor); - return 0; -} - -static uint8_t -count_trailing_zeroes(uint8_t octet) -{ - uint8_t count = 0; - - if (octet == 0) - return 8; - - while ((octet & (1 << count)) == 0) - count++; - - return count; -} - -static int -trim_end_u8(CBS *cbs, uint8_t trim) -{ - uint8_t octet; - - while (CBS_len(cbs) > 0) { - if (!CBS_peek_last_u8(cbs, &octet)) - return 0; - if (octet != trim) - return 1; - if (!CBS_get_last_u8(cbs, &octet)) - return 0; - } - - return 1; -} - -/* - * Populate IPAddressOrRange with bit string encoding of a range, see - * RFC 3779, 2.1.2. - */ -static int -make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max, - uint32_t afi, int length) -{ - IPAddressOrRange *aor = NULL; - IPAddressRange *range; - int prefix_len; - CBS cbs; - size_t max_len, min_len; - uint8_t unused_bits_min, unused_bits_max; - uint8_t octet; - - if (memcmp(min, max, length) > 0) - goto err; - - /* - * RFC 3779, 2.2.3.6 - a range that can be expressed as a prefix - * must be encoded as a prefix. - */ - - if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0) - return make_addressPrefix(out_aor, min, afi, prefix_len); - - /* - * The bit string representing min is formed by removing all its - * trailing zero bits, so remove all trailing zero octets and count - * the trailing zero bits of the last octet. - */ - - CBS_init(&cbs, min, length); - - if (!trim_end_u8(&cbs, 0x00)) - goto err; - - unused_bits_min = 0; - if ((min_len = CBS_len(&cbs)) > 0) { - if (!CBS_peek_last_u8(&cbs, &octet)) - goto err; - - unused_bits_min = count_trailing_zeroes(octet); - } - - /* - * The bit string representing max is formed by removing all its - * trailing one bits, so remove all trailing 0xff octets and count - * the trailing ones of the last octet. - */ - - CBS_init(&cbs, max, length); - - if (!trim_end_u8(&cbs, 0xff)) - goto err; - - unused_bits_max = 0; - if ((max_len = CBS_len(&cbs)) > 0) { - if (!CBS_peek_last_u8(&cbs, &octet)) - goto err; - - unused_bits_max = count_trailing_zeroes(octet + 1); - } - - /* - * Populate IPAddressOrRange. - */ - - if ((aor = IPAddressOrRange_new()) == NULL) - goto err; - - aor->type = IPAddressOrRange_addressRange; - - if ((range = aor->u.addressRange = IPAddressRange_new()) == NULL) - goto err; - - if (!ASN1_BIT_STRING_set(range->min, min, min_len)) - goto err; - if (!asn1_abs_set_unused_bits(range->min, unused_bits_min)) - goto err; - - if (!ASN1_BIT_STRING_set(range->max, max, max_len)) - goto err; - if (!asn1_abs_set_unused_bits(range->max, unused_bits_max)) - goto err; - - *out_aor = aor; - - return 1; - - err: - IPAddressOrRange_free(aor); - return 0; -} - -/* - * Construct a new address family or find an existing one. - */ -static IPAddressFamily * -make_IPAddressFamily(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi) -{ - IPAddressFamily *af = NULL; - CBB cbb; - CBS cbs; - uint8_t *key = NULL; - size_t keylen; - int i; - - if (!CBB_init(&cbb, 0)) - goto err; - - if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6) - goto err; - if (!CBB_add_u16(&cbb, afi)) - goto err; - - if (safi != NULL) { - if (*safi > 255) - goto err; - if (!CBB_add_u8(&cbb, *safi)) - goto err; - } - - if (!CBB_finish(&cbb, &key, &keylen)) - goto err; - - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - af = sk_IPAddressFamily_value(addr, i); - - CBS_init(&cbs, af->addressFamily->data, - af->addressFamily->length); - if (CBS_mem_equal(&cbs, key, keylen)) - goto done; - } - - if ((af = IPAddressFamily_new()) == NULL) - goto err; - if (!ASN1_OCTET_STRING_set(af->addressFamily, key, keylen)) - goto err; - if (!sk_IPAddressFamily_push(addr, af)) - goto err; - - done: - free(key); - - return af; - - err: - CBB_cleanup(&cbb); - free(key); - IPAddressFamily_free(af); - - return NULL; -} - -/* - * Add an inheritance element. - */ -int -X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi) -{ - IPAddressFamily *af; - - if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL) - return 0; - - return IPAddressFamily_set_inheritance(af); -} -LCRYPTO_ALIAS(X509v3_addr_add_inherit); - -/* - * Construct an IPAddressOrRange sequence, or return an existing one. - */ -static IPAddressOrRanges * -make_prefix_or_range(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi) -{ - IPAddressFamily *af; - IPAddressOrRanges *aors = NULL; - - if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL) - return NULL; - - if (IPAddressFamily_inheritance(af) != NULL) - return NULL; - - if ((aors = IPAddressFamily_addressesOrRanges(af)) != NULL) - return aors; - - if ((aors = sk_IPAddressOrRange_new_null()) == NULL) - return NULL; - - switch (afi) { - case IANA_AFI_IPV4: - (void)sk_IPAddressOrRange_set_cmp_func(aors, - v4IPAddressOrRange_cmp); - break; - case IANA_AFI_IPV6: - (void)sk_IPAddressOrRange_set_cmp_func(aors, - v6IPAddressOrRange_cmp); - break; - } - - af->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; - af->ipAddressChoice->u.addressesOrRanges = aors; - - return aors; -} - -/* - * Add a prefix. - */ -int -X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi, unsigned char *a, const int prefix_len) -{ - IPAddressOrRanges *aors; - IPAddressOrRange *aor; - - if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) - return 0; - - if (!make_addressPrefix(&aor, a, afi, prefix_len)) - return 0; - - if (sk_IPAddressOrRange_push(aors, aor) <= 0) { - IPAddressOrRange_free(aor); - return 0; - } - - return 1; -} -LCRYPTO_ALIAS(X509v3_addr_add_prefix); - -/* - * Add a range. - */ -int -X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi, unsigned char *min, unsigned char *max) -{ - IPAddressOrRanges *aors; - IPAddressOrRange *aor; - int length; - - if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) - return 0; - - if (!length_from_afi(afi, &length)) - return 0; - - if (!make_addressRange(&aor, min, max, afi, length)) - return 0; - - if (sk_IPAddressOrRange_push(aors, aor) <= 0) { - IPAddressOrRange_free(aor); - return 0; - } - - return 1; -} -LCRYPTO_ALIAS(X509v3_addr_add_range); - -static int -extract_min_max_bitstr(IPAddressOrRange *aor, ASN1_BIT_STRING **out_min, - ASN1_BIT_STRING **out_max) -{ - switch (aor->type) { - case IPAddressOrRange_addressPrefix: - *out_min = *out_max = aor->u.addressPrefix; - return 1; - case IPAddressOrRange_addressRange: - *out_min = aor->u.addressRange->min; - *out_max = aor->u.addressRange->max; - return 1; - default: - return 0; - } -} - -/* - * Extract min and max values from an IPAddressOrRange. - */ -static int -extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max, - int length) -{ - ASN1_BIT_STRING *min_bitstr, *max_bitstr; - - if (aor == NULL || min == NULL || max == NULL) - return 0; - - if (!extract_min_max_bitstr(aor, &min_bitstr, &max_bitstr)) - return 0; - - if (!addr_expand(min, min_bitstr, length, 0)) - return 0; - - return addr_expand(max, max_bitstr, length, 1); -} - -/* - * Public wrapper for extract_min_max(). - */ -int -X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, - unsigned char *min, unsigned char *max, const int length) -{ - int afi_len; - - if (!length_from_afi(afi, &afi_len)) - return 0; - - if (length < afi_len) - return 0; - - if (!extract_min_max(aor, min, max, afi_len)) - return 0; - - return afi_len; -} -LCRYPTO_ALIAS(X509v3_addr_get_range); - -/* - * Check whether an IPAddrBLocks is in canonical form. - */ -int -X509v3_addr_is_canonical(IPAddrBlocks *addr) -{ - unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; - unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; - IPAddressFamily *af; - IPAddressOrRanges *aors; - IPAddressOrRange *aor, *aor_a, *aor_b; - int i, j, k, length; - - /* - * Empty extension is canonical. - */ - if (addr == NULL) - return 1; - - /* - * Check whether the top-level list is in order. - */ - for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { - const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); - const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); - - /* Check that both have valid AFIs before comparing them. */ - if (!IPAddressFamily_afi_is_valid(a)) - return 0; - if (!IPAddressFamily_afi_is_valid(b)) - return 0; - - if (IPAddressFamily_cmp(&a, &b) >= 0) - return 0; - } - - /* - * Top level's ok, now check each address family. - */ - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - af = sk_IPAddressFamily_value(addr, i); - - if (!IPAddressFamily_afi_length(af, &length)) - return 0; - - /* - * If this family has an inheritance element, it is canonical. - */ - if (IPAddressFamily_inheritance(af) != NULL) - continue; - - /* - * If this family has neither an inheritance element nor an - * addressesOrRanges, we don't know what this is. - */ - if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL) - return 0; - - if (sk_IPAddressOrRange_num(aors) == 0) - return 0; - - for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { - aor_a = sk_IPAddressOrRange_value(aors, j); - aor_b = sk_IPAddressOrRange_value(aors, j + 1); - - if (!extract_min_max(aor_a, a_min, a_max, length) || - !extract_min_max(aor_b, b_min, b_max, length)) - return 0; - - /* - * Punt misordered list, overlapping start, or inverted - * range. - */ - if (memcmp(a_min, b_min, length) >= 0 || - memcmp(a_min, a_max, length) > 0 || - memcmp(b_min, b_max, length) > 0) - return 0; - - /* - * Punt if adjacent or overlapping. Check for adjacency - * by subtracting one from b_min first. - */ - for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) - continue; - if (memcmp(a_max, b_min, length) >= 0) - return 0; - - /* - * Check for range that should be expressed as a prefix. - */ - if (aor_a->type == IPAddressOrRange_addressPrefix) - continue; - - if (range_should_be_prefix(a_min, a_max, length) >= 0) - return 0; - } - - /* - * Check final range to see if it's inverted or should be a - * prefix. - */ - aor = sk_IPAddressOrRange_value(aors, j); - if (aor->type == IPAddressOrRange_addressRange) { - if (!extract_min_max(aor, a_min, a_max, length)) - return 0; - if (memcmp(a_min, a_max, length) > 0) - return 0; - if (range_should_be_prefix(a_min, a_max, length) >= 0) - return 0; - } - } - - /* - * If we made it through all that, we're happy. - */ - return 1; -} -LCRYPTO_ALIAS(X509v3_addr_is_canonical); - -/* - * Whack an IPAddressOrRanges into canonical form. - */ -static int -IPAddressOrRanges_canonize(IPAddressOrRanges *aors, const unsigned afi) -{ - IPAddressOrRange *a, *b, *merged; - unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; - unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; - int i, j, length; - - if (!length_from_afi(afi, &length)) - return 0; - - /* - * Sort the IPAddressOrRanges sequence. - */ - sk_IPAddressOrRange_sort(aors); - - /* - * Clean up representation issues, punt on duplicates or overlaps. - */ - for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { - a = sk_IPAddressOrRange_value(aors, i); - b = sk_IPAddressOrRange_value(aors, i + 1); - - if (!extract_min_max(a, a_min, a_max, length) || - !extract_min_max(b, b_min, b_max, length)) - return 0; - - /* - * Punt inverted ranges. - */ - if (memcmp(a_min, a_max, length) > 0 || - memcmp(b_min, b_max, length) > 0) - return 0; - - /* - * Punt overlaps. - */ - if (memcmp(a_max, b_min, length) >= 0) - return 0; - - /* - * Merge if a and b are adjacent. We check for - * adjacency by subtracting one from b_min first. - */ - for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) - continue; - - if (memcmp(a_max, b_min, length) != 0) - continue; - - if (!make_addressRange(&merged, a_min, b_max, afi, length)) - return 0; - sk_IPAddressOrRange_set(aors, i, merged); - (void)sk_IPAddressOrRange_delete(aors, i + 1); - IPAddressOrRange_free(a); - IPAddressOrRange_free(b); - i--; - } - - /* - * Check for inverted final range. - */ - a = sk_IPAddressOrRange_value(aors, i); - if (a != NULL && a->type == IPAddressOrRange_addressRange) { - if (!extract_min_max(a, a_min, a_max, length)) - return 0; - if (memcmp(a_min, a_max, length) > 0) - return 0; - } - - return 1; -} - -/* - * Whack an IPAddrBlocks extension into canonical form. - */ -int -X509v3_addr_canonize(IPAddrBlocks *addr) -{ - IPAddressFamily *af; - IPAddressOrRanges *aors; - uint16_t afi; - int i; - - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - af = sk_IPAddressFamily_value(addr, i); - - /* Check AFI/SAFI here - IPAddressFamily_cmp() can't error. */ - if (!IPAddressFamily_afi(af, &afi)) - return 0; - - if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL) - continue; - - if (!IPAddressOrRanges_canonize(aors, afi)) - return 0; - } - - (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); - sk_IPAddressFamily_sort(addr); - - return X509v3_addr_is_canonical(addr); -} -LCRYPTO_ALIAS(X509v3_addr_canonize); - -/* - * v2i handler for the IPAddrBlocks extension. - */ -static void * -v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE)*values) -{ - static const char v4addr_chars[] = "0123456789."; - static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; - IPAddrBlocks *addr = NULL; - char *s = NULL, *t; - int i; - - if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - CONF_VALUE *val = sk_CONF_VALUE_value(values, i); - unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; - unsigned afi, *safi = NULL, safi_; - const char *addr_chars = NULL; - const char *errstr; - int prefix_len, i1, i2, delim, length; - - if (!name_cmp(val->name, "IPv4")) { - afi = IANA_AFI_IPV4; - } else if (!name_cmp(val->name, "IPv6")) { - afi = IANA_AFI_IPV6; - } else if (!name_cmp(val->name, "IPv4-SAFI")) { - afi = IANA_AFI_IPV4; - safi = &safi_; - } else if (!name_cmp(val->name, "IPv6-SAFI")) { - afi = IANA_AFI_IPV6; - safi = &safi_; - } else { - X509V3error(X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); - goto err; - } - - switch (afi) { - case IANA_AFI_IPV4: - addr_chars = v4addr_chars; - break; - case IANA_AFI_IPV6: - addr_chars = v6addr_chars; - break; - } - - if (!length_from_afi(afi, &length)) - goto err; - - /* - * Handle SAFI, if any, and strdup() so we can null-terminate - * the other input values. - */ - if (safi != NULL) { - unsigned long parsed_safi; - int saved_errno = errno; - - errno = 0; - parsed_safi = strtoul(val->value, &t, 0); - - /* Value must be present, then a tab, space or colon. */ - if (val->value[0] == '\0' || - (*t != '\t' && *t != ' ' && *t != ':')) { - X509V3error(X509V3_R_INVALID_SAFI); - X509V3_conf_err(val); - goto err; - } - /* Range and overflow check. */ - if ((errno == ERANGE && parsed_safi == ULONG_MAX) || - parsed_safi > 0xff) { - X509V3error(X509V3_R_INVALID_SAFI); - X509V3_conf_err(val); - goto err; - } - errno = saved_errno; - - *safi = parsed_safi; - - /* Check possible whitespace is followed by a colon. */ - t += strspn(t, " \t"); - if (*t != ':') { - X509V3error(X509V3_R_INVALID_SAFI); - X509V3_conf_err(val); - goto err; - } - - /* Skip over colon. */ - t++; - - /* Then over any trailing whitespace. */ - t += strspn(t, " \t"); - - s = strdup(t); - } else { - s = strdup(val->value); - } - if (s == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * Check for inheritance. Not worth additional complexity to - * optimize this (seldom-used) case. - */ - if (strcmp(s, "inherit") == 0) { - if (!X509v3_addr_add_inherit(addr, afi, safi)) { - X509V3error(X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); - goto err; - } - free(s); - s = NULL; - continue; - } - - i1 = strspn(s, addr_chars); - i2 = i1 + strspn(s + i1, " \t"); - delim = s[i2++]; - s[i1] = '\0'; - - if (a2i_ipadd(min, s) != length) { - X509V3error(X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); - goto err; - } - - switch (delim) { - case '/': - /* length contains the size of the address in bytes. */ - if (length != 4 && length != 16) - goto err; - prefix_len = strtonum(s + i2, 0, 8 * length, &errstr); - if (errstr != NULL) { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (!X509v3_addr_add_prefix(addr, afi, safi, min, - prefix_len)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - break; - case '-': - i1 = i2 + strspn(s + i2, " \t"); - i2 = i1 + strspn(s + i1, addr_chars); - if (i1 == i2 || s[i2] != '\0') { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (a2i_ipadd(max, s + i1) != length) { - X509V3error(X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); - goto err; - } - if (memcmp(min, max, length) > 0) { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (!X509v3_addr_add_range(addr, afi, safi, min, max)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - break; - case '\0': - if (!X509v3_addr_add_prefix(addr, afi, safi, min, - length * 8)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - break; - default: - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - - free(s); - s = NULL; - } - - /* - * Canonize the result, then we're done. - */ - if (!X509v3_addr_canonize(addr)) - goto err; - return addr; - - err: - free(s); - sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); - return NULL; -} - -/* - * OpenSSL dispatch - */ -static const X509V3_EXT_METHOD x509v3_ext_sbgp_ipAddrBlock = { - .ext_nid = NID_sbgp_ipAddrBlock, - .ext_flags = 0, - .it = &IPAddrBlocks_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = v2i_IPAddrBlocks, - .i2r = i2r_IPAddrBlocks, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_sbgp_ipAddrBlock(void) -{ - return &x509v3_ext_sbgp_ipAddrBlock; -} - -/* - * Figure out whether extension uses inheritance. - */ -int -X509v3_addr_inherits(IPAddrBlocks *addr) -{ - IPAddressFamily *af; - int i; - - if (addr == NULL) - return 0; - - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - af = sk_IPAddressFamily_value(addr, i); - - if (IPAddressFamily_inheritance(af) != NULL) - return 1; - } - - return 0; -} -LCRYPTO_ALIAS(X509v3_addr_inherits); - -/* - * Figure out whether parent contains child. - * - * This only works correctly if both parent and child are in canonical form. - */ -static int -addr_contains(IPAddressOrRanges *parent, IPAddressOrRanges *child, int length) -{ - IPAddressOrRange *child_aor, *parent_aor; - uint8_t parent_min[ADDR_RAW_BUF_LEN], parent_max[ADDR_RAW_BUF_LEN]; - uint8_t child_min[ADDR_RAW_BUF_LEN], child_max[ADDR_RAW_BUF_LEN]; - int p, c; - - if (child == NULL || parent == child) - return 1; - if (parent == NULL) - return 0; - - p = 0; - for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { - child_aor = sk_IPAddressOrRange_value(child, c); - - if (!extract_min_max(child_aor, child_min, child_max, length)) - return 0; - - for (;; p++) { - if (p >= sk_IPAddressOrRange_num(parent)) - return 0; - - parent_aor = sk_IPAddressOrRange_value(parent, p); - - if (!extract_min_max(parent_aor, parent_min, parent_max, - length)) - return 0; - - if (memcmp(parent_max, child_max, length) < 0) - continue; - if (memcmp(parent_min, child_min, length) > 0) - return 0; - break; - } - } - - return 1; -} - -/* - * Test whether |child| is a subset of |parent|. - */ -int -X509v3_addr_subset(IPAddrBlocks *child, IPAddrBlocks *parent) -{ - IPAddressFamily *child_af, *parent_af; - IPAddressOrRanges *child_aor, *parent_aor; - int i, length; - - if (child == NULL || child == parent) - return 1; - if (parent == NULL) - return 0; - - if (X509v3_addr_inherits(child) || X509v3_addr_inherits(parent)) - return 0; - - for (i = 0; i < sk_IPAddressFamily_num(child); i++) { - child_af = sk_IPAddressFamily_value(child, i); - - parent_af = IPAddressFamily_find_in_parent(parent, child_af); - if (parent_af == NULL) - return 0; - - if (!IPAddressFamily_afi_length(parent_af, &length)) - return 0; - - child_aor = IPAddressFamily_addressesOrRanges(child_af); - parent_aor = IPAddressFamily_addressesOrRanges(parent_af); - - if (!addr_contains(parent_aor, child_aor, length)) - return 0; - } - return 1; -} -LCRYPTO_ALIAS(X509v3_addr_subset); - -static int -verify_error(X509_STORE_CTX *ctx, X509 *cert, int error, int depth) -{ - if (ctx == NULL) - return 0; - - ctx->current_cert = cert; - ctx->error = error; - ctx->error_depth = depth; - - return ctx->verify_cb(0, ctx); -} - -/* - * Core code for RFC 3779 2.3 path validation. - * - * Returns 1 for success, 0 on error. - * - * When returning 0, ctx->error MUST be set to an appropriate value other than - * X509_V_OK. - */ -static int -addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, - IPAddrBlocks *ext) -{ - IPAddrBlocks *child = NULL, *parent = NULL; - IPAddressFamily *child_af, *parent_af; - IPAddressOrRanges *child_aor, *parent_aor; - X509 *cert = NULL; - int depth = -1; - int i; - unsigned int length; - int ret = 1; - - /* We need a non-empty chain to test against. */ - if (sk_X509_num(chain) <= 0) - goto err; - /* We need either a store ctx or an extension to work with. */ - if (ctx == NULL && ext == NULL) - goto err; - /* If there is a store ctx, it needs a verify_cb. */ - if (ctx != NULL && ctx->verify_cb == NULL) - goto err; - - /* - * Figure out where to start. If we don't have an extension to check, - * (either extracted from the leaf or passed by the caller), we're done. - * Otherwise, check canonical form and set up for walking up the chain. - */ - if (ext == NULL) { - depth = 0; - cert = sk_X509_value(chain, depth); - if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) { - if ((ret = verify_error(ctx, cert, - X509_V_ERR_INVALID_EXTENSION, depth)) == 0) - goto done; - } - if ((ext = cert->rfc3779_addr) == NULL) - goto done; - } else if (!X509v3_addr_is_canonical(ext)) { - if ((ret = verify_error(ctx, cert, - X509_V_ERR_INVALID_EXTENSION, depth)) == 0) - goto done; - } - - (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); - if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - if (ctx != NULL) - ctx->error = X509_V_ERR_OUT_OF_MEM; - ret = 0; - goto done; - } - - /* - * Now walk up the chain. No cert may list resources that its parent - * doesn't list. - */ - for (depth++; depth < sk_X509_num(chain); depth++) { - cert = sk_X509_value(chain, depth); - - if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) { - if ((ret = verify_error(ctx, cert, - X509_V_ERR_INVALID_EXTENSION, depth)) == 0) - goto done; - } - - if ((parent = cert->rfc3779_addr) == NULL) { - for (i = 0; i < sk_IPAddressFamily_num(child); i++) { - child_af = sk_IPAddressFamily_value(child, i); - - if (IPAddressFamily_inheritance(child_af) != - NULL) - continue; - - if ((ret = verify_error(ctx, cert, - X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) - goto done; - break; - } - continue; - } - - /* - * Check that the child's resources are covered by the parent. - * Each covered resource is replaced with the parent's resource - * covering it, so the next iteration will check that the - * parent's resources are covered by the grandparent. - */ - for (i = 0; i < sk_IPAddressFamily_num(child); i++) { - child_af = sk_IPAddressFamily_value(child, i); - - if ((parent_af = IPAddressFamily_find_in_parent(parent, - child_af)) == NULL) { - /* - * If we have no match in the parent and the - * child inherits, that's fine. - */ - if (IPAddressFamily_inheritance(child_af) != - NULL) - continue; - - /* Otherwise the child isn't covered. */ - if ((ret = verify_error(ctx, cert, - X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) - goto done; - break; - } - - /* Parent inherits, nothing to do. */ - if (IPAddressFamily_inheritance(parent_af) != NULL) - continue; - - /* Child inherits. Use parent's address family. */ - if (IPAddressFamily_inheritance(child_af) != NULL) { - sk_IPAddressFamily_set(child, i, parent_af); - continue; - } - - child_aor = IPAddressFamily_addressesOrRanges(child_af); - parent_aor = - IPAddressFamily_addressesOrRanges(parent_af); - - /* - * Child and parent are canonical and neither inherits. - * If either addressesOrRanges is NULL, something's - * very wrong. - */ - if (child_aor == NULL || parent_aor == NULL) - goto err; - - if (!IPAddressFamily_afi_length(child_af, &length)) - goto err; - - /* Now check containment and replace or error. */ - if (addr_contains(parent_aor, child_aor, length)) { - sk_IPAddressFamily_set(child, i, parent_af); - continue; - } - - if ((ret = verify_error(ctx, cert, - X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) - goto done; - } - } - - /* - * Trust anchor can't inherit. - */ - if ((parent = cert->rfc3779_addr) != NULL) { - for (i = 0; i < sk_IPAddressFamily_num(parent); i++) { - parent_af = sk_IPAddressFamily_value(parent, i); - - if (IPAddressFamily_inheritance(parent_af) == NULL) - continue; - - if ((ret = verify_error(ctx, cert, - X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0) - goto done; - } - } - - done: - sk_IPAddressFamily_free(child); - return ret; - - err: - sk_IPAddressFamily_free(child); - - if (ctx != NULL) - ctx->error = X509_V_ERR_UNSPECIFIED; - - return 0; -} - -/* - * RFC 3779 2.3 path validation -- called from X509_verify_cert(). - */ -int -X509v3_addr_validate_path(X509_STORE_CTX *ctx) -{ - if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { - ctx->error = X509_V_ERR_UNSPECIFIED; - return 0; - } - return addr_validate_path_internal(ctx, ctx->chain, NULL); -} -LCRYPTO_ALIAS(X509v3_addr_validate_path); - -/* - * RFC 3779 2.3 path validation of an extension. - * Test whether chain covers extension. - */ -int -X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext, - int allow_inheritance) -{ - if (ext == NULL) - return 1; - if (sk_X509_num(chain) <= 0) - return 0; - if (!allow_inheritance && X509v3_addr_inherits(ext)) - return 0; - return addr_validate_path_internal(NULL, chain, ext); -} -LCRYPTO_ALIAS(X509v3_addr_validate_resource_set); - -#endif /* OPENSSL_NO_RFC3779 */ diff --git a/src/lib/libcrypto/x509/x509_akey.c b/src/lib/libcrypto/x509/x509_akey.c deleted file mode 100644 index 926508c4cd..0000000000 --- a/src/lib/libcrypto/x509/x509_akey.c +++ /dev/null @@ -1,245 +0,0 @@ -/* $OpenBSD: x509_akey.c,v 1.3 2024/08/31 10:03:03 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "x509_local.h" - -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist); -static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); - -static const X509V3_EXT_METHOD x509v3_ext_authority_key_identifier = { - .ext_nid = NID_authority_key_identifier, - .ext_flags = X509V3_EXT_MULTILINE, - .it = &AUTHORITY_KEYID_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID, - .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_authority_key_identifier(void) -{ - return &x509v3_ext_authority_key_identifier; -} - -static STACK_OF(CONF_VALUE) * -i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, AUTHORITY_KEYID *akeyid, - STACK_OF(CONF_VALUE) *extlist) -{ - STACK_OF(CONF_VALUE) *free_extlist = NULL; - char *tmpstr = NULL; - - if (extlist == NULL) { - if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - if (akeyid->keyid != NULL) { - if ((tmpstr = hex_to_string(akeyid->keyid->data, - akeyid->keyid->length)) == NULL) - goto err; - if (!X509V3_add_value("keyid", tmpstr, &extlist)) - goto err; - free(tmpstr); - tmpstr = NULL; - } - - if (akeyid->issuer != NULL) { - if ((extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, - extlist)) == NULL) - goto err; - } - - if (akeyid->serial != NULL) { - if ((tmpstr = hex_to_string(akeyid->serial->data, - akeyid->serial->length)) == NULL) - goto err; - if (!X509V3_add_value("serial", tmpstr, &extlist)) - goto err; - free(tmpstr); - tmpstr = NULL; - } - - if (sk_CONF_VALUE_num(extlist) <= 0) - goto err; - - return extlist; - - err: - free(tmpstr); - sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); - - return NULL; -} - -/* - * Currently two options: - * keyid: use the issuers subject keyid, the value 'always' means its is - * an error if the issuer certificate doesn't have a key id. - * issuer: use the issuers cert issuer and serial number. The default is - * to only use this if keyid is not present. With the option 'always' - * this is always included. - */ -static AUTHORITY_KEYID * -v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - char keyid = 0, issuer = 0; - int i; - CONF_VALUE *cnf; - ASN1_OCTET_STRING *ikeyid = NULL; - X509_NAME *isname = NULL; - STACK_OF(GENERAL_NAME) *gens = NULL; - GENERAL_NAME *gen = NULL; - ASN1_INTEGER *serial = NULL; - X509_EXTENSION *ext; - X509 *cert; - AUTHORITY_KEYID *akeyid = NULL; - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - cnf = sk_CONF_VALUE_value(values, i); - if (!strcmp(cnf->name, "keyid")) { - keyid = 1; - if (cnf->value && !strcmp(cnf->value, "always")) - keyid = 2; - } else if (!strcmp(cnf->name, "issuer")) { - issuer = 1; - if (cnf->value && !strcmp(cnf->value, "always")) - issuer = 2; - } else { - X509V3error(X509V3_R_UNKNOWN_OPTION); - ERR_asprintf_error_data("name=%s", cnf->name); - return NULL; - } - } - - if (!ctx || !ctx->issuer_cert) { - if (ctx && (ctx->flags == CTX_TEST)) - return AUTHORITY_KEYID_new(); - X509V3error(X509V3_R_NO_ISSUER_CERTIFICATE); - return NULL; - } - - cert = ctx->issuer_cert; - - if (keyid) { - i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); - if ((i >= 0) && (ext = X509_get_ext(cert, i))) - ikeyid = X509V3_EXT_d2i(ext); - if (keyid == 2 && !ikeyid) { - X509V3error(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); - return NULL; - } - } - - if ((issuer && !ikeyid) || (issuer == 2)) { - isname = X509_NAME_dup(X509_get_issuer_name(cert)); - serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); - if (!isname || !serial) { - X509V3error(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); - goto err; - } - } - - if (!(akeyid = AUTHORITY_KEYID_new())) - goto err; - - if (isname) { - if (!(gens = sk_GENERAL_NAME_new_null()) || - !(gen = GENERAL_NAME_new()) || - !sk_GENERAL_NAME_push(gens, gen)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - gen->type = GEN_DIRNAME; - gen->d.dirn = isname; - } - - akeyid->issuer = gens; - akeyid->serial = serial; - akeyid->keyid = ikeyid; - - return akeyid; - - err: - AUTHORITY_KEYID_free(akeyid); - GENERAL_NAME_free(gen); - sk_GENERAL_NAME_free(gens); - X509_NAME_free(isname); - ASN1_INTEGER_free(serial); - ASN1_OCTET_STRING_free(ikeyid); - return NULL; -} diff --git a/src/lib/libcrypto/x509/x509_akeya.c b/src/lib/libcrypto/x509/x509_akeya.c deleted file mode 100644 index e816e6b613..0000000000 --- a/src/lib/libcrypto/x509/x509_akeya.c +++ /dev/null @@ -1,129 +0,0 @@ -/* $OpenBSD: x509_akeya.c,v 1.4 2024/07/08 14:47:44 beck Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include -#include -#include -#include - -static const ASN1_TEMPLATE AUTHORITY_KEYID_seq_tt[] = { - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(AUTHORITY_KEYID, keyid), - .field_name = "keyid", - .item = &ASN1_OCTET_STRING_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(AUTHORITY_KEYID, issuer), - .field_name = "issuer", - .item = &GENERAL_NAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 2, - .offset = offsetof(AUTHORITY_KEYID, serial), - .field_name = "serial", - .item = &ASN1_INTEGER_it, - }, -}; - -const ASN1_ITEM AUTHORITY_KEYID_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = AUTHORITY_KEYID_seq_tt, - .tcount = sizeof(AUTHORITY_KEYID_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(AUTHORITY_KEYID), - .sname = "AUTHORITY_KEYID", -}; -LCRYPTO_ALIAS(AUTHORITY_KEYID_it); - - -AUTHORITY_KEYID * -d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len) -{ - return (AUTHORITY_KEYID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &AUTHORITY_KEYID_it); -} -LCRYPTO_ALIAS(d2i_AUTHORITY_KEYID); - -int -i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_KEYID_it); -} -LCRYPTO_ALIAS(i2d_AUTHORITY_KEYID); - -AUTHORITY_KEYID * -AUTHORITY_KEYID_new(void) -{ - return (AUTHORITY_KEYID *)ASN1_item_new(&AUTHORITY_KEYID_it); -} -LCRYPTO_ALIAS(AUTHORITY_KEYID_new); - -void -AUTHORITY_KEYID_free(AUTHORITY_KEYID *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_KEYID_it); -} -LCRYPTO_ALIAS(AUTHORITY_KEYID_free); diff --git a/src/lib/libcrypto/x509/x509_alt.c b/src/lib/libcrypto/x509/x509_alt.c deleted file mode 100644 index 34734a55bd..0000000000 --- a/src/lib/libcrypto/x509/x509_alt.c +++ /dev/null @@ -1,799 +0,0 @@ -/* $OpenBSD: x509_alt.c,v 1.19 2025/03/06 07:20:01 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include - -#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, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); -static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); -static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); - -static const X509V3_EXT_METHOD x509v3_ext_subject_alt_name = { - .ext_nid = NID_subject_alt_name, - .ext_flags = 0, - .it = &GENERAL_NAMES_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, - .v2i = (X509V3_EXT_V2I)v2i_subject_alt, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_subject_alt_name(void) -{ - return &x509v3_ext_subject_alt_name; -} - -static const X509V3_EXT_METHOD x509v3_ext_issuer_alt_name = { - .ext_nid = NID_issuer_alt_name, - .ext_flags = 0, - .it = &GENERAL_NAMES_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, - .v2i = (X509V3_EXT_V2I)v2i_issuer_alt, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_issuer_alt_name(void) -{ - return &x509v3_ext_issuer_alt_name; -} - -static const X509V3_EXT_METHOD x509v3_ext_certificate_issuer = { - .ext_nid = NID_certificate_issuer, - .ext_flags = 0, - .it = &GENERAL_NAMES_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_certificate_issuer(void) -{ - return &x509v3_ext_certificate_issuer; -} - -STACK_OF(CONF_VALUE) * -i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens, - STACK_OF(CONF_VALUE) *ret) -{ - STACK_OF(CONF_VALUE) *free_ret = NULL; - GENERAL_NAME *gen; - int i; - - if (ret == NULL) { - if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - if ((gen = sk_GENERAL_NAME_value(gens, i)) == NULL) - goto err; - if ((ret = i2v_GENERAL_NAME(method, gen, ret)) == NULL) - goto err; - } - - return ret; - - err: - sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); - - return NULL; -} -LCRYPTO_ALIAS(i2v_GENERAL_NAMES); - -STACK_OF(CONF_VALUE) * -i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, - STACK_OF(CONF_VALUE) *ret) -{ - STACK_OF(CONF_VALUE) *free_ret = NULL; - unsigned char *p; - char oline[256], htmp[5]; - int i; - - if (ret == NULL) { - if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - switch (gen->type) { - case GEN_OTHERNAME: - if (!X509V3_add_value("othername", "", &ret)) - goto err; - break; - - case GEN_X400: - if (!X509V3_add_value("X400Name", "", &ret)) - goto err; - break; - - case GEN_EDIPARTY: - if (!X509V3_add_value("EdiPartyName", "", &ret)) - goto err; - break; - - case GEN_EMAIL: - if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) - goto err; - break; - - case GEN_DNS: - if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) - goto err; - break; - - case GEN_URI: - if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) - goto err; - break; - - case GEN_DIRNAME: - if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL) - goto err; - if (!X509V3_add_value("DirName", oline, &ret)) - goto err; - break; - - case GEN_IPADD: /* XXX */ - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - (void) snprintf(oline, sizeof oline, - "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - oline[0] = 0; - for (i = 0; i < 8; i++) { - (void) snprintf(htmp, sizeof htmp, - "%X", p[0] << 8 | p[1]); - p += 2; - strlcat(oline, htmp, sizeof(oline)); - if (i != 7) - strlcat(oline, ":", sizeof(oline)); - } - } else { - if (!X509V3_add_value("IP Address", "", &ret)) - goto err; - break; - } - if (!X509V3_add_value("IP Address", oline, &ret)) - goto err; - break; - - case GEN_RID: - if (!i2t_ASN1_OBJECT(oline, 256, gen->d.rid)) - goto err; - if (!X509V3_add_value("Registered ID", oline, &ret)) - goto err; - break; - } - - return ret; - - err: - sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); - - return NULL; -} -LCRYPTO_ALIAS(i2v_GENERAL_NAME); - -int -GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) -{ - unsigned char *p; - int i; - - switch (gen->type) { - case GEN_OTHERNAME: - BIO_printf(out, "othername:"); - break; - - case GEN_X400: - BIO_printf(out, "X400Name:"); - break; - - case GEN_EDIPARTY: - /* Maybe fix this: it is supported now */ - BIO_printf(out, "EdiPartyName:"); - break; - - case GEN_EMAIL: - 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->length, - gen->d.ia5->data); - break; - - case GEN_URI: - BIO_printf(out, "URI:%.*s", gen->d.ia5->length, - gen->d.ia5->data); - break; - - case GEN_DIRNAME: - BIO_printf(out, "DirName: "); - X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); - break; - - case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_printf(out, "IP Address:%d.%d.%d.%d", - p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - BIO_printf(out, "IP Address"); - for (i = 0; i < 8; i++) { - BIO_printf(out, ":%X", p[0] << 8 | p[1]); - p += 2; - } - BIO_puts(out, "\n"); - } else { - BIO_printf(out, "IP Address:"); - break; - } - break; - - case GEN_RID: - BIO_printf(out, "Registered ID"); - i2a_ASN1_OBJECT(out, gen->d.rid); - break; - } - return 1; -} -LCRYPTO_ALIAS(GENERAL_NAME_print); - -static GENERAL_NAMES * -v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - int i; - - if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL && - strcmp(cnf->value, "copy") == 0) { - if (!copy_issuer(ctx, gens)) - goto err; - } else { - GENERAL_NAME *gen; - if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) - goto err; - if (sk_GENERAL_NAME_push(gens, gen) == 0) { - GENERAL_NAME_free(gen); - goto err; - } - } - } - return gens; - -err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; -} - -/* Append subject altname of issuer to issuer alt name of subject */ - -static int -copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) -{ - GENERAL_NAMES *ialt = NULL; - GENERAL_NAME *gen = NULL; - X509_EXTENSION *ext; - int i; - int ret = 0; - - if (ctx && (ctx->flags == CTX_TEST)) - return 1; - if (!ctx || !ctx->issuer_cert) { - X509V3error(X509V3_R_NO_ISSUER_DETAILS); - goto err; - } - i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); - if (i < 0) - return 1; - if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || - !(ialt = X509V3_EXT_d2i(ext))) { - X509V3error(X509V3_R_ISSUER_DECODE_ERROR); - goto err; - } - - for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { - GENERAL_NAME *val = sk_GENERAL_NAME_value(ialt, i); - - if ((gen = GENERAL_NAME_dup(val)) == NULL) - goto err; - if (!sk_GENERAL_NAME_push(gens, gen)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - gen = NULL; - } - - ret = 1; - - err: - sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); - GENERAL_NAME_free(gen); - - return ret; -} - -static GENERAL_NAMES * -v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - int i; - - if (!(gens = sk_GENERAL_NAME_new_null())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "copy")) { - if (!copy_email(ctx, gens, 0)) - goto err; - } else if (!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "move")) { - if (!copy_email(ctx, gens, 1)) - goto err; - } else { - GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - if (sk_GENERAL_NAME_push(gens, gen) == 0) { - GENERAL_NAME_free(gen); - goto err; - } - } - } - return gens; - -err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; -} - -/* Copy any email addresses in a certificate or request to - * GENERAL_NAMES - */ - -static int -copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) -{ - X509_NAME *nm; - ASN1_IA5STRING *email = NULL; - X509_NAME_ENTRY *ne; - GENERAL_NAME *gen = NULL; - int i; - - if (ctx != NULL && ctx->flags == CTX_TEST) - return 1; - if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { - X509V3error(X509V3_R_NO_SUBJECT_DETAILS); - goto err; - } - /* Find the subject name */ - if (ctx->subject_cert) - nm = X509_get_subject_name(ctx->subject_cert); - else - nm = X509_REQ_get_subject_name(ctx->subject_req); - - /* Now add any email address(es) to STACK */ - i = -1; - while ((i = X509_NAME_get_index_by_NID(nm, - NID_pkcs9_emailAddress, i)) >= 0) { - ne = X509_NAME_get_entry(nm, i); - email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); - if (move_p) { - X509_NAME_delete_entry(nm, i); - X509_NAME_ENTRY_free(ne); - i--; - } - if (!email || !(gen = GENERAL_NAME_new())) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - gen->d.ia5 = email; - email = NULL; - gen->type = GEN_EMAIL; - if (!sk_GENERAL_NAME_push(gens, gen)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - gen = NULL; - } - - return 1; - -err: - GENERAL_NAME_free(gen); - ASN1_IA5STRING_free(email); - return 0; -} - -GENERAL_NAMES * -v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAME *gen; - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - int i; - - if (!(gens = sk_GENERAL_NAME_new_null())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - if (sk_GENERAL_NAME_push(gens, gen) == 0) { - GENERAL_NAME_free(gen); - goto err; - } - } - return gens; - -err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; -} -LCRYPTO_ALIAS(v2i_GENERAL_NAMES); - -GENERAL_NAME * -v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf) -{ - return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); -} -LCRYPTO_ALIAS(v2i_GENERAL_NAME); - -GENERAL_NAME * -a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, const char *value, int is_nc) -{ - char is_string = 0; - GENERAL_NAME *gen = NULL; - - if (!value) { - X509V3error(X509V3_R_MISSING_VALUE); - return NULL; - } - - if (out) - gen = out; - else { - gen = GENERAL_NAME_new(); - if (gen == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - } - - switch (gen_type) { - case GEN_URI: - case GEN_EMAIL: - case GEN_DNS: - is_string = 1; - break; - - case GEN_RID: - { - ASN1_OBJECT *obj; - if (!(obj = OBJ_txt2obj(value, 0))) { - X509V3error(X509V3_R_BAD_OBJECT); - ERR_asprintf_error_data("value=%s", value); - goto err; - } - gen->d.rid = obj; - } - break; - - case GEN_IPADD: - if (is_nc) - gen->d.ip = a2i_IPADDRESS_NC(value); - else - gen->d.ip = a2i_IPADDRESS(value); - if (gen->d.ip == NULL) { - X509V3error(X509V3_R_BAD_IP_ADDRESS); - ERR_asprintf_error_data("value=%s", value); - goto err; - } - break; - - case GEN_DIRNAME: - if (!do_dirname(gen, value, ctx)) { - X509V3error(X509V3_R_DIRNAME_ERROR); - goto err; - } - break; - - case GEN_OTHERNAME: - if (!do_othername(gen, value, ctx)) { - X509V3error(X509V3_R_OTHERNAME_ERROR); - goto err; - } - break; - - default: - X509V3error(X509V3_R_UNSUPPORTED_TYPE); - goto err; - } - - if (is_string) { - if (!(gen->d.ia5 = ASN1_IA5STRING_new()) || - !ASN1_STRING_set(gen->d.ia5, value, strlen(value))) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - } - - gen->type = gen_type; - - return gen; - -err: - if (out == NULL) - GENERAL_NAME_free(gen); - return NULL; -} -LCRYPTO_ALIAS(a2i_GENERAL_NAME); - -GENERAL_NAME * -v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) -{ - uint8_t *bytes = NULL; - char *name, *value; - GENERAL_NAME *ret; - size_t len = 0; - int type; - CBS cbs; - - name = cnf->name; - value = cnf->value; - - if (!value) { - X509V3error(X509V3_R_MISSING_VALUE); - return NULL; - } - - if (!name_cmp(name, "email")) - type = GEN_EMAIL; - else if (!name_cmp(name, "URI")) - type = GEN_URI; - else if (!name_cmp(name, "DNS")) - type = GEN_DNS; - else if (!name_cmp(name, "RID")) - type = GEN_RID; - else if (!name_cmp(name, "IP")) - type = GEN_IPADD; - else if (!name_cmp(name, "dirName")) - type = GEN_DIRNAME; - else if (!name_cmp(name, "otherName")) - type = GEN_OTHERNAME; - else { - X509V3error(X509V3_R_UNSUPPORTED_OPTION); - ERR_asprintf_error_data("name=%s", name); - return NULL; - } - - 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); - CBS_init(&cbs, bytes, len); - switch (type) { - case GEN_DNS: - if (!x509_constraints_valid_sandns(&cbs)) { - 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(&cbs, 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; -} -LCRYPTO_ALIAS(v2i_GENERAL_NAME_ex); - -static int -do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) -{ - char *objtmp = NULL, *p; - int objlen; - - if (!(p = strchr(value, ';'))) - return 0; - if (!(gen->d.otherName = OTHERNAME_new())) - return 0; - /* Free this up because we will overwrite it. - * no need to free type_id because it is static - */ - ASN1_TYPE_free(gen->d.otherName->value); - if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) - return 0; - objlen = p - value; - objtmp = malloc(objlen + 1); - if (objtmp) { - strlcpy(objtmp, value, objlen + 1); - gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); - free(objtmp); - } else - gen->d.otherName->type_id = NULL; - if (!gen->d.otherName->type_id) - return 0; - return 1; -} - -static int -do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) -{ - int ret; - STACK_OF(CONF_VALUE) *sk; - X509_NAME *nm; - - if (!(nm = X509_NAME_new())) - return 0; - sk = X509V3_get0_section(ctx, value); - if (!sk) { - X509V3error(X509V3_R_SECTION_NOT_FOUND); - ERR_asprintf_error_data("section=%s", value); - X509_NAME_free(nm); - return 0; - } - /* FIXME: should allow other character types... */ - ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); - if (!ret) - X509_NAME_free(nm); - gen->d.dirn = nm; - - return ret; -} diff --git a/src/lib/libcrypto/x509/x509_asid.c b/src/lib/libcrypto/x509/x509_asid.c deleted file mode 100644 index 40ee201a9f..0000000000 --- a/src/lib/libcrypto/x509/x509_asid.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* $OpenBSD: x509_asid.c,v 1.45 2024/07/13 15:08:58 tb Exp $ */ -/* - * Contributed to the OpenSSL Project by the American Registry for - * Internet Numbers ("ARIN"). - */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - */ - -/* - * Implementation of RFC 3779 section 3.2. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "x509_local.h" - -#ifndef OPENSSL_NO_RFC3779 - -static const ASN1_TEMPLATE ASRange_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(ASRange, min), - .field_name = "min", - .item = &ASN1_INTEGER_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(ASRange, max), - .field_name = "max", - .item = &ASN1_INTEGER_it, - }, -}; - -const ASN1_ITEM ASRange_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = ASRange_seq_tt, - .tcount = sizeof(ASRange_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(ASRange), - .sname = "ASRange", -}; -LCRYPTO_ALIAS(ASRange_it); - -static const ASN1_TEMPLATE ASIdOrRange_ch_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(ASIdOrRange, u.id), - .field_name = "u.id", - .item = &ASN1_INTEGER_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(ASIdOrRange, u.range), - .field_name = "u.range", - .item = &ASRange_it, - }, -}; - -const ASN1_ITEM ASIdOrRange_it = { - .itype = ASN1_ITYPE_CHOICE, - .utype = offsetof(ASIdOrRange, type), - .templates = ASIdOrRange_ch_tt, - .tcount = sizeof(ASIdOrRange_ch_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(ASIdOrRange), - .sname = "ASIdOrRange", -}; -LCRYPTO_ALIAS(ASIdOrRange_it); - -static const ASN1_TEMPLATE ASIdentifierChoice_ch_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(ASIdentifierChoice, u.inherit), - .field_name = "u.inherit", - .item = &ASN1_NULL_it, - }, - { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = offsetof(ASIdentifierChoice, u.asIdsOrRanges), - .field_name = "u.asIdsOrRanges", - .item = &ASIdOrRange_it, - }, -}; - -const ASN1_ITEM ASIdentifierChoice_it = { - .itype = ASN1_ITYPE_CHOICE, - .utype = offsetof(ASIdentifierChoice, type), - .templates = ASIdentifierChoice_ch_tt, - .tcount = sizeof(ASIdentifierChoice_ch_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(ASIdentifierChoice), - .sname = "ASIdentifierChoice", -}; -LCRYPTO_ALIAS(ASIdentifierChoice_it); - -static const ASN1_TEMPLATE ASIdentifiers_seq_tt[] = { - { - .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(ASIdentifiers, asnum), - .field_name = "asnum", - .item = &ASIdentifierChoice_it, - }, - { - .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(ASIdentifiers, rdi), - .field_name = "rdi", - .item = &ASIdentifierChoice_it, - }, -}; - -const ASN1_ITEM ASIdentifiers_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = ASIdentifiers_seq_tt, - .tcount = sizeof(ASIdentifiers_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(ASIdentifiers), - .sname = "ASIdentifiers", -}; -LCRYPTO_ALIAS(ASIdentifiers_it); - -ASRange * -d2i_ASRange(ASRange **a, const unsigned char **in, long len) -{ - return (ASRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ASRange_it); -} -LCRYPTO_ALIAS(d2i_ASRange); - -int -i2d_ASRange(ASRange *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASRange_it); -} -LCRYPTO_ALIAS(i2d_ASRange); - -ASRange * -ASRange_new(void) -{ - return (ASRange *)ASN1_item_new(&ASRange_it); -} -LCRYPTO_ALIAS(ASRange_new); - -void -ASRange_free(ASRange *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &ASRange_it); -} -LCRYPTO_ALIAS(ASRange_free); - -ASIdOrRange * -d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, long len) -{ - return (ASIdOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ASIdOrRange_it); -} -LCRYPTO_ALIAS(d2i_ASIdOrRange); - -int -i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdOrRange_it); -} -LCRYPTO_ALIAS(i2d_ASIdOrRange); - -ASIdOrRange * -ASIdOrRange_new(void) -{ - return (ASIdOrRange *)ASN1_item_new(&ASIdOrRange_it); -} -LCRYPTO_ALIAS(ASIdOrRange_new); - -void -ASIdOrRange_free(ASIdOrRange *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &ASIdOrRange_it); -} -LCRYPTO_ALIAS(ASIdOrRange_free); - -ASIdentifierChoice * -d2i_ASIdentifierChoice(ASIdentifierChoice **a, const unsigned char **in, - long len) -{ - return (ASIdentifierChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ASIdentifierChoice_it); -} -LCRYPTO_ALIAS(d2i_ASIdentifierChoice); - -int -i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifierChoice_it); -} -LCRYPTO_ALIAS(i2d_ASIdentifierChoice); - -ASIdentifierChoice * -ASIdentifierChoice_new(void) -{ - return (ASIdentifierChoice *)ASN1_item_new(&ASIdentifierChoice_it); -} -LCRYPTO_ALIAS(ASIdentifierChoice_new); - -void -ASIdentifierChoice_free(ASIdentifierChoice *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &ASIdentifierChoice_it); -} -LCRYPTO_ALIAS(ASIdentifierChoice_free); - -ASIdentifiers * -d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, long len) -{ - return (ASIdentifiers *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ASIdentifiers_it); -} -LCRYPTO_ALIAS(d2i_ASIdentifiers); - -int -i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifiers_it); -} -LCRYPTO_ALIAS(i2d_ASIdentifiers); - -ASIdentifiers * -ASIdentifiers_new(void) -{ - return (ASIdentifiers *)ASN1_item_new(&ASIdentifiers_it); -} -LCRYPTO_ALIAS(ASIdentifiers_new); - -void -ASIdentifiers_free(ASIdentifiers *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &ASIdentifiers_it); -} -LCRYPTO_ALIAS(ASIdentifiers_free); - -/* - * i2r method for an ASIdentifierChoice. - */ -static int -i2r_ASIdentifierChoice(BIO *out, ASIdentifierChoice *choice, int indent, - const char *msg) -{ - int i; - char *s; - if (choice == NULL) - return 1; - BIO_printf(out, "%*s%s:\n", indent, "", msg); - switch (choice->type) { - case ASIdentifierChoice_inherit: - BIO_printf(out, "%*sinherit\n", indent + 2, ""); - break; - case ASIdentifierChoice_asIdsOrRanges: - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); - i++) { - ASIdOrRange *aor = - sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - switch (aor->type) { - case ASIdOrRange_id: - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == - NULL) - return 0; - BIO_printf(out, "%*s%s\n", indent + 2, "", s); - free(s); - break; - case ASIdOrRange_range: - if ((s = i2s_ASN1_INTEGER(NULL, - aor->u.range->min)) == NULL) - return 0; - BIO_printf(out, "%*s%s-", indent + 2, "", s); - free(s); - if ((s = i2s_ASN1_INTEGER(NULL, - aor->u.range->max)) == NULL) - return 0; - BIO_printf(out, "%s\n", s); - free(s); - break; - default: - return 0; - } - } - break; - default: - return 0; - } - return 1; -} - -/* - * i2r method for an ASIdentifier extension. - */ -static int -i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out, - int indent) -{ - ASIdentifiers *asid = ext; - return (i2r_ASIdentifierChoice(out, asid->asnum, indent, - "Autonomous System Numbers") && - i2r_ASIdentifierChoice(out, asid->rdi, indent, - "Routing Domain Identifiers")); -} - -/* - * Sort comparison function for a sequence of ASIdOrRange elements. - */ -static int -ASIdOrRange_cmp(const ASIdOrRange *const *a_, const ASIdOrRange *const *b_) -{ - const ASIdOrRange *a = *a_, *b = *b_; - - /* XXX: these asserts need to be replaced */ - OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || - (a->type == ASIdOrRange_range && a->u.range != NULL && - a->u.range->min != NULL && a->u.range->max != NULL)); - - OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || - (b->type == ASIdOrRange_range && b->u.range != NULL && - b->u.range->min != NULL && b->u.range->max != NULL)); - - if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) - return ASN1_INTEGER_cmp(a->u.id, b->u.id); - - if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { - int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); - return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, - b->u.range->max); - } - - if (a->type == ASIdOrRange_id) - return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); - else - return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); -} - -/* - * Add an inherit element. - */ -int -X509v3_asid_add_inherit(ASIdentifiers *asid, int which) -{ - ASIdentifierChoice **choice; - ASIdentifierChoice *aic = NULL; - int ret = 0; - - if (asid == NULL) - goto err; - - switch (which) { - case V3_ASID_ASNUM: - choice = &asid->asnum; - break; - case V3_ASID_RDI: - choice = &asid->rdi; - break; - default: - goto err; - } - - if (*choice != NULL) { - if ((*choice)->type != ASIdentifierChoice_inherit) - goto err; - } else { - if ((aic = ASIdentifierChoice_new()) == NULL) - goto err; - if ((aic->u.inherit = ASN1_NULL_new()) == NULL) - goto err; - aic->type = ASIdentifierChoice_inherit; - - *choice = aic; - aic = NULL; - } - - ret = 1; - - err: - ASIdentifierChoice_free(aic); - - return ret; -} -LCRYPTO_ALIAS(X509v3_asid_add_inherit); - -static int -ASIdOrRanges_add_id_or_range(ASIdOrRanges *aors, ASN1_INTEGER *min, - ASN1_INTEGER *max) -{ - ASIdOrRange *aor = NULL; - ASRange *asr = NULL; - int ret = 0; - - /* Preallocate since we must not fail after sk_ASIdOrRange_push(). */ - if (max != NULL) { - if ((asr = ASRange_new()) == NULL) - goto err; - } - - if ((aor = ASIdOrRange_new()) == NULL) - goto err; - if (sk_ASIdOrRange_push(aors, aor) <= 0) - goto err; - - if (max == NULL) { - aor->type = ASIdOrRange_id; - aor->u.id = min; - } else { - ASN1_INTEGER_free(asr->min); - asr->min = min; - ASN1_INTEGER_free(asr->max); - asr->max = max; - - aor->type = ASIdOrRange_range; - aor->u.range = asr; - asr = NULL; - } - - aor = NULL; - - ret = 1; - - err: - ASIdOrRange_free(aor); - ASRange_free(asr); - - return ret; -} - -/* - * Add an ID or range to an ASIdentifierChoice. - */ -int -X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min, - ASN1_INTEGER *max) -{ - ASIdentifierChoice **choice; - ASIdentifierChoice *aic = NULL, *new_aic = NULL; - int ret = 0; - - if (asid == NULL) - goto err; - - switch (which) { - case V3_ASID_ASNUM: - choice = &asid->asnum; - break; - case V3_ASID_RDI: - choice = &asid->rdi; - break; - default: - goto err; - } - - if ((aic = *choice) != NULL) { - if (aic->type != ASIdentifierChoice_asIdsOrRanges) - goto err; - } else { - if ((aic = new_aic = ASIdentifierChoice_new()) == NULL) - goto err; - aic->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); - if (aic->u.asIdsOrRanges == NULL) - goto err; - aic->type = ASIdentifierChoice_asIdsOrRanges; - } - - if (!ASIdOrRanges_add_id_or_range(aic->u.asIdsOrRanges, min, max)) - goto err; - - *choice = aic; - aic = new_aic = NULL; - - ret = 1; - - err: - ASIdentifierChoice_free(new_aic); - - return ret; -} -LCRYPTO_ALIAS(X509v3_asid_add_id_or_range); - -/* - * Extract min and max values from an ASIdOrRange. - */ -static int -extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) -{ - switch (aor->type) { - case ASIdOrRange_id: - *min = aor->u.id; - *max = aor->u.id; - return 1; - case ASIdOrRange_range: - *min = aor->u.range->min; - *max = aor->u.range->max; - return 1; - } - *min = NULL; - *max = NULL; - - return 0; -} - -/* - * Check whether an ASIdentifierChoice is in canonical form. - */ -static int -ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) -{ - ASIdOrRange *a, *b; - ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max = NULL; - ASN1_INTEGER *a_max_plus_one = NULL; - ASN1_INTEGER *orig; - BIGNUM *bn = NULL; - int i, ret = 0; - - /* - * Empty element or inheritance is canonical. - */ - if (choice == NULL || choice->type == ASIdentifierChoice_inherit) - return 1; - - /* - * If not a list, or if empty list, it's broken. - */ - if (choice->type != ASIdentifierChoice_asIdsOrRanges || - sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) - return 0; - - /* - * It's a list, check it. - */ - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { - a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); - - if (!extract_min_max(a, &a_min, &a_max) || - !extract_min_max(b, &b_min, &b_max)) - goto done; - - /* - * Punt misordered list, overlapping start, or inverted range. - */ - if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || - ASN1_INTEGER_cmp(a_min, a_max) > 0 || - ASN1_INTEGER_cmp(b_min, b_max) > 0) - goto done; - - /* - * Calculate a_max + 1 to check for adjacency. - */ - if ((bn == NULL && (bn = BN_new()) == NULL) || - ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto done; - } - - if ((a_max_plus_one = - BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { - a_max_plus_one = orig; - X509V3error(ERR_R_MALLOC_FAILURE); - goto done; - } - - /* - * Punt if adjacent or overlapping. - */ - if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) - goto done; - } - - /* - * Check for inverted range. - */ - i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; - a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - if (a != NULL && a->type == ASIdOrRange_range) { - if (!extract_min_max(a, &a_min, &a_max) || - ASN1_INTEGER_cmp(a_min, a_max) > 0) - goto done; - } - - ret = 1; - - done: - ASN1_INTEGER_free(a_max_plus_one); - BN_free(bn); - return ret; -} - -/* - * Check whether an ASIdentifier extension is in canonical form. - */ -int -X509v3_asid_is_canonical(ASIdentifiers *asid) -{ - return (asid == NULL || - (ASIdentifierChoice_is_canonical(asid->asnum) && - ASIdentifierChoice_is_canonical(asid->rdi))); -} -LCRYPTO_ALIAS(X509v3_asid_is_canonical); - -/* - * Whack an ASIdentifierChoice into canonical form. - */ -static int -ASIdentifierChoice_canonize(ASIdentifierChoice *choice) -{ - ASIdOrRange *a, *b; - ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max = NULL; - ASN1_INTEGER *a_max_plus_one = NULL; - ASN1_INTEGER *orig; - BIGNUM *bn = NULL; - int i, ret = 0; - - /* - * Nothing to do for empty element or inheritance. - */ - if (choice == NULL || choice->type == ASIdentifierChoice_inherit) - return 1; - - /* - * If not a list, or if empty list, it's broken. - */ - if (choice->type != ASIdentifierChoice_asIdsOrRanges || - sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - return 0; - } - - /* - * We have a non-empty list. Sort it. - */ - sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); - - /* - * Now check for errors and suboptimal encoding, rejecting the - * former and fixing the latter. - */ - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { - a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); - - if (!extract_min_max(a, &a_min, &a_max) || - !extract_min_max(b, &b_min, &b_max)) - goto done; - - /* - * Make sure we're properly sorted (paranoia). - */ - if (ASN1_INTEGER_cmp(a_min, b_min) > 0) - goto done; - - /* - * Punt inverted ranges. - */ - if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || - ASN1_INTEGER_cmp(b_min, b_max) > 0) - goto done; - - /* - * Check for overlaps. - */ - if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - goto done; - } - - /* - * Calculate a_max + 1 to check for adjacency. - */ - if ((bn == NULL && (bn = BN_new()) == NULL) || - ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto done; - } - - if ((a_max_plus_one = - BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { - a_max_plus_one = orig; - X509V3error(ERR_R_MALLOC_FAILURE); - goto done; - } - - /* - * If a and b are adjacent, merge them. - */ - if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { - ASRange *r; - switch (a->type) { - case ASIdOrRange_id: - if ((r = calloc(1, sizeof(*r))) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto done; - } - r->min = a_min; - r->max = b_max; - a->type = ASIdOrRange_range; - a->u.range = r; - break; - case ASIdOrRange_range: - ASN1_INTEGER_free(a->u.range->max); - a->u.range->max = b_max; - break; - } - switch (b->type) { - case ASIdOrRange_id: - b->u.id = NULL; - break; - case ASIdOrRange_range: - b->u.range->max = NULL; - break; - } - ASIdOrRange_free(b); - (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, - i + 1); - i--; - continue; - } - } - - /* - * Check for final inverted range. - */ - i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; - a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - if (a != NULL && a->type == ASIdOrRange_range) { - if (!extract_min_max(a, &a_min, &a_max) || - ASN1_INTEGER_cmp(a_min, a_max) > 0) - goto done; - } - - /* Paranoia */ - if (!ASIdentifierChoice_is_canonical(choice)) - goto done; - - ret = 1; - - done: - ASN1_INTEGER_free(a_max_plus_one); - BN_free(bn); - return ret; -} - -/* - * Whack an ASIdentifier extension into canonical form. - */ -int -X509v3_asid_canonize(ASIdentifiers *asid) -{ - if (asid == NULL) - return 1; - - if (!ASIdentifierChoice_canonize(asid->asnum)) - return 0; - - return ASIdentifierChoice_canonize(asid->rdi); -} -LCRYPTO_ALIAS(X509v3_asid_canonize); - -/* - * v2i method for an ASIdentifier extension. - */ -static void * -v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE)*values) -{ - ASN1_INTEGER *min = NULL, *max = NULL; - ASIdentifiers *asid = NULL; - int i; - - if ((asid = ASIdentifiers_new()) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - CONF_VALUE *val = sk_CONF_VALUE_value(values, i); - int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0; - - /* - * Figure out whether this is an AS or an RDI. - */ - if (!name_cmp(val->name, "AS")) { - which = V3_ASID_ASNUM; - } else if (!name_cmp(val->name, "RDI")) { - which = V3_ASID_RDI; - } else { - X509V3error(X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); - goto err; - } - - /* - * Handle inheritance. - */ - if (strcmp(val->value, "inherit") == 0) { - if (X509v3_asid_add_inherit(asid, which)) - continue; - X509V3error(X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); - goto err; - } - - /* - * Number, range, or mistake, pick it apart and figure out which - */ - i1 = strspn(val->value, "0123456789"); - if (val->value[i1] == '\0') { - is_range = 0; - } else { - is_range = 1; - i2 = i1 + strspn(val->value + i1, " \t"); - if (val->value[i2] != '-') { - X509V3error(X509V3_R_INVALID_ASNUMBER); - X509V3_conf_err(val); - goto err; - } - i2++; - i2 = i2 + strspn(val->value + i2, " \t"); - i3 = i2 + strspn(val->value + i2, "0123456789"); - if (val->value[i3] != '\0') { - X509V3error(X509V3_R_INVALID_ASRANGE); - X509V3_conf_err(val); - goto err; - } - } - - /* - * Syntax is ok, read and add it. - */ - if (!is_range) { - if (!X509V3_get_value_int(val, &min)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - } else { - char *s = strdup(val->value); - if (s == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - s[i1] = '\0'; - min = s2i_ASN1_INTEGER(NULL, s); - max = s2i_ASN1_INTEGER(NULL, s + i2); - free(s); - if (min == NULL || max == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - if (ASN1_INTEGER_cmp(min, max) > 0) { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - goto err; - } - } - if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - min = max = NULL; - } - - /* - * Canonize the result, then we're done. - */ - if (!X509v3_asid_canonize(asid)) - goto err; - return asid; - - err: - ASIdentifiers_free(asid); - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); - return NULL; -} - -/* - * OpenSSL dispatch. - */ -static const X509V3_EXT_METHOD x509v3_ext_sbgp_autonomousSysNum = { - .ext_nid = NID_sbgp_autonomousSysNum, - .ext_flags = 0, - .it = &ASIdentifiers_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = v2i_ASIdentifiers, - .i2r = i2r_ASIdentifiers, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_sbgp_autonomousSysNum(void) -{ - return &x509v3_ext_sbgp_autonomousSysNum; -} - -/* - * Figure out whether extension uses inheritance. - */ -int -X509v3_asid_inherits(ASIdentifiers *asid) -{ - if (asid == NULL) - return 0; - - if (asid->asnum != NULL) { - if (asid->asnum->type == ASIdentifierChoice_inherit) - return 1; - } - - if (asid->rdi != NULL) { - if (asid->rdi->type == ASIdentifierChoice_inherit) - return 1; - } - - return 0; -} -LCRYPTO_ALIAS(X509v3_asid_inherits); - -/* - * Figure out whether parent contains child. - */ -static int -asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) -{ - ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL; - int p, c; - - if (child == NULL || parent == child) - return 1; - - if (parent == NULL) - return 0; - - p = 0; - for (c = 0; c < sk_ASIdOrRange_num(child); c++) { - if (!extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, - &c_max)) - return 0; - for (;; p++) { - if (p >= sk_ASIdOrRange_num(parent)) - return 0; - if (!extract_min_max(sk_ASIdOrRange_value(parent, p), - &p_min, &p_max)) - return 0; - if (ASN1_INTEGER_cmp(p_max, c_max) < 0) - continue; - if (ASN1_INTEGER_cmp(p_min, c_min) > 0) - return 0; - break; - } - } - - return 1; -} - -/* - * Test whether child is a subset of parent. - */ -int -X509v3_asid_subset(ASIdentifiers *child, ASIdentifiers *parent) -{ - if (child == NULL || child == parent) - return 1; - - if (parent == NULL) - return 0; - - if (X509v3_asid_inherits(child) || X509v3_asid_inherits(parent)) - return 0; - - if (child->asnum != NULL) { - if (parent->asnum == NULL) - return 0; - - if (!asid_contains(parent->asnum->u.asIdsOrRanges, - child->asnum->u.asIdsOrRanges)) - return 0; - } - - if (child->rdi != NULL) { - if (parent->rdi == NULL) - return 0; - - if (!asid_contains(parent->rdi->u.asIdsOrRanges, - child->rdi->u.asIdsOrRanges)) - return 0; - } - - return 1; -} -LCRYPTO_ALIAS(X509v3_asid_subset); - -/* - * Validation error handling via callback. - */ -#define validation_err(_err_) \ - do { \ - if (ctx != NULL) { \ - ctx->error = _err_; \ - ctx->error_depth = i; \ - ctx->current_cert = x; \ - ret = ctx->verify_cb(0, ctx); \ - } else { \ - ret = 0; \ - } \ - if (!ret) \ - goto done; \ - } while (0) - -/* - * Core code for RFC 3779 3.3 path validation. - */ -static int -asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, - ASIdentifiers *ext) -{ - ASIdOrRanges *child_as = NULL, *child_rdi = NULL; - int i, ret = 1, inherit_as = 0, inherit_rdi = 0; - X509 *x; - - /* We need a non-empty chain to test against. */ - if (sk_X509_num(chain) <= 0) - goto err; - /* We need either a store ctx or an extension to work with. */ - if (ctx == NULL && ext == NULL) - goto err; - /* If there is a store ctx, it needs a verify_cb. */ - if (ctx != NULL && ctx->verify_cb == NULL) - goto err; - - /* - * Figure out where to start. If we don't have an extension to check, - * (either extracted from the leaf or passed by the caller), we're done. - * Otherwise, check canonical form and set up for walking up the chain. - */ - if (ext != NULL) { - i = -1; - x = NULL; - if (!X509v3_asid_is_canonical(ext)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - } else { - i = 0; - x = sk_X509_value(chain, i); - if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) - goto done; - if ((ext = x->rfc3779_asid) == NULL) - goto done; - } - if (ext->asnum != NULL) { - switch (ext->asnum->type) { - case ASIdentifierChoice_inherit: - inherit_as = 1; - break; - case ASIdentifierChoice_asIdsOrRanges: - child_as = ext->asnum->u.asIdsOrRanges; - break; - } - } - if (ext->rdi != NULL) { - switch (ext->rdi->type) { - case ASIdentifierChoice_inherit: - inherit_rdi = 1; - break; - case ASIdentifierChoice_asIdsOrRanges: - child_rdi = ext->rdi->u.asIdsOrRanges; - break; - } - } - - /* - * Now walk up the chain. Extensions must be in canonical form, no - * cert may list resources that its parent doesn't list. - */ - for (i++; i < sk_X509_num(chain); i++) { - x = sk_X509_value(chain, i); - - if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) - validation_err(X509_V_ERR_INVALID_EXTENSION); - if (x->rfc3779_asid == NULL) { - if (child_as != NULL || child_rdi != NULL) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - continue; - } - if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - child_as = NULL; - inherit_as = 0; - } - if (x->rfc3779_asid->asnum != NULL && - x->rfc3779_asid->asnum->type == - ASIdentifierChoice_asIdsOrRanges) { - if (inherit_as || - asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, - child_as)) { - child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; - inherit_as = 0; - } else { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - child_rdi = NULL; - inherit_rdi = 0; - } - if (x->rfc3779_asid->rdi != NULL && - x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { - if (inherit_rdi || - asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, - child_rdi)) { - child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; - inherit_rdi = 0; - } else { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - } - - /* - * Trust anchor can't inherit. - */ - - if (x == NULL) - goto err; - - if (x->rfc3779_asid != NULL) { - if (x->rfc3779_asid->asnum != NULL && - x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - if (x->rfc3779_asid->rdi != NULL && - x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - - done: - return ret; - - err: - if (ctx != NULL) - ctx->error = X509_V_ERR_UNSPECIFIED; - - return 0; -} - -#undef validation_err - -/* - * RFC 3779 3.3 path validation -- called from X509_verify_cert(). - */ -int -X509v3_asid_validate_path(X509_STORE_CTX *ctx) -{ - if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { - ctx->error = X509_V_ERR_UNSPECIFIED; - return 0; - } - return asid_validate_path_internal(ctx, ctx->chain, NULL); -} -LCRYPTO_ALIAS(X509v3_asid_validate_path); - -/* - * RFC 3779 3.3 path validation of an extension. - * Test whether chain covers extension. - */ -int -X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, - int allow_inheritance) -{ - if (ext == NULL) - return 1; - if (sk_X509_num(chain) <= 0) - return 0; - if (!allow_inheritance && X509v3_asid_inherits(ext)) - return 0; - return asid_validate_path_internal(NULL, chain, ext); -} -LCRYPTO_ALIAS(X509v3_asid_validate_resource_set); - -#endif /* OPENSSL_NO_RFC3779 */ diff --git a/src/lib/libcrypto/x509/x509_att.c b/src/lib/libcrypto/x509/x509_att.c deleted file mode 100644 index 4931cbbc17..0000000000 --- a/src/lib/libcrypto/x509/x509_att.c +++ /dev/null @@ -1,377 +0,0 @@ -/* $OpenBSD: x509_att.c,v 1.25 2024/08/31 10:46:40 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "x509_local.h" - -int -X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, int lastpos) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-2); - return (X509at_get_attr_by_OBJ(x, obj, lastpos)); -} - -int -X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, - const ASN1_OBJECT *obj, int lastpos) -{ - int n; - X509_ATTRIBUTE *ex; - - if (sk == NULL) - return (-1); - lastpos++; - if (lastpos < 0) - lastpos = 0; - n = sk_X509_ATTRIBUTE_num(sk); - for (; lastpos < n; lastpos++) { - ex = sk_X509_ATTRIBUTE_value(sk, lastpos); - if (OBJ_cmp(ex->object, obj) == 0) - return (lastpos); - } - return (-1); -} - -STACK_OF(X509_ATTRIBUTE) * -X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr) -{ - X509_ATTRIBUTE *new_attr = NULL; - STACK_OF(X509_ATTRIBUTE) *sk = NULL; - - if (x == NULL) { - X509error(ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - - if (*x == NULL) { - if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) - goto err; - } else - sk = *x; - - if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) - goto err2; - if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) - goto err; - if (*x == NULL) - *x = sk; - return (sk); - -err: - X509error(ERR_R_MALLOC_FAILURE); -err2: - if (new_attr != NULL) - X509_ATTRIBUTE_free(new_attr); - if (sk != NULL && sk != *x) - sk_X509_ATTRIBUTE_free(sk); - return (NULL); -} - -STACK_OF(X509_ATTRIBUTE) * -X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj, - int type, const unsigned char *bytes, int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - - attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -STACK_OF(X509_ATTRIBUTE) * -X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, int nid, int type, - const unsigned char *bytes, int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - - attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -STACK_OF(X509_ATTRIBUTE) * -X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, const char *attrname, - int type, const unsigned char *bytes, int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - - attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -void * -X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, const ASN1_OBJECT *obj, - int lastpos, int type) -{ - int i; - X509_ATTRIBUTE *at; - - i = X509at_get_attr_by_OBJ(x, obj, lastpos); - if (i == -1) - return NULL; - if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) - return NULL; - at = sk_X509_ATTRIBUTE_value(x, i); - if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) - return NULL; - return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); -} - -X509_ATTRIBUTE * -X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype, - const void *data, int len) -{ - ASN1_OBJECT *obj; - X509_ATTRIBUTE *ret; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - X509error(X509_R_UNKNOWN_NID); - return (NULL); - } - ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); - if (ret == NULL) - ASN1_OBJECT_free(obj); - return (ret); -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_NID); - -X509_ATTRIBUTE * -X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj, - int atrtype, const void *data, int len) -{ - X509_ATTRIBUTE *ret; - - if ((attr == NULL) || (*attr == NULL)) { - if ((ret = X509_ATTRIBUTE_new()) == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - return (NULL); - } - } else - ret= *attr; - - if (!X509_ATTRIBUTE_set1_object(ret, obj)) - goto err; - if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) - goto err; - - if ((attr != NULL) && (*attr == NULL)) - *attr = ret; - return (ret); - -err: - if ((attr == NULL) || (ret != *attr)) - X509_ATTRIBUTE_free(ret); - return (NULL); -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_OBJ); - -X509_ATTRIBUTE * -X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const char *atrname, - int type, const unsigned char *bytes, int len) -{ - ASN1_OBJECT *obj; - X509_ATTRIBUTE *nattr; - - obj = OBJ_txt2obj(atrname, 0); - if (obj == NULL) { - X509error(X509_R_INVALID_FIELD_NAME); - ERR_asprintf_error_data("name=%s", atrname); - return (NULL); - } - nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nattr; -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_txt); - -int -X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) -{ - if ((attr == NULL) || (obj == NULL)) - return (0); - ASN1_OBJECT_free(attr->object); - attr->object = OBJ_dup(obj); - return attr->object != NULL; -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_object); - -int -X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, - int len) -{ - ASN1_TYPE *ttmp = NULL; - ASN1_STRING *stmp = NULL; - int atype = 0; - - if (!attr) - return 0; - if (attrtype & MBSTRING_FLAG) { - stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, - OBJ_obj2nid(attr->object)); - if (!stmp) { - X509error(ERR_R_ASN1_LIB); - return 0; - } - atype = stmp->type; - } else if (len != -1){ - if (!(stmp = ASN1_STRING_type_new(attrtype))) - goto err; - if (!ASN1_STRING_set(stmp, data, len)) - goto err; - atype = attrtype; - } - /* - * This is a bit naughty because the attribute should really have - * at least one value but some types use and zero length SET and - * require this. - */ - if (attrtype == 0) { - ASN1_STRING_free(stmp); - return 1; - } - - if (!(ttmp = ASN1_TYPE_new())) - goto err; - if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { - if (!ASN1_TYPE_set1(ttmp, attrtype, data)) - goto err; - } else - ASN1_TYPE_set(ttmp, atype, stmp); - if (!sk_ASN1_TYPE_push(attr->set, ttmp)) - goto err; - return 1; - -err: - ASN1_TYPE_free(ttmp); - ASN1_STRING_free(stmp); - X509error(ERR_R_MALLOC_FAILURE); - return 0; -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_data); - -int -X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) -{ - if (attr == NULL) - return 0; - - return sk_ASN1_TYPE_num(attr->set); -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_count); - -ASN1_OBJECT * -X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) -{ - if (attr == NULL) - return (NULL); - return (attr->object); -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_object); - -void * -X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data) -{ - ASN1_TYPE *ttmp; - - ttmp = X509_ATTRIBUTE_get0_type(attr, idx); - if (!ttmp) - return NULL; - if (atrtype != ASN1_TYPE_get(ttmp)){ - X509error(X509_R_WRONG_TYPE); - return NULL; - } - return ttmp->value.ptr; -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_data); - -ASN1_TYPE * -X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) -{ - if (attr == NULL) - return (NULL); - - return sk_ASN1_TYPE_value(attr->set, idx); -} -LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_type); diff --git a/src/lib/libcrypto/x509/x509_bcons.c b/src/lib/libcrypto/x509/x509_bcons.c deleted file mode 100644 index 99cb5afe9a..0000000000 --- a/src/lib/libcrypto/x509/x509_bcons.c +++ /dev/null @@ -1,212 +0,0 @@ -/* $OpenBSD: x509_bcons.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "x509_local.h" - -static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist); -static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); - -static const X509V3_EXT_METHOD x509v3_ext_basic_constraints = { - .ext_nid = NID_basic_constraints, - .ext_flags = 0, - .it = &BASIC_CONSTRAINTS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS, - .v2i = (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_basic_constraints(void) -{ - return &x509v3_ext_basic_constraints; -} - -static const ASN1_TEMPLATE BASIC_CONSTRAINTS_seq_tt[] = { - { - .flags = ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(BASIC_CONSTRAINTS, ca), - .field_name = "ca", - .item = &ASN1_FBOOLEAN_it, - }, - { - .flags = ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(BASIC_CONSTRAINTS, pathlen), - .field_name = "pathlen", - .item = &ASN1_INTEGER_it, - }, -}; - -const ASN1_ITEM BASIC_CONSTRAINTS_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = BASIC_CONSTRAINTS_seq_tt, - .tcount = sizeof(BASIC_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(BASIC_CONSTRAINTS), - .sname = "BASIC_CONSTRAINTS", -}; -LCRYPTO_ALIAS(BASIC_CONSTRAINTS_it); - - -BASIC_CONSTRAINTS * -d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len) -{ - return (BASIC_CONSTRAINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &BASIC_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(d2i_BASIC_CONSTRAINTS); - -int -i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &BASIC_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(i2d_BASIC_CONSTRAINTS); - -BASIC_CONSTRAINTS * -BASIC_CONSTRAINTS_new(void) -{ - return (BASIC_CONSTRAINTS *)ASN1_item_new(&BASIC_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(BASIC_CONSTRAINTS_new); - -void -BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &BASIC_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(BASIC_CONSTRAINTS_free); - - -static STACK_OF(CONF_VALUE) * -i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, - STACK_OF(CONF_VALUE) *extlist) -{ - STACK_OF(CONF_VALUE) *free_extlist = NULL; - - if (extlist == NULL) { - if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - if (!X509V3_add_value_bool("CA", bcons->ca, &extlist)) - goto err; - if (!X509V3_add_value_int("pathlen", bcons->pathlen, &extlist)) - goto err; - - return extlist; - - err: - sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); - - return NULL; -} - -static BASIC_CONSTRAINTS * -v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - BASIC_CONSTRAINTS *bcons = NULL; - CONF_VALUE *val; - int i; - - if (!(bcons = BASIC_CONSTRAINTS_new())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - val = sk_CONF_VALUE_value(values, i); - if (!strcmp(val->name, "CA")) { - if (!X509V3_get_value_bool(val, &bcons->ca)) - goto err; - } else if (!strcmp(val->name, "pathlen")) { - if (!X509V3_get_value_int(val, &bcons->pathlen)) - goto err; - } else { - X509V3error(X509V3_R_INVALID_NAME); - X509V3_conf_err(val); - goto err; - } - } - return bcons; - -err: - BASIC_CONSTRAINTS_free(bcons); - return NULL; -} diff --git a/src/lib/libcrypto/x509/x509_bitst.c b/src/lib/libcrypto/x509/x509_bitst.c deleted file mode 100644 index 2bc4f9911a..0000000000 --- a/src/lib/libcrypto/x509/x509_bitst.c +++ /dev/null @@ -1,240 +0,0 @@ -/* $OpenBSD: x509_bitst.c,v 1.8 2024/08/31 10:23:13 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include - -#include "x509_local.h" - -static const BIT_STRING_BITNAME ns_cert_type_table[] = { - {0, "SSL Client", "client"}, - {1, "SSL Server", "server"}, - {2, "S/MIME", "email"}, - {3, "Object Signing", "objsign"}, - {4, "Unused", "reserved"}, - {5, "SSL CA", "sslCA"}, - {6, "S/MIME CA", "emailCA"}, - {7, "Object Signing CA", "objCA"}, - {-1, NULL, NULL} -}; - -static const BIT_STRING_BITNAME key_usage_type_table[] = { - {0, "Digital Signature", "digitalSignature"}, - {1, "Non Repudiation", "nonRepudiation"}, - {2, "Key Encipherment", "keyEncipherment"}, - {3, "Data Encipherment", "dataEncipherment"}, - {4, "Key Agreement", "keyAgreement"}, - {5, "Certificate Sign", "keyCertSign"}, - {6, "CRL Sign", "cRLSign"}, - {7, "Encipher Only", "encipherOnly"}, - {8, "Decipher Only", "decipherOnly"}, - {-1, NULL, NULL} -}; - -static const BIT_STRING_BITNAME crl_reasons[] = { - {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, - {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, - {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, - {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"}, - {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, - {CRL_REASON_CESSATION_OF_OPERATION, "Cessation Of Operation", "cessationOfOperation"}, - {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, - {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, - {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"}, - {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, - {-1, NULL, NULL} -}; - -static const X509V3_EXT_METHOD x509v3_ext_netscape_cert_type = { - .ext_nid = NID_netscape_cert_type, - .ext_flags = 0, - .it = &ASN1_BIT_STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, - .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, - .i2r = NULL, - .r2i = NULL, - .usr_data = ns_cert_type_table, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_cert_type(void) -{ - return &x509v3_ext_netscape_cert_type; -} - -static const X509V3_EXT_METHOD x509v3_ext_key_usage = { - .ext_nid = NID_key_usage, - .ext_flags = 0, - .it = &ASN1_BIT_STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, - .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, - .i2r = NULL, - .r2i = NULL, - .usr_data = key_usage_type_table, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_key_usage(void) -{ - return &x509v3_ext_key_usage; -} - -static const X509V3_EXT_METHOD x509v3_ext_crl_reason = { - .ext_nid = NID_crl_reason, - .ext_flags = 0, - .it = &ASN1_ENUMERATED_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = crl_reasons, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_crl_reason(void) -{ - return &x509v3_ext_crl_reason; -} - -STACK_OF(CONF_VALUE) * -i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits, - STACK_OF(CONF_VALUE) *ret) -{ - const BIT_STRING_BITNAME *bnam; - STACK_OF(CONF_VALUE) *free_ret = NULL; - - if (ret == NULL) { - if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - for (bnam = method->usr_data; bnam->lname != NULL; bnam++) { - if (!ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) - continue; - if (!X509V3_add_value(bnam->lname, NULL, &ret)) - goto err; - } - - return ret; - - err: - sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); - - return NULL; -} -LCRYPTO_ALIAS(i2v_ASN1_BIT_STRING); - -ASN1_BIT_STRING * -v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - CONF_VALUE *val; - ASN1_BIT_STRING *bs; - int i; - const BIT_STRING_BITNAME *bnam; - - if (!(bs = ASN1_BIT_STRING_new())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - for (bnam = method->usr_data; bnam->lname; bnam++) { - if (!strcmp(bnam->sname, val->name) || - !strcmp(bnam->lname, val->name) ) { - if (!ASN1_BIT_STRING_set_bit(bs, - bnam->bitnum, 1)) { - X509V3error(ERR_R_MALLOC_FAILURE); - ASN1_BIT_STRING_free(bs); - return NULL; - } - break; - } - } - if (!bnam->lname) { - X509V3error(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); - X509V3_conf_err(val); - ASN1_BIT_STRING_free(bs); - return NULL; - } - } - return bs; -} -LCRYPTO_ALIAS(v2i_ASN1_BIT_STRING); diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c deleted file mode 100644 index 2c1e427093..0000000000 --- a/src/lib/libcrypto/x509/x509_cmp.c +++ /dev/null @@ -1,429 +0,0 @@ -/* $OpenBSD: x509_cmp.c,v 1.44 2024/03/25 03:41:16 joshua Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include "evp_local.h" -#include "x509_local.h" - -int -X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) -{ - int i; - X509_CINF *ai, *bi; - - ai = a->cert_info; - bi = b->cert_info; - i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); - if (i) - return (i); - return (X509_NAME_cmp(ai->issuer, bi->issuer)); -} -LCRYPTO_ALIAS(X509_issuer_and_serial_cmp); - -#ifndef OPENSSL_NO_MD5 -unsigned long -X509_issuer_and_serial_hash(X509 *a) -{ - unsigned long ret = 0; - EVP_MD_CTX *md_ctx; - unsigned char md[16]; - char *f = NULL; - - if ((md_ctx = EVP_MD_CTX_new()) == NULL) - goto err; - - if ((f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0)) == NULL) - goto err; - if (!EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL)) - goto err; - if (!EVP_DigestUpdate(md_ctx, (unsigned char *)f, strlen(f))) - goto err; - if (!EVP_DigestUpdate(md_ctx, - (unsigned char *)a->cert_info->serialNumber->data, - (unsigned long)a->cert_info->serialNumber->length)) - goto err; - if (!EVP_DigestFinal_ex(md_ctx, &(md[0]), NULL)) - goto err; - - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & - 0xffffffffL; - -err: - EVP_MD_CTX_free(md_ctx); - free(f); - - return ret; -} -LCRYPTO_ALIAS(X509_issuer_and_serial_hash); -#endif - -int -X509_issuer_name_cmp(const X509 *a, const X509 *b) -{ - return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); -} -LCRYPTO_ALIAS(X509_issuer_name_cmp); - -int -X509_subject_name_cmp(const X509 *a, const X509 *b) -{ - return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); -} -LCRYPTO_ALIAS(X509_subject_name_cmp); - -int -X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) -{ - return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); -} -LCRYPTO_ALIAS(X509_CRL_cmp); - -#ifndef OPENSSL_NO_SHA -int -X509_CRL_match(const X509_CRL *a, const X509_CRL *b) -{ - return memcmp(a->hash, b->hash, X509_CRL_HASH_LEN); -} -LCRYPTO_ALIAS(X509_CRL_match); -#endif - -X509_NAME * -X509_get_issuer_name(const X509 *a) -{ - return (a->cert_info->issuer); -} -LCRYPTO_ALIAS(X509_get_issuer_name); - -unsigned long -X509_issuer_name_hash(X509 *x) -{ - return (X509_NAME_hash(x->cert_info->issuer)); -} -LCRYPTO_ALIAS(X509_issuer_name_hash); - -#ifndef OPENSSL_NO_MD5 -unsigned long -X509_issuer_name_hash_old(X509 *x) -{ - return (X509_NAME_hash_old(x->cert_info->issuer)); -} -LCRYPTO_ALIAS(X509_issuer_name_hash_old); -#endif - -X509_NAME * -X509_get_subject_name(const X509 *a) -{ - return (a->cert_info->subject); -} -LCRYPTO_ALIAS(X509_get_subject_name); - -ASN1_INTEGER * -X509_get_serialNumber(X509 *a) -{ - return (a->cert_info->serialNumber); -} -LCRYPTO_ALIAS(X509_get_serialNumber); - -const ASN1_INTEGER * -X509_get0_serialNumber(const X509 *a) -{ - return (a->cert_info->serialNumber); -} -LCRYPTO_ALIAS(X509_get0_serialNumber); - -unsigned long -X509_subject_name_hash(X509 *x) -{ - return (X509_NAME_hash(x->cert_info->subject)); -} -LCRYPTO_ALIAS(X509_subject_name_hash); - -#ifndef OPENSSL_NO_MD5 -unsigned long -X509_subject_name_hash_old(X509 *x) -{ - return (X509_NAME_hash_old(x->cert_info->subject)); -} -LCRYPTO_ALIAS(X509_subject_name_hash_old); -#endif - -#ifndef OPENSSL_NO_SHA -/* Compare two certificates: they must be identical for - * this to work. NB: Although "cmp" operations are generally - * prototyped to take "const" arguments (eg. for use in - * STACKs), the way X509 handling is - these operations may - * involve ensuring the hashes are up-to-date and ensuring - * certain cert information is cached. So this is the point - * where the "depth-first" constification tree has to halt - * with an evil cast. - */ -int -X509_cmp(const X509 *a, const X509 *b) -{ - /* ensure hash is valid */ - X509_check_purpose((X509 *)a, -1, 0); - X509_check_purpose((X509 *)b, -1, 0); - - return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN); -} -LCRYPTO_ALIAS(X509_cmp); -#endif - -int -X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) -{ - int ret; - - /* Ensure canonical encoding is present and up to date */ - if (!a->canon_enc || a->modified) { - ret = i2d_X509_NAME((X509_NAME *)a, NULL); - if (ret < 0) - return -2; - } - if (!b->canon_enc || b->modified) { - ret = i2d_X509_NAME((X509_NAME *)b, NULL); - if (ret < 0) - return -2; - } - ret = a->canon_enclen - b->canon_enclen; - if (ret) - return ret; - return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); -} -LCRYPTO_ALIAS(X509_NAME_cmp); - -unsigned long -X509_NAME_hash(X509_NAME *x) -{ - unsigned long ret = 0; - unsigned char md[SHA_DIGEST_LENGTH]; - - /* Make sure X509_NAME structure contains valid cached encoding */ - i2d_X509_NAME(x, NULL); - if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), - NULL)) - return 0; - - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & - 0xffffffffL; - return (ret); -} -LCRYPTO_ALIAS(X509_NAME_hash); - - -#ifndef OPENSSL_NO_MD5 -/* I now DER encode the name and hash it. Since I cache the DER encoding, - * this is reasonably efficient. */ - -unsigned long -X509_NAME_hash_old(X509_NAME *x) -{ - EVP_MD_CTX *md_ctx; - unsigned long ret = 0; - unsigned char md[16]; - - if ((md_ctx = EVP_MD_CTX_new()) == NULL) - return ret; - - /* Make sure X509_NAME structure contains valid cached encoding */ - i2d_X509_NAME(x, NULL); - if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) && - EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length) && - EVP_DigestFinal_ex(md_ctx, md, NULL)) - ret = (((unsigned long)md[0]) | - ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | - ((unsigned long)md[3] << 24L)) & - 0xffffffffL; - - EVP_MD_CTX_free(md_ctx); - - return ret; -} -LCRYPTO_ALIAS(X509_NAME_hash_old); -#endif - -/* Search a stack of X509 for a match */ -X509 * -X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, - ASN1_INTEGER *serial) -{ - int i; - X509_CINF cinf; - X509 x, *x509 = NULL; - - if (!sk) - return NULL; - - x.cert_info = &cinf; - cinf.serialNumber = serial; - cinf.issuer = name; - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - if (X509_issuer_and_serial_cmp(x509, &x) == 0) - return (x509); - } - return (NULL); -} -LCRYPTO_ALIAS(X509_find_by_issuer_and_serial); - -X509 * -X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) -{ - X509 *x509; - int i; - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) - return (x509); - } - return (NULL); -} -LCRYPTO_ALIAS(X509_find_by_subject); - -EVP_PKEY * -X509_get_pubkey(X509 *x) -{ - if (x == NULL || x->cert_info == NULL) - return (NULL); - return (X509_PUBKEY_get(x->cert_info->key)); -} -LCRYPTO_ALIAS(X509_get_pubkey); - -EVP_PKEY * -X509_get0_pubkey(const X509 *x) -{ - if (x == NULL || x->cert_info == NULL) - return (NULL); - return (X509_PUBKEY_get0(x->cert_info->key)); -} -LCRYPTO_ALIAS(X509_get0_pubkey); - -ASN1_BIT_STRING * -X509_get0_pubkey_bitstr(const X509 *x) -{ - if (!x) - return NULL; - return x->cert_info->key->public_key; -} -LCRYPTO_ALIAS(X509_get0_pubkey_bitstr); - -int -X509_check_private_key(const X509 *x, const EVP_PKEY *k) -{ - const EVP_PKEY *xk; - int ret; - - xk = X509_get0_pubkey(x); - - if (xk) - ret = EVP_PKEY_cmp(xk, k); - else - ret = -2; - - switch (ret) { - case 1: - break; - case 0: - X509error(X509_R_KEY_VALUES_MISMATCH); - break; - case -1: - X509error(X509_R_KEY_TYPE_MISMATCH); - break; - case -2: - X509error(X509_R_UNKNOWN_KEY_TYPE); - } - if (ret > 0) - return 1; - return 0; -} -LCRYPTO_ALIAS(X509_check_private_key); - -/* - * Not strictly speaking an "up_ref" as a STACK doesn't have a reference - * count but it has the same effect by duping the STACK and upping the ref of - * each X509 structure. - */ -STACK_OF(X509) * -X509_chain_up_ref(STACK_OF(X509) *chain) -{ - STACK_OF(X509) *ret; - size_t i; - - ret = sk_X509_dup(chain); - for (i = 0; i < sk_X509_num(ret); i++) - X509_up_ref(sk_X509_value(ret, i)); - - return ret; -} -LCRYPTO_ALIAS(X509_chain_up_ref); diff --git a/src/lib/libcrypto/x509/x509_conf.c b/src/lib/libcrypto/x509/x509_conf.c deleted file mode 100644 index e5b18c2f77..0000000000 --- a/src/lib/libcrypto/x509/x509_conf.c +++ /dev/null @@ -1,456 +0,0 @@ -/* $OpenBSD: x509_conf.c,v 1.29 2025/03/06 07:20:01 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* extension creation utilities */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "conf_local.h" -#include "x509_local.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 nid, - int crit, const char *value); -static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, - int crit, int type, X509V3_CTX *ctx); -static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int nid, - int crit, void *ext_struct); -static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, - long *ext_len); - -X509_EXTENSION * -X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, - const char *value) -{ - int crit; - int ext_type; - X509_EXTENSION *ret; - - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) - return v3_generic_extension(name, value, crit, ext_type, ctx); - ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); - if (!ret) { - X509V3error(X509V3_R_ERROR_IN_EXTENSION); - ERR_asprintf_error_data("name=%s, value=%s", name, value); - } - return ret; -} -LCRYPTO_ALIAS(X509V3_EXT_nconf); - -X509_EXTENSION * -X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int nid, const char *value) -{ - int crit; - int ext_type; - - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) - return v3_generic_extension(OBJ_nid2sn(nid), - value, crit, ext_type, ctx); - return do_ext_nconf(conf, ctx, nid, crit, value); -} -LCRYPTO_ALIAS(X509V3_EXT_nconf_nid); - -static X509_EXTENSION * -do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int nid, int crit, const char *value) -{ - const X509V3_EXT_METHOD *method; - X509_EXTENSION *ext; - void *ext_struct; - - if (nid == NID_undef) { - X509V3error(X509V3_R_UNKNOWN_EXTENSION_NAME); - return NULL; - } - if (!(method = X509V3_EXT_get_nid(nid))) { - X509V3error(X509V3_R_UNKNOWN_EXTENSION); - return NULL; - } - /* Now get internal extension representation based on type */ - if (method->v2i) { - STACK_OF(CONF_VALUE) *nval; - - if (*value == '@') - nval = NCONF_get_section(conf, value + 1); - else - nval = X509V3_parse_list(value); - if (sk_CONF_VALUE_num(nval) <= 0) { - X509V3error(X509V3_R_INVALID_EXTENSION_STRING); - ERR_asprintf_error_data("name=%s,section=%s", - OBJ_nid2sn(nid), value); - if (*value != '@') - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - return NULL; - } - ext_struct = method->v2i(method, ctx, nval); - if (*value != '@') - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - } else if (method->s2i) { - ext_struct = method->s2i(method, ctx, value); - } else if (method->r2i) { - if (ctx->db == NULL) { - X509V3error(X509V3_R_NO_CONFIG_DATABASE); - return NULL; - } - ext_struct = method->r2i(method, ctx, value); - } else { - X509V3error(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); - ERR_asprintf_error_data("name=%s", OBJ_nid2sn(nid)); - return NULL; - } - if (ext_struct == NULL) - return NULL; - - ext = do_ext_i2d(method, nid, crit, ext_struct); - if (method->it) - ASN1_item_free(ext_struct, method->it); - else - method->ext_free(ext_struct); - return ext; -} - -static X509_EXTENSION * -do_ext_i2d(const X509V3_EXT_METHOD *method, int nid, int crit, - void *ext_struct) -{ - unsigned char *ext_der = NULL; - int ext_len; - ASN1_OCTET_STRING *ext_oct = NULL; - X509_EXTENSION *ext; - - /* Convert internal representation to DER */ - if (method->it != NULL) { - ext_der = NULL; - ext_len = ASN1_item_i2d(ext_struct, &ext_der, method->it); - if (ext_len < 0) - goto err; - } else { - unsigned char *p; - - if ((ext_len = method->i2d(ext_struct, NULL)) <= 0) - goto err; - if ((ext_der = calloc(1, ext_len)) == NULL) - goto err; - p = ext_der; - if (method->i2d(ext_struct, &p) != ext_len) - goto err; - } - if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) - goto err; - ASN1_STRING_set0(ext_oct, ext_der, ext_len); - ext_der = NULL; - ext_len = 0; - - ext = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_oct); - if (ext == NULL) - goto err; - ASN1_OCTET_STRING_free(ext_oct); - - return ext; - - err: - free(ext_der); - ASN1_OCTET_STRING_free(ext_oct); - X509V3error(ERR_R_MALLOC_FAILURE); - - return NULL; -} - -/* Given an internal structure, nid and critical flag create an extension */ -X509_EXTENSION * -X509V3_EXT_i2d(int nid, int crit, void *ext_struct) -{ - const X509V3_EXT_METHOD *method; - - if (!(method = X509V3_EXT_get_nid(nid))) { - X509V3error(X509V3_R_UNKNOWN_EXTENSION); - return NULL; - } - return do_ext_i2d(method, nid, crit, ext_struct); -} -LCRYPTO_ALIAS(X509V3_EXT_i2d); - -/* Check the extension string for critical flag */ -static int -v3_check_critical(const char **value) -{ - const char *p = *value; - - if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) - return 0; - p += 9; - while (isspace((unsigned char)*p)) p++; - *value = p; - return 1; -} - -/* Check extension string for generic extension and return the type */ -static int -v3_check_generic(const char **value) -{ - int gen_type = 0; - const char *p = *value; - - if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { - p += 4; - gen_type = 1; - } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { - p += 5; - gen_type = 2; - } else - return 0; - - while (isspace((unsigned char)*p)) - p++; - *value = p; - return gen_type; -} - -/* Create a generic extension: for now just handle DER type */ -static X509_EXTENSION * -v3_generic_extension(const char *name, const char *value, int crit, int gen_type, - X509V3_CTX *ctx) -{ - unsigned char *ext_der = NULL; - long ext_len = 0; - ASN1_OBJECT *obj = NULL; - ASN1_OCTET_STRING *oct = NULL; - X509_EXTENSION *ext = NULL; - - if ((obj = OBJ_txt2obj(name, 0)) == NULL) { - X509V3error(X509V3_R_EXTENSION_NAME_ERROR); - ERR_asprintf_error_data("name=%s", name); - goto err; - } - - if (gen_type == 1) - ext_der = string_to_hex(value, &ext_len); - else if (gen_type == 2) - ext_der = generic_asn1(value, ctx, &ext_len); - else { - ERR_asprintf_error_data("Unexpected generic extension type %d", gen_type); - goto err; - } - - if (ext_der == NULL) { - X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); - ERR_asprintf_error_data("value=%s", value); - goto err; - } - - if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - - ASN1_STRING_set0(oct, ext_der, ext_len); - ext_der = NULL; - ext_len = 0; - - ext = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); - - err: - ASN1_OBJECT_free(obj); - ASN1_OCTET_STRING_free(oct); - free(ext_der); - - return ext; -} - -static unsigned char * -generic_asn1(const char *value, X509V3_CTX *ctx, long *ext_len) -{ - ASN1_TYPE *typ; - unsigned char *ext_der = NULL; - - typ = ASN1_generate_v3(value, ctx); - if (typ == NULL) - return NULL; - *ext_len = i2d_ASN1_TYPE(typ, &ext_der); - ASN1_TYPE_free(typ); - return ext_der; -} - -/* - * This is the main function: add a bunch of extensions based on a config file - * section to an extension STACK. - */ - -int -X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, - STACK_OF(X509_EXTENSION) **sk) -{ - X509_EXTENSION *ext; - STACK_OF(CONF_VALUE) *nval; - CONF_VALUE *val; - int i; - - if (!(nval = NCONF_get_section(conf, section))) - return 0; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) - return 0; - if (sk) - X509v3_add_ext(sk, ext, -1); - X509_EXTENSION_free(ext); - } - return 1; -} -LCRYPTO_ALIAS(X509V3_EXT_add_nconf_sk); - -int -X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509 *cert) -{ - STACK_OF(X509_EXTENSION) **sk = NULL; - - if (cert) - sk = &cert->cert_info->extensions; - return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -} -LCRYPTO_ALIAS(X509V3_EXT_add_nconf); - -int -X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_CRL *crl) -{ - STACK_OF(X509_EXTENSION) **sk = NULL; - - if (crl) - sk = &crl->crl->extensions; - return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -} -LCRYPTO_ALIAS(X509V3_EXT_CRL_add_nconf); - -int -X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_REQ *req) -{ - STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; - int i; - - if (req) - sk = &extlist; - i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); - if (!i || !sk) - return i; - i = X509_REQ_add_extensions(req, extlist); - sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); - return i; -} -LCRYPTO_ALIAS(X509V3_EXT_REQ_add_nconf); - -STACK_OF(CONF_VALUE) * -X509V3_get0_section(X509V3_CTX *ctx, const char *section) -{ - if (ctx->db == NULL) { - X509V3error(X509V3_R_OPERATION_NOT_DEFINED); - return NULL; - } - return NCONF_get_section(ctx->db, section); -} - -void -X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) -{ - ctx->db = conf; -} -LCRYPTO_ALIAS(X509V3_set_nconf); - -void -X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, - X509_CRL *crl, int flags) -{ - ctx->issuer_cert = issuer; - ctx->subject_cert = subj; - ctx->crl = crl; - ctx->subject_req = req; - ctx->flags = flags; -} -LCRYPTO_ALIAS(X509V3_set_ctx); - -X509_EXTENSION * -X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *name, - const char *value) -{ - CONF ctmp; - - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_nconf(&ctmp, ctx, name, value); -} -LCRYPTO_ALIAS(X509V3_EXT_conf); - -X509_EXTENSION * -X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int nid, - const char *value) -{ - CONF ctmp; - - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_nconf_nid(&ctmp, ctx, nid, value); -} -LCRYPTO_ALIAS(X509V3_EXT_conf_nid); diff --git a/src/lib/libcrypto/x509/x509_constraints.c b/src/lib/libcrypto/x509/x509_constraints.c deleted file mode 100644 index 0773d2ba71..0000000000 --- a/src/lib/libcrypto/x509/x509_constraints.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* $OpenBSD: x509_constraints.c,v 1.32 2023/09/29 15:53:59 beck Exp $ */ -/* - * Copyright (c) 2020 Bob Beck - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "bytestring.h" -#include "x509_internal.h" - -/* RFC 2821 section 4.5.3.1 */ -#define LOCAL_PART_MAX_LEN (size_t)64 -#define DOMAIN_PART_MAX_LEN (size_t)255 -#define MAX_IP_ADDRESS_LENGTH (size_t)46 - -static int -cbs_is_ip_address(CBS *cbs, int *is_ip) -{ - struct sockaddr_in6 sin6; - struct sockaddr_in sin4; - char *name = NULL; - - *is_ip = 0; - if (CBS_len(cbs) > MAX_IP_ADDRESS_LENGTH) - return 1; - if (!CBS_strdup(cbs, &name)) - return 0; - if (inet_pton(AF_INET, name, &sin4) == 1 || - inet_pton(AF_INET6, name, &sin6) == 1) - *is_ip = 1; - - free(name); - return 1; -} - -struct x509_constraints_name * -x509_constraints_name_new(void) -{ - return (calloc(1, sizeof(struct x509_constraints_name))); -} - -void -x509_constraints_name_clear(struct x509_constraints_name *name) -{ - free(name->name); - free(name->local); - free(name->der); - memset(name, 0, sizeof(*name)); -} - -void -x509_constraints_name_free(struct x509_constraints_name *name) -{ - if (name == NULL) - return; - x509_constraints_name_clear(name); - free(name); -} - -struct x509_constraints_name * -x509_constraints_name_dup(struct x509_constraints_name *name) -{ - struct x509_constraints_name *new; - - if ((new = x509_constraints_name_new()) == NULL) - goto err; - new->type = name->type; - new->af = name->af; - new->der_len = 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) - goto err; - memcpy(new->address, name->address, sizeof(name->address)); - return new; - err: - x509_constraints_name_free(new); - return NULL; -} - -struct x509_constraints_names * -x509_constraints_names_new(size_t names_max) -{ - 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 -x509_constraints_names_clear(struct x509_constraints_names *names) -{ - size_t i; - - for (i = 0; i < names->names_count; i++) - x509_constraints_name_free(names->names[i]); - free(names->names); - memset(names, 0, sizeof(*names)); -} - -void -x509_constraints_names_free(struct x509_constraints_names *names) -{ - if (names == NULL) - return; - - x509_constraints_names_clear(names); - free(names); -} - -int -x509_constraints_names_add(struct x509_constraints_names *names, - struct x509_constraints_name *name) -{ - 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, - names->names_len + 32, sizeof(*tmp))) == NULL) - return 0; - names->names_len += 32; - names->names = tmp; - } - names->names[names->names_count] = name; - names->names_count++; - return 1; -} - -struct x509_constraints_names * -x509_constraints_names_dup(struct x509_constraints_names *names) -{ - struct x509_constraints_names *new = NULL; - struct x509_constraints_name *name = NULL; - size_t i; - - if (names == NULL) - return 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); - x509_constraints_name_free(name); - return NULL; -} - -/* - * 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 subdomain based - * constraint, as well as allowing for '_' which is commonly accepted - * by nonconformant DNS implementations. - * - * if "wildcards" is set it allows '*' to occur in the string at the end of a - * component. - */ -static int -x509_constraints_valid_domain_internal(CBS *cbs, int wildcards) -{ - int first, component = 0; - uint8_t prev, c = 0; - size_t i, len; - CBS copy; - - CBS_dup(cbs, ©); - - len = CBS_len(cbs); - - if (len > DOMAIN_PART_MAX_LEN) - return 0; - for (i = 0; i < len; i++) { - prev = c; - if (!CBS_get_u8(©, &c)) - return 0; - - first = (i == 0); - - /* Everything has to be ASCII, with no NUL byte */ - if (!isascii(c) || c == '\0') - return 0; - /* It must be alphanumeric, a '-', '.', '_' or '*' */ - if (!isalnum(c) && c != '-' && c != '.' && c != '_' && c != '*') - return 0; - - /* if it is a '*', fail if not wildcards */ - if (!wildcards && c == '*') - return 0; - - /* '-' must not start a component or be at the end. */ - if (c == '-' && (component == 0 || i == len - 1)) - return 0; - - /* - * '.' must not be at the end. It may be first overall - * but must not otherwise start a component. - */ - if (c == '.' && ((component == 0 && !first) || i == len - 1)) - return 0; - - if (c == '.') { - /* Components can not end with a dash. */ - if (prev == '-') - return 0; - /* Start new component */ - 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; - } - - return 1; -} - -int -x509_constraints_valid_host(CBS *cbs, int permit_ip) -{ - uint8_t first; - int is_ip; - - if (!CBS_peek_u8(cbs, &first)) - return 0; - if (first == '.') - return 0; /* leading . not allowed in a host name or IP */ - if (!permit_ip) { - if (!cbs_is_ip_address(cbs, &is_ip)) - return 0; - if (is_ip) - return 0; - } - - return x509_constraints_valid_domain_internal(cbs, 0); -} - -int -x509_constraints_valid_sandns(CBS *cbs) -{ - uint8_t first; - - if (!CBS_peek_u8(cbs, &first)) - return 0; - if (first == '.') - return 0; /* leading . not allowed in a SAN DNS name */ - /* - * A domain may not be less than two characters, so you - * can't wildcard a single domain of less than that - */ - if (CBS_len(cbs) < 4 && first == '*') - return 0; - - return x509_constraints_valid_domain_internal(cbs, 1); -} - -static inline int -local_part_ok(char c) -{ - return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || c == '!' || c == '#' || c == '$' || - c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' || - c == '-' || c == '/' || c == '=' || c == '?' || c == '^' || - c == '_' || c == '`' || c == '{' || c == '|' || c == '}' || - c == '~' || c == '.'); -} - -/* - * Parse "candidate" as an RFC 2821 mailbox. - * Returns 0 if candidate is not a valid mailbox or if an error occurs. - * Returns 1 if candidate is a mailbox and adds newly allocated - * local and domain parts of the mailbox to "name->local" and name->name" - */ -int -x509_constraints_parse_mailbox(CBS *candidate, - struct x509_constraints_name *name) -{ - char working[DOMAIN_PART_MAX_LEN + 1] = { 0 }; - char *candidate_local = NULL; - char *candidate_domain = NULL; - CBS domain_cbs; - size_t i, len, wi = 0; - int accept = 0; - int quoted = 0; - CBS copy; - - /* XXX This should not be necessary - revisit and remove */ - if (candidate == NULL) - return 0; - - CBS_dup(candidate, ©); - - if ((len = CBS_len(©)) == 0) - return 0; - - /* It can't be bigger than the local part, domain part and the '@' */ - if (len > LOCAL_PART_MAX_LEN + DOMAIN_PART_MAX_LEN + 1) - return 0; - - for (i = 0; i < len; i++) { - char c; - if (!CBS_get_u8(©, &c)) - goto bad; - /* non ascii, cr, lf, or nul is never allowed */ - if (!isascii(c) || c == '\r' || c == '\n' || c == '\0') - goto bad; - if (i == 0) { - /* local part is quoted part */ - if (c == '"') - quoted = 1; - /* can not start with a . */ - if (c == '.') - 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) - goto bad; - working[wi++] = c; - if (i == len - 1) { - if (wi == 0) - goto bad; - if (candidate_domain != NULL) - goto bad; - candidate_domain = strdup(working); - if (candidate_domain == NULL) - goto bad; - } - continue; - } - /* We are looking for the local part */ - if (wi >= LOCAL_PART_MAX_LEN) - break; - - if (quoted) { - if (c == '\\') { - accept = 1; - continue; - } - if (c == '"' && i != 0) { - uint8_t next; - /* end the quoted part. @ must be next */ - if (!CBS_peek_u8(©, &next)) - goto bad; - if (next != '@') - goto bad; - quoted = 0; - } - /* - * XXX Go strangely permits sp but forbids ht - * mimic that for now - */ - 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; - if (candidate_local != NULL) - goto bad; - candidate_local = strdup(working); - if (candidate_local == NULL) - goto bad; - memset(working, 0, sizeof(working)); - wi = 0; - continue; - } - if (c == '\\') { - uint8_t next; - /* - * RFC 2821 hints these can happen outside of - * quoted string. Don't include the \ but - * next character must be ok. - */ - if (!CBS_peek_u8(©, &next)) - goto bad; - if (!local_part_ok(next)) - goto bad; - accept = 1; - } - 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) - goto bad; - CBS_init(&domain_cbs, candidate_domain, strlen(candidate_domain)); - if (!x509_constraints_valid_host(&domain_cbs, 0)) - goto bad; - - 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); - free(candidate_domain); - return 0; -} - -int -x509_constraints_valid_domain_constraint(CBS *cbs) -{ - uint8_t first; - - if (CBS_len(cbs) == 0) - return 1; /* empty constraints match */ - - /* - * A domain may not be less than two characters, so you - * can't match a single domain of less than that - */ - if (CBS_len(cbs) < 3) { - if (!CBS_peek_u8(cbs, &first)) - return 0; - if (first == '.') - return 0; - } - return x509_constraints_valid_domain_internal(cbs, 0); -} - -/* - * Extract the host part of a URI. On failure to parse a valid host part of the - * URI, 0 is returned indicating an invalid URI. If the host part parses as - * valid, or is not present, 1 is returned indicating a possibly valid URI. - * - * In the case of a valid URI, *hostpart will be set to a copy of the host part - * of the URI, or the empty string if no URI is present. If memory allocation - * fails *hostpart will be set to NULL, even though we returned 1. It is the - * caller's responsibility to indicate an error for memory allocation failure, - * and the callers responsibility to free *hostpart. - * - * RFC 3986: - * the authority part of a uri starts with // and is terminated with - * the next '/', '?', '#' or end of the URI. - * - * The authority itself contains [userinfo '@'] host [: port] - * - * so the host starts at the start or after the '@', and ends - * with end of URI, '/', '?', "#', or ':'. - */ -int -x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostpart) -{ - size_t i, hostlen = 0; - uint8_t *authority = NULL; - char *host = NULL; - CBS host_cbs; - - /* - * Find first '//'. there must be at least a '//' and - * something else. - */ - if (len < 3) - return 0; - for (i = 0; i < len - 1; i++) { - if (!isascii(uri[i])) - return 0; - if (uri[i] == '/' && uri[i + 1] == '/') { - authority = uri + i + 2; - break; - } - } - if (authority == NULL) { - /* - * There is no authority, so no host part in this - * URI. This might be ok or might not, but it must - * fail if we run into a name constraint later, so - * we indicate that we have a URI with an empty - * host part, and succeed. - */ - if (hostpart != NULL) - *hostpart = strdup(""); - return 1; - } - for (i = authority - uri; i < len; i++) { - if (!isascii(uri[i])) - return 0; - /* it has a userinfo part */ - if (uri[i] == '@') { - hostlen = 0; - /* it can only have one */ - if (host != NULL) - break; - /* start after the userinfo part */ - host = uri + i + 1; - continue; - } - /* did we find the end? */ - if (uri[i] == ':' || uri[i] == '/' || uri[i] == '?' || - uri[i] == '#') - break; - hostlen++; - } - if (hostlen == 0) - return 0; - if (host == NULL) - host = authority; - CBS_init(&host_cbs, host, hostlen); - if (!x509_constraints_valid_host(&host_cbs, 1)) - return 0; - if (hostpart != NULL && !CBS_strdup(&host_cbs, hostpart)) - return 0; - return 1; -} - -int -x509_constraints_sandns(char *sandns, size_t dlen, char *constraint, size_t len) -{ - char *suffix; - - if (len == 0) - return 1; /* an empty constraint matches everything */ - - /* match the end of the domain */ - if (dlen < len) - return 0; - suffix = sandns + (dlen - len); - return (strncasecmp(suffix, constraint, len) == 0); -} - -/* - * Validate a pre-validated domain of length dlen against a pre-validated - * constraint of length len. - * - * returns 1 if the domain and constraint match. - * returns 0 otherwise. - * - * an empty constraint matches everything. - * constraint will be matched against the domain as a suffix if it - * starts with a '.'. - * domain will be matched against the constraint as a suffix if it - * starts with a '.'. - */ -int -x509_constraints_domain(char *domain, size_t dlen, char *constraint, size_t len) -{ - if (len == 0) - return 1; /* an empty constraint matches everything */ - - if (constraint[0] == '.') { - /* match the end of the domain */ - char *suffix; - if (dlen < len) - return 0; - suffix = domain + (dlen - len); - return (strncasecmp(suffix, constraint, len) == 0); - } - if (domain[0] == '.') { - /* match the end of the constraint */ - char *suffix; - if (len < dlen) - return 0; - suffix = constraint + (len - dlen); - return (strncasecmp(suffix, domain, dlen) == 0); - } - /* otherwise we must exactly match the constraint */ - if (dlen != len) - return 0; - return (strncasecmp(domain, constraint, len) == 0); -} - -int -x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, - size_t len, - int *error) -{ - int ret = 0; - char *hostpart = NULL; - CBS cbs; - - CBS_init(&cbs, constraint, len); - if (!x509_constraints_uri_host(uri, ulen, &hostpart)) { - *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - goto err; - } - if (hostpart == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!x509_constraints_valid_domain_constraint(&cbs)) { - *error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; - goto err; - } - ret = x509_constraints_domain(hostpart, strlen(hostpart), constraint, - len); - err: - free(hostpart); - return ret; -} - -/* - * Verify a validated address of size alen with a validated constraint - * of size constraint_len. returns 1 if matching, 0 if not. - * Addresses are assumed to be pre-validated for a length of 4 and 8 - * respectively for ipv4 addresses and constraints, and a length of - * 16 and 32 respectively for ipv6 address constraints by the caller. - */ -int -x509_constraints_ipaddr(uint8_t *address, size_t alen, uint8_t *constraint, - size_t len) -{ - uint8_t *mask; - size_t i; - - if (alen * 2 != len) - return 0; - - mask = constraint + alen; - for (i = 0; i < alen; i++) { - if ((address[i] & mask[i]) != (constraint[i] & mask[i])) - return 0; - } - return 1; -} - -/* - * Verify a canonicalized der encoded constraint dirname - * a canonicalized der encoded constraint. - */ -int -x509_constraints_dirname(uint8_t *dirname, size_t dlen, - uint8_t *constraint, size_t len) -{ - /* - * 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); -} - -/* - * De-obfuscate a GENERAL_NAME into useful bytes for a name or constraint. - */ -int -x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes, - size_t *len) -{ - *bytes = NULL; - *len = 0; - - if (name->type == GEN_DNS) { - ASN1_IA5STRING *aname = name->d.dNSName; - - *bytes = aname->data; - *len = aname->length; - - return name->type; - } - if (name->type == GEN_EMAIL) { - ASN1_IA5STRING *aname = name->d.rfc822Name; - - *bytes = aname->data; - *len = aname->length; - - return name->type; - } - if (name->type == GEN_URI) { - ASN1_IA5STRING *aname = name->d.uniformResourceIdentifier; - - *bytes = 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; -} - -/* - * Extract the relevant names for constraint checking from "cert", - * validate them, and add them to the list of cert names for "chain". - * returns 1 on success sets error and returns 0 on failure. - */ -int -x509_constraints_extract_names(struct x509_constraints_names *names, - X509 *cert, int is_leaf, int *error) -{ - struct x509_constraints_name *vname = NULL; - X509_NAME *subject_name; - GENERAL_NAME *name; - ssize_t i = 0; - int name_type, include_cn = is_leaf, include_email = is_leaf; - - /* first grab the altnames */ - while ((name = sk_GENERAL_NAME_value(cert->altname, i++)) != NULL) { - uint8_t *bytes = NULL; - size_t len = 0; - CBS cbs; - - if ((vname = x509_constraints_name_new()) == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - - name_type = x509_constraints_general_to_bytes(name, &bytes, - &len); - CBS_init(&cbs, bytes, len); - switch (name_type) { - case GEN_DNS: - if (!x509_constraints_valid_sandns(&cbs)) { - *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - goto err; - } - if (!CBS_strdup(&cbs, &vname->name)) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - vname->type = GEN_DNS; - include_cn = 0; /* Don't use cn from subject */ - break; - case GEN_EMAIL: - if (!x509_constraints_parse_mailbox(&cbs, vname)) { - *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - goto err; - } - vname->type = GEN_EMAIL; - include_email = 0; /* Don't use email from subject */ - break; - case GEN_URI: - if (!x509_constraints_uri_host(bytes, len, - &vname->name)) { - *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - goto err; - } - if (vname->name == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - 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; - } - memcpy(vname->der, bytes, len); - vname->der_len = len; - vname->type = GEN_DIRNAME; - break; - case GEN_IPADD: - if (len == 4) - vname->af = AF_INET; - if (len == 16) - vname->af = AF_INET6; - if (vname->af != AF_INET && vname->af != AF_INET6) { - *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - goto err; - } - memcpy(vname->address, bytes, len); - vname->type = GEN_IPADD; - break; - default: - /* Ignore this name */ - x509_constraints_name_free(vname); - vname = NULL; - continue; - } - if (!x509_constraints_names_add(names, vname)) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - vname = NULL; - } - - x509_constraints_name_free(vname); - vname = NULL; - - subject_name = X509_get_subject_name(cert); - if (X509_NAME_entry_count(subject_name) > 0) { - X509_NAME_ENTRY *email; - X509_NAME_ENTRY *cn; - /* - * This cert has a non-empty subject, so we must add - * the subject as a dirname to be compared against - * any dirname constraints - */ - if ((subject_name->modified && - i2d_X509_NAME(subject_name, NULL) < 0) || - (vname = x509_constraints_name_new()) == NULL || - (vname->der = malloc(subject_name->canon_enclen)) == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - - memcpy(vname->der, subject_name->canon_enc, - subject_name->canon_enclen); - vname->der_len = subject_name->canon_enclen; - vname->type = GEN_DIRNAME; - if (!x509_constraints_names_add(names, vname)) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - vname = NULL; - /* - * Get any email addresses from the subject line, and - * add them as mbox names to be compared against any - * email constraints - */ - while (include_email && - (i = X509_NAME_get_index_by_NID(subject_name, - NID_pkcs9_emailAddress, i)) >= 0) { - ASN1_STRING *aname; - CBS cbs; - if ((email = X509_NAME_get_entry(subject_name, i)) == - NULL || - (aname = X509_NAME_ENTRY_get_data(email)) == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - CBS_init(&cbs, aname->data, aname->length); - if ((vname = x509_constraints_name_new()) == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!x509_constraints_parse_mailbox(&cbs, vname)) { - *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - goto err; - } - vname->type = GEN_EMAIL; - if (!x509_constraints_names_add(names, vname)) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - vname = NULL; - } - /* - * Include the CN as a hostname to be checked against - * name constraints if it looks like a hostname. - */ - while (include_cn && - (i = X509_NAME_get_index_by_NID(subject_name, - NID_commonName, i)) >= 0) { - CBS cbs; - ASN1_STRING *aname; - if ((cn = X509_NAME_get_entry(subject_name, i)) == - NULL || - (aname = X509_NAME_ENTRY_get_data(cn)) == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - CBS_init(&cbs, aname->data, aname->length); - if (!x509_constraints_valid_host(&cbs, 0)) - continue; /* ignore it if not a hostname */ - if ((vname = x509_constraints_name_new()) == NULL) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!CBS_strdup(&cbs, &vname->name)) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - vname->type = GEN_DNS; - if (!x509_constraints_names_add(names, vname)) { - *error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - vname = NULL; - } - } - return 1; - err: - x509_constraints_name_free(vname); - return 0; -} - -/* - * Validate a constraint in a general name, putting the relevant data - * into "name" if valid. returns 0, and sets error if the constraint is - * not valid. returns 1 if the constraint validated. name->type will be - * set to a valid type if there is constraint data in name, or unmodified - * if the GENERAL_NAME had a valid type but was ignored. - */ -int -x509_constraints_validate(GENERAL_NAME *constraint, - struct x509_constraints_name **out_name, int *out_error) -{ - uint8_t next, *bytes = NULL; - size_t len = 0; - struct x509_constraints_name *name; - int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; - int name_type; - CBS cbs; - - 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); - CBS_init(&cbs, bytes, len); - switch (name_type) { - case GEN_DIRNAME: - 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; - break; - case GEN_DNS: - if (!x509_constraints_valid_domain_constraint(&cbs)) - goto err; - 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 (len > 0 && memchr(bytes + 1, '@', len - 1) != NULL) { - if (!x509_constraints_parse_mailbox(&cbs, name)) - goto err; - break; - } - /* - * Mail constraints of the form @domain.com are accepted by - * OpenSSL and Microsoft. - */ - if (CBS_len(&cbs) > 0) { - if (!CBS_peek_u8(&cbs, &next)) - goto err; - if (next == '@') { - if (!CBS_skip(&cbs, 1)) - goto err; - } - } - if (!x509_constraints_valid_domain_constraint(&cbs)) - goto err; - if (!CBS_strdup(&cbs, &name->name)) { - error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - name->type = GEN_EMAIL; - break; - case GEN_IPADD: - /* Constraints are ip then mask */ - if (len == 8) - name->af = AF_INET; - else if (len == 32) - name->af = AF_INET6; - else - goto err; - memcpy(&name->address[0], bytes, len); - name->type = GEN_IPADD; - break; - case GEN_URI: - if (!x509_constraints_valid_domain_constraint(&cbs)) - goto err; - 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: - x509_constraints_name_free(name); - if (out_error != NULL) - *out_error = error; - - return 0; -} - -int -x509_constraints_extract_constraints(X509 *cert, - struct x509_constraints_names *permitted, - struct x509_constraints_names *excluded, - int *error) -{ - struct x509_constraints_name *vname = NULL; - NAME_CONSTRAINTS *nc = cert->nc; - GENERAL_SUBTREE *subtree; - int i; - - if (nc == NULL) - return 1; - - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { - subtree = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); - if (subtree->minimum || subtree->maximum) { - *error = X509_V_ERR_SUBTREE_MINMAX; - return 0; - } - if (!x509_constraints_validate(subtree->base, &vname, error)) - 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++) { - subtree = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); - if (subtree->minimum || subtree->maximum) { - *error = X509_V_ERR_SUBTREE_MINMAX; - return 0; - } - if (!x509_constraints_validate(subtree->base, &vname, error)) - 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; -} - -/* - * Match a validated name in "name" against a validated constraint in - * "constraint" return 1 if then name matches, 0 otherwise. - */ -int -x509_constraints_match(struct x509_constraints_name *name, - struct x509_constraints_name *constraint) -{ - if (name->type != constraint->type) - return 0; - if (name->type == GEN_DNS) - return x509_constraints_sandns(name->name, strlen(name->name), - constraint->name, strlen(constraint->name)); - if (name->type == GEN_URI) - return x509_constraints_domain(name->name, strlen(name->name), - constraint->name, strlen(constraint->name)); - if (name->type == GEN_IPADD) { - size_t nlen = name->af == AF_INET ? 4 : 16; - size_t clen = name->af == AF_INET ? 8 : 32; - if (name->af != AF_INET && name->af != AF_INET6) - return 0; - if (constraint->af != AF_INET && constraint->af != AF_INET6) - return 0; - if (name->af != constraint->af) - return 0; - return x509_constraints_ipaddr(name->address, nlen, - constraint->address, clen); - } - if (name->type == GEN_EMAIL) { - if (constraint->local) { - /* mailbox local and domain parts must exactly match */ - return (strcmp(name->local, constraint->local) == 0 && - strcmp(name->name, constraint->name) == 0); - } - /* otherwise match the constraint to the domain part */ - return x509_constraints_domain(name->name, strlen(name->name), - constraint->name, strlen(constraint->name)); - } - if (name->type == GEN_DIRNAME) - return x509_constraints_dirname(name->der, name->der_len, - constraint->der, constraint->der_len); - return 0; -} - -/* - * Make sure every name in names does not match any excluded - * constraints, and does match at least one permitted constraint if - * any are present. Returns 1 if ok, 0, and sets error if not. - */ -int -x509_constraints_check(struct x509_constraints_names *names, - struct x509_constraints_names *permitted, - struct x509_constraints_names *excluded, int *error) -{ - size_t i, j; - - for (i = 0; i < names->names_count; i++) { - int permitted_seen = 0; - int permitted_matched = 0; - - for (j = 0; j < excluded->names_count; j++) { - if (x509_constraints_match(names->names[i], - excluded->names[j])) { - *error = X509_V_ERR_EXCLUDED_VIOLATION; - return 0; - } - } - for (j = 0; j < permitted->names_count; j++) { - if (permitted->names[j]->type == names->names[i]->type) - permitted_seen++; - if (x509_constraints_match(names->names[i], - permitted->names[j])) { - permitted_matched++; - break; - } - } - if (permitted_seen && !permitted_matched) { - *error = X509_V_ERR_PERMITTED_VIOLATION; - return 0; - } - } - return 1; -} - -/* - * Walk a validated chain of X509 certs, starting at the leaf, and - * validate the name constraints in the chain. Intended for use with - * the legacy X509 validation code in x509_vfy.c - * - * returns 1 if the constraints are ok, 0 otherwise, setting error and - * depth - */ -int -x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth) -{ - int chain_length, verify_err = X509_V_ERR_UNSPECIFIED, i = 0; - struct x509_constraints_names *names = NULL; - struct x509_constraints_names *excluded = NULL; - struct x509_constraints_names *permitted = NULL; - size_t constraints_count = 0; - X509 *cert; - - if (chain == NULL || (chain_length = sk_X509_num(chain)) == 0) - goto err; - if (chain_length == 1) - return 1; - if ((names = x509_constraints_names_new( - X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) { - verify_err = X509_V_ERR_OUT_OF_MEM; - goto err; - } - - if ((cert = sk_X509_value(chain, 0)) == NULL) - goto err; - if (!x509_constraints_extract_names(names, cert, 1, &verify_err)) - goto err; - for (i = 1; i < chain_length; i++) { - if ((cert = sk_X509_value(chain, i)) == NULL) - goto err; - if (cert->nc != 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( - X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { - verify_err = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!x509_constraints_extract_constraints(cert, - permitted, excluded, &verify_err)) - goto err; - constraints_count += permitted->names_count; - constraints_count += excluded->names_count; - if (constraints_count > - X509_VERIFY_MAX_CHAIN_CONSTRAINTS) { - verify_err = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!x509_constraints_check(names, permitted, excluded, - &verify_err)) - goto err; - x509_constraints_names_free(excluded); - excluded = NULL; - x509_constraints_names_free(permitted); - permitted = NULL; - } - if (!x509_constraints_extract_names(names, cert, 0, - &verify_err)) - goto err; - } - - x509_constraints_names_free(names); - return 1; - - err: - *error = verify_err; - *depth = i; - x509_constraints_names_free(excluded); - x509_constraints_names_free(permitted); - x509_constraints_names_free(names); - return 0; -} diff --git a/src/lib/libcrypto/x509/x509_cpols.c b/src/lib/libcrypto/x509/x509_cpols.c deleted file mode 100644 index 6bae2a0482..0000000000 --- a/src/lib/libcrypto/x509/x509_cpols.c +++ /dev/null @@ -1,773 +0,0 @@ -/* $OpenBSD: x509_cpols.c,v 1.15 2025/03/06 07:20:01 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "x509_local.h" - -/* Certificate policies extension support: this one is a bit complex... */ - -static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, - BIO *out, int indent); -static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value); -static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, - int indent); -static void print_notice(BIO *out, USERNOTICE *notice, int indent); -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org); -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *unot, int ia5org); -static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); - -static const X509V3_EXT_METHOD x509v3_ext_certificate_policies = { - .ext_nid = NID_certificate_policies, - .ext_flags = 0, - .it = &CERTIFICATEPOLICIES_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = (X509V3_EXT_I2R)i2r_certpol, - .r2i = (X509V3_EXT_R2I)r2i_certpol, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_certificate_policies(void) -{ - return &x509v3_ext_certificate_policies; -} - -static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "CERTIFICATEPOLICIES", - .item = &POLICYINFO_it, -}; - -const ASN1_ITEM CERTIFICATEPOLICIES_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &CERTIFICATEPOLICIES_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "CERTIFICATEPOLICIES", -}; -LCRYPTO_ALIAS(CERTIFICATEPOLICIES_it); - - -CERTIFICATEPOLICIES * -d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len) -{ - return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &CERTIFICATEPOLICIES_it); -} -LCRYPTO_ALIAS(d2i_CERTIFICATEPOLICIES); - -int -i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it); -} -LCRYPTO_ALIAS(i2d_CERTIFICATEPOLICIES); - -CERTIFICATEPOLICIES * -CERTIFICATEPOLICIES_new(void) -{ - return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it); -} -LCRYPTO_ALIAS(CERTIFICATEPOLICIES_new); - -void -CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it); -} -LCRYPTO_ALIAS(CERTIFICATEPOLICIES_free); - -static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICYINFO, policyid), - .field_name = "policyid", - .item = &ASN1_OBJECT_it, - }, - { - .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(POLICYINFO, qualifiers), - .field_name = "qualifiers", - .item = &POLICYQUALINFO_it, - }, -}; - -const ASN1_ITEM POLICYINFO_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = POLICYINFO_seq_tt, - .tcount = sizeof(POLICYINFO_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(POLICYINFO), - .sname = "POLICYINFO", -}; -LCRYPTO_ALIAS(POLICYINFO_it); - - -POLICYINFO * -d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len) -{ - return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &POLICYINFO_it); -} -LCRYPTO_ALIAS(d2i_POLICYINFO); - -int -i2d_POLICYINFO(POLICYINFO *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it); -} -LCRYPTO_ALIAS(i2d_POLICYINFO); - -POLICYINFO * -POLICYINFO_new(void) -{ - return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it); -} -LCRYPTO_ALIAS(POLICYINFO_new); - -void -POLICYINFO_free(POLICYINFO *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it); -} -LCRYPTO_ALIAS(POLICYINFO_free); - -static const ASN1_TEMPLATE policydefault_tt = { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICYQUALINFO, d.other), - .field_name = "d.other", - .item = &ASN1_ANY_it, -}; - -static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = { - { - .value = NID_id_qt_cps, - .tt = { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICYQUALINFO, d.cpsuri), - .field_name = "d.cpsuri", - .item = &ASN1_IA5STRING_it, - }, - }, - { - .value = NID_id_qt_unotice, - .tt = { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICYQUALINFO, d.usernotice), - .field_name = "d.usernotice", - .item = &USERNOTICE_it, - }, - }, -}; - -static const ASN1_ADB POLICYQUALINFO_adb = { - .flags = 0, - .offset = offsetof(POLICYQUALINFO, pqualid), - .tbl = POLICYQUALINFO_adbtbl, - .tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE), - .default_tt = &policydefault_tt, - .null_tt = NULL, -}; - -static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICYQUALINFO, pqualid), - .field_name = "pqualid", - .item = &ASN1_OBJECT_it, - }, - { - .flags = ASN1_TFLG_ADB_OID, - .tag = -1, - .offset = 0, - .field_name = "POLICYQUALINFO", - .item = (const ASN1_ITEM *)&POLICYQUALINFO_adb, - }, -}; - -const ASN1_ITEM POLICYQUALINFO_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = POLICYQUALINFO_seq_tt, - .tcount = sizeof(POLICYQUALINFO_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(POLICYQUALINFO), - .sname = "POLICYQUALINFO", -}; -LCRYPTO_ALIAS(POLICYQUALINFO_it); - - -POLICYQUALINFO * -d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len) -{ - return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &POLICYQUALINFO_it); -} -LCRYPTO_ALIAS(d2i_POLICYQUALINFO); - -int -i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it); -} -LCRYPTO_ALIAS(i2d_POLICYQUALINFO); - -POLICYQUALINFO * -POLICYQUALINFO_new(void) -{ - return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it); -} -LCRYPTO_ALIAS(POLICYQUALINFO_new); - -void -POLICYQUALINFO_free(POLICYQUALINFO *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it); -} -LCRYPTO_ALIAS(POLICYQUALINFO_free); - -static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = { - { - .flags = ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(USERNOTICE, noticeref), - .field_name = "noticeref", - .item = &NOTICEREF_it, - }, - { - .flags = ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(USERNOTICE, exptext), - .field_name = "exptext", - .item = &DISPLAYTEXT_it, - }, -}; - -const ASN1_ITEM USERNOTICE_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = USERNOTICE_seq_tt, - .tcount = sizeof(USERNOTICE_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(USERNOTICE), - .sname = "USERNOTICE", -}; -LCRYPTO_ALIAS(USERNOTICE_it); - - -USERNOTICE * -d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len) -{ - return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &USERNOTICE_it); -} -LCRYPTO_ALIAS(d2i_USERNOTICE); - -int -i2d_USERNOTICE(USERNOTICE *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it); -} -LCRYPTO_ALIAS(i2d_USERNOTICE); - -USERNOTICE * -USERNOTICE_new(void) -{ - return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it); -} -LCRYPTO_ALIAS(USERNOTICE_new); - -void -USERNOTICE_free(USERNOTICE *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it); -} -LCRYPTO_ALIAS(USERNOTICE_free); - -static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(NOTICEREF, organization), - .field_name = "organization", - .item = &DISPLAYTEXT_it, - }, - { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = offsetof(NOTICEREF, noticenos), - .field_name = "noticenos", - .item = &ASN1_INTEGER_it, - }, -}; - -const ASN1_ITEM NOTICEREF_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = NOTICEREF_seq_tt, - .tcount = sizeof(NOTICEREF_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(NOTICEREF), - .sname = "NOTICEREF", -}; -LCRYPTO_ALIAS(NOTICEREF_it); - - -NOTICEREF * -d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len) -{ - return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &NOTICEREF_it); -} -LCRYPTO_ALIAS(d2i_NOTICEREF); - -int -i2d_NOTICEREF(NOTICEREF *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it); -} -LCRYPTO_ALIAS(i2d_NOTICEREF); - -NOTICEREF * -NOTICEREF_new(void) -{ - return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it); -} -LCRYPTO_ALIAS(NOTICEREF_new); - -void -NOTICEREF_free(NOTICEREF *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it); -} -LCRYPTO_ALIAS(NOTICEREF_free); - -static STACK_OF(POLICYINFO) * -r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value) -{ - STACK_OF(POLICYINFO) *pols = NULL; - char *pstr; - POLICYINFO *pol; - ASN1_OBJECT *pobj; - STACK_OF(CONF_VALUE) *vals; - CONF_VALUE *cnf; - int i, ia5org; - - pols = sk_POLICYINFO_new_null(); - if (pols == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - vals = X509V3_parse_list(value); - if (vals == NULL) { - X509V3error(ERR_R_X509V3_LIB); - goto err; - } - ia5org = 0; - for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { - cnf = sk_CONF_VALUE_value(vals, i); - if (cnf->value || !cnf->name) { - X509V3error(X509V3_R_INVALID_POLICY_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pstr = cnf->name; - if (!strcmp(pstr, "ia5org")) { - ia5org = 1; - continue; - } else if (*pstr == '@') { - STACK_OF(CONF_VALUE) *polsect; - polsect = X509V3_get0_section(ctx, pstr + 1); - if (!polsect) { - X509V3error(X509V3_R_INVALID_SECTION); - X509V3_conf_err(cnf); - goto err; - } - pol = policy_section(ctx, polsect, ia5org); - if (!pol) - goto err; - } else { - if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { - X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pol = POLICYINFO_new(); - pol->policyid = pobj; - } - if (!sk_POLICYINFO_push(pols, pol)){ - POLICYINFO_free(pol); - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - } - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - return pols; - -err: - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - sk_POLICYINFO_pop_free(pols, POLICYINFO_free); - return NULL; -} - -static POLICYINFO * -policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org) -{ - int i; - CONF_VALUE *cnf; - POLICYINFO *pol; - POLICYQUALINFO *nqual = NULL; - - if ((pol = POLICYINFO_new()) == NULL) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { - cnf = sk_CONF_VALUE_value(polstrs, i); - if (strcmp(cnf->name, "policyIdentifier") == 0) { - ASN1_OBJECT *pobj; - - if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) { - X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pol->policyid = pobj; - } else if (name_cmp(cnf->name, "CPS") == 0) { - if ((nqual = POLICYQUALINFO_new()) == NULL) - goto merr; - nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps); - nqual->d.cpsuri = ASN1_IA5STRING_new(); - if (nqual->d.cpsuri == NULL) - goto merr; - if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value, - strlen(cnf->value)) == 0) - goto merr; - - if (pol->qualifiers == NULL) { - pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (pol->qualifiers == NULL) - goto merr; - } - if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0) - goto merr; - nqual = NULL; - } else if (name_cmp(cnf->name, "userNotice") == 0) { - STACK_OF(CONF_VALUE) *unot; - POLICYQUALINFO *qual; - - if (*cnf->value != '@') { - X509V3error(X509V3_R_EXPECTED_A_SECTION_NAME); - X509V3_conf_err(cnf); - goto err; - } - unot = X509V3_get0_section(ctx, cnf->value + 1); - if (unot == NULL) { - X509V3error(X509V3_R_INVALID_SECTION); - X509V3_conf_err(cnf); - goto err; - } - qual = notice_section(ctx, unot, ia5org); - if (qual == NULL) - goto err; - - if (pol->qualifiers == NULL) { - pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (pol->qualifiers == NULL) - goto merr; - } - if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0) - goto merr; - } else { - X509V3error(X509V3_R_INVALID_OPTION); - X509V3_conf_err(cnf); - goto err; - } - } - if (pol->policyid == NULL) { - X509V3error(X509V3_R_NO_POLICY_IDENTIFIER); - goto err; - } - - return pol; - -merr: - X509V3error(ERR_R_MALLOC_FAILURE); - -err: - POLICYQUALINFO_free(nqual); - POLICYINFO_free(pol); - return NULL; -} - -static POLICYQUALINFO * -notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org) -{ - int i, ret; - CONF_VALUE *cnf; - USERNOTICE *not; - POLICYQUALINFO *qual; - - if (!(qual = POLICYQUALINFO_new())) - goto merr; - qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); - if (!(not = USERNOTICE_new())) - goto merr; - qual->d.usernotice = not; - for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { - cnf = sk_CONF_VALUE_value(unot, i); - if (!strcmp(cnf->name, "explicitText")) { - if (not->exptext == NULL) { - not->exptext = ASN1_UTF8STRING_new(); - if (not->exptext == NULL) - goto merr; - } - if (!ASN1_STRING_set(not->exptext, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!strcmp(cnf->name, "organization")) { - NOTICEREF *nref; - if (!not->noticeref) { - if (!(nref = NOTICEREF_new())) - goto merr; - not->noticeref = nref; - } else - nref = not->noticeref; - if (ia5org) - nref->organization->type = V_ASN1_IA5STRING; - else - nref->organization->type = V_ASN1_VISIBLESTRING; - if (!ASN1_STRING_set(nref->organization, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!strcmp(cnf->name, "noticeNumbers")) { - NOTICEREF *nref; - STACK_OF(CONF_VALUE) *nos; - if (!not->noticeref) { - if (!(nref = NOTICEREF_new())) - goto merr; - not->noticeref = nref; - } else - nref = not->noticeref; - nos = X509V3_parse_list(cnf->value); - if (!nos || !sk_CONF_VALUE_num(nos)) { - X509V3error(X509V3_R_INVALID_NUMBERS); - X509V3_conf_err(cnf); - if (nos != NULL) - sk_CONF_VALUE_pop_free(nos, - X509V3_conf_free); - goto err; - } - ret = nref_nos(nref->noticenos, nos); - sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); - if (!ret) - goto err; - } else { - X509V3error(X509V3_R_INVALID_OPTION); - X509V3_conf_err(cnf); - goto err; - } - } - - if (not->noticeref && - (!not->noticeref->noticenos || !not->noticeref->organization)) { - X509V3error(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); - goto err; - } - - return qual; - -merr: - X509V3error(ERR_R_MALLOC_FAILURE); - -err: - POLICYQUALINFO_free(qual); - return NULL; -} - -static int -nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) -{ - CONF_VALUE *cnf; - ASN1_INTEGER *aint; - int i; - - for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { - cnf = sk_CONF_VALUE_value(nos, i); - if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { - X509V3error(X509V3_R_INVALID_NUMBER); - goto err; - } - if (!sk_ASN1_INTEGER_push(nnums, aint)) - goto merr; - } - return 1; - -merr: - X509V3error(ERR_R_MALLOC_FAILURE); - -err: - sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free); - return 0; -} - -static int -i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, - int indent) -{ - int i; - POLICYINFO *pinfo; - - /* First print out the policy OIDs */ - for (i = 0; i < sk_POLICYINFO_num(pol); i++) { - pinfo = sk_POLICYINFO_value(pol, i); - BIO_printf(out, "%*sPolicy: ", indent, ""); - i2a_ASN1_OBJECT(out, pinfo->policyid); - BIO_puts(out, "\n"); - if (pinfo->qualifiers) - print_qualifiers(out, pinfo->qualifiers, indent + 2); - } - return 1; -} - -static void -print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent) -{ - POLICYQUALINFO *qualinfo; - int i; - - for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { - qualinfo = sk_POLICYQUALINFO_value(quals, i); - switch (OBJ_obj2nid(qualinfo->pqualid)) { - case NID_id_qt_cps: - BIO_printf(out, "%*sCPS: %.*s\n", indent, "", - qualinfo->d.cpsuri->length, - qualinfo->d.cpsuri->data); - break; - - case NID_id_qt_unotice: - BIO_printf(out, "%*sUser Notice:\n", indent, ""); - print_notice(out, qualinfo->d.usernotice, indent + 2); - break; - - default: - BIO_printf(out, "%*sUnknown Qualifier: ", - indent + 2, ""); - - i2a_ASN1_OBJECT(out, qualinfo->pqualid); - BIO_puts(out, "\n"); - break; - } - } -} - -static void -print_notice(BIO *out, USERNOTICE *notice, int indent) -{ - int i; - - if (notice->noticeref) { - NOTICEREF *ref; - ref = notice->noticeref; - 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++) { - ASN1_INTEGER *num; - char *tmp; - num = sk_ASN1_INTEGER_value(ref->noticenos, i); - if (i) - BIO_puts(out, ", "); - tmp = i2s_ASN1_INTEGER(NULL, num); - BIO_puts(out, tmp); - free(tmp); - } - BIO_puts(out, "\n"); - } - if (notice->exptext) - BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", - notice->exptext->length, notice->exptext->data); -} diff --git a/src/lib/libcrypto/x509/x509_crld.c b/src/lib/libcrypto/x509/x509_crld.c deleted file mode 100644 index 81f2010df5..0000000000 --- a/src/lib/libcrypto/x509/x509_crld.c +++ /dev/null @@ -1,852 +0,0 @@ -/* $OpenBSD: x509_crld.c,v 1.9 2025/03/06 07:20:01 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "x509_local.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, - int indent); - -static const X509V3_EXT_METHOD x509v3_ext_crl_distribution_points = { - .ext_nid = NID_crl_distribution_points, - .ext_flags = 0, - .it = &CRL_DIST_POINTS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = v2i_crld, - .i2r = i2r_crldp, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_crl_distribution_points(void) -{ - return &x509v3_ext_crl_distribution_points; -} - -static const X509V3_EXT_METHOD x509v3_ext_freshest_crl = { - .ext_nid = NID_freshest_crl, - .ext_flags = 0, - .it = &CRL_DIST_POINTS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = v2i_crld, - .i2r = i2r_crldp, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_freshest_crl(void) -{ - return &x509v3_ext_freshest_crl; -} - -static STACK_OF(GENERAL_NAME) * -gnames_from_sectname(X509V3_CTX *ctx, char *sect) -{ - STACK_OF(CONF_VALUE) *gnsect; - STACK_OF(GENERAL_NAME) *gens; - - if (*sect == '@') - gnsect = X509V3_get0_section(ctx, sect + 1); - else - gnsect = X509V3_parse_list(sect); - if (!gnsect) { - X509V3error(X509V3_R_SECTION_NOT_FOUND); - return NULL; - } - gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); - if (*sect != '@') - sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); - return gens; -} - -static int -set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, CONF_VALUE *cnf) -{ - STACK_OF(GENERAL_NAME) *fnm = NULL; - STACK_OF(X509_NAME_ENTRY) *rnm = NULL; - - if (!strncmp(cnf->name, "fullname", 9)) { - fnm = gnames_from_sectname(ctx, cnf->value); - if (!fnm) - goto err; - } else if (!strcmp(cnf->name, "relativename")) { - int ret; - STACK_OF(CONF_VALUE) *dnsect; - X509_NAME *nm; - nm = X509_NAME_new(); - if (!nm) - return -1; - dnsect = X509V3_get0_section(ctx, cnf->value); - if (!dnsect) { - X509V3error(X509V3_R_SECTION_NOT_FOUND); - X509_NAME_free(nm); - return -1; - } - ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); - rnm = nm->entries; - nm->entries = NULL; - X509_NAME_free(nm); - if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) - goto err; - /* Since its a name fragment can't have more than one - * RDNSequence - */ - if (sk_X509_NAME_ENTRY_value(rnm, - sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { - X509V3error(X509V3_R_INVALID_MULTIPLE_RDNS); - goto err; - } - } else - return 0; - - if (*pdp) { - X509V3error(X509V3_R_DISTPOINT_ALREADY_SET); - goto err; - } - - *pdp = DIST_POINT_NAME_new(); - if (!*pdp) - goto err; - if (fnm) { - (*pdp)->type = 0; - (*pdp)->name.fullname = fnm; - } else { - (*pdp)->type = 1; - (*pdp)->name.relativename = rnm; - } - - return 1; - -err: - sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); - sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); - return -1; -} - -static const BIT_STRING_BITNAME reason_flags[] = { - {0, "Unused", "unused"}, - {1, "Key Compromise", "keyCompromise"}, - {2, "CA Compromise", "CACompromise"}, - {3, "Affiliation Changed", "affiliationChanged"}, - {4, "Superseded", "superseded"}, - {5, "Cessation Of Operation", "cessationOfOperation"}, - {6, "Certificate Hold", "certificateHold"}, - {7, "Privilege Withdrawn", "privilegeWithdrawn"}, - {8, "AA Compromise", "AACompromise"}, - {-1, NULL, NULL} -}; - -static int -set_reasons(ASN1_BIT_STRING **preas, char *value) -{ - STACK_OF(CONF_VALUE) *rsk = NULL; - const BIT_STRING_BITNAME *pbn; - const char *bnam; - int i, ret = 0; - - if (*preas != NULL) - return 0; - rsk = X509V3_parse_list(value); - if (rsk == NULL) - return 0; - for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { - bnam = sk_CONF_VALUE_value(rsk, i)->name; - if (!*preas) { - *preas = ASN1_BIT_STRING_new(); - if (!*preas) - goto err; - } - for (pbn = reason_flags; pbn->lname; pbn++) { - if (!strcmp(pbn->sname, bnam)) { - if (!ASN1_BIT_STRING_set_bit(*preas, - pbn->bitnum, 1)) - goto err; - break; - } - } - if (!pbn->lname) - goto err; - } - ret = 1; - -err: - sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); - return ret; -} - -static int -print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, int indent) -{ - int first = 1; - const BIT_STRING_BITNAME *pbn; - - BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); - for (pbn = reason_flags; pbn->lname; pbn++) { - if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { - if (first) - first = 0; - else - BIO_puts(out, ", "); - BIO_puts(out, pbn->lname); - } - } - if (first) - BIO_puts(out, "\n"); - else - BIO_puts(out, "\n"); - return 1; -} - -static DIST_POINT * -crldp_from_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - int i; - CONF_VALUE *cnf; - DIST_POINT *point = NULL; - - point = DIST_POINT_new(); - if (!point) - goto err; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - int ret; - cnf = sk_CONF_VALUE_value(nval, i); - ret = set_dist_point_name(&point->distpoint, ctx, cnf); - if (ret > 0) - continue; - if (ret < 0) - goto err; - if (!strcmp(cnf->name, "reasons")) { - if (!set_reasons(&point->reasons, cnf->value)) - goto err; - } - else if (!strcmp(cnf->name, "CRLissuer")) { - point->CRLissuer = - gnames_from_sectname(ctx, cnf->value); - if (!point->CRLissuer) - goto err; - } - } - - return point; - -err: - DIST_POINT_free(point); - return NULL; -} - -static void * -v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - STACK_OF(DIST_POINT) *crld = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gen = NULL; - CONF_VALUE *cnf; - int i; - - if (!(crld = sk_DIST_POINT_new_null())) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - DIST_POINT *point; - cnf = sk_CONF_VALUE_value(nval, i); - if (!cnf->value) { - STACK_OF(CONF_VALUE) *dpsect; - dpsect = X509V3_get0_section(ctx, cnf->name); - if (!dpsect) - goto err; - point = crldp_from_section(ctx, dpsect); - if (!point) - goto err; - if (!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - } else { - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - if (!(gens = GENERAL_NAMES_new())) - goto merr; - if (!sk_GENERAL_NAME_push(gens, gen)) - goto merr; - gen = NULL; - if (!(point = DIST_POINT_new())) - goto merr; - if (!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - if (!(point->distpoint = DIST_POINT_NAME_new())) - goto merr; - point->distpoint->name.fullname = gens; - point->distpoint->type = 0; - gens = NULL; - } - } - return crld; - -merr: - X509V3error(ERR_R_MALLOC_FAILURE); -err: - GENERAL_NAME_free(gen); - GENERAL_NAMES_free(gens); - sk_DIST_POINT_pop_free(crld, DIST_POINT_free); - return NULL; -} - -static int -dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) -{ - DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; - - switch (operation) { - case ASN1_OP_NEW_POST: - dpn->dpname = NULL; - break; - - case ASN1_OP_FREE_POST: - if (dpn->dpname) - X509_NAME_free(dpn->dpname); - break; - } - return 1; -} - - -static const ASN1_AUX DIST_POINT_NAME_aux = { - .app_data = NULL, - .flags = 0, - .ref_offset = 0, - .ref_lock = 0, - .asn1_cb = dpn_cb, - .enc_offset = 0, -}; -static const ASN1_TEMPLATE DIST_POINT_NAME_ch_tt[] = { - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = offsetof(DIST_POINT_NAME, name.fullname), - .field_name = "name.fullname", - .item = &GENERAL_NAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF, - .tag = 1, - .offset = offsetof(DIST_POINT_NAME, name.relativename), - .field_name = "name.relativename", - .item = &X509_NAME_ENTRY_it, - }, -}; - -const ASN1_ITEM DIST_POINT_NAME_it = { - .itype = ASN1_ITYPE_CHOICE, - .utype = offsetof(DIST_POINT_NAME, type), - .templates = DIST_POINT_NAME_ch_tt, - .tcount = sizeof(DIST_POINT_NAME_ch_tt) / sizeof(ASN1_TEMPLATE), - .funcs = &DIST_POINT_NAME_aux, - .size = sizeof(DIST_POINT_NAME), - .sname = "DIST_POINT_NAME", -}; -LCRYPTO_ALIAS(DIST_POINT_NAME_it); - - - -DIST_POINT_NAME * -d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len) -{ - return (DIST_POINT_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &DIST_POINT_NAME_it); -} -LCRYPTO_ALIAS(d2i_DIST_POINT_NAME); - -int -i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it); -} -LCRYPTO_ALIAS(i2d_DIST_POINT_NAME); - -DIST_POINT_NAME * -DIST_POINT_NAME_new(void) -{ - return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it); -} -LCRYPTO_ALIAS(DIST_POINT_NAME_new); - -void -DIST_POINT_NAME_free(DIST_POINT_NAME *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it); -} -LCRYPTO_ALIAS(DIST_POINT_NAME_free); - -static const ASN1_TEMPLATE DIST_POINT_seq_tt[] = { - { - .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(DIST_POINT, distpoint), - .field_name = "distpoint", - .item = &DIST_POINT_NAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(DIST_POINT, reasons), - .field_name = "reasons", - .item = &ASN1_BIT_STRING_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, - .tag = 2, - .offset = offsetof(DIST_POINT, CRLissuer), - .field_name = "CRLissuer", - .item = &GENERAL_NAME_it, - }, -}; - -const ASN1_ITEM DIST_POINT_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = DIST_POINT_seq_tt, - .tcount = sizeof(DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(DIST_POINT), - .sname = "DIST_POINT", -}; -LCRYPTO_ALIAS(DIST_POINT_it); - - -DIST_POINT * -d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len) -{ - return (DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &DIST_POINT_it); -} -LCRYPTO_ALIAS(d2i_DIST_POINT); - -int -i2d_DIST_POINT(DIST_POINT *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it); -} -LCRYPTO_ALIAS(i2d_DIST_POINT); - -DIST_POINT * -DIST_POINT_new(void) -{ - return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it); -} -LCRYPTO_ALIAS(DIST_POINT_new); - -void -DIST_POINT_free(DIST_POINT *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it); -} -LCRYPTO_ALIAS(DIST_POINT_free); - -static const ASN1_TEMPLATE CRL_DIST_POINTS_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "CRLDistributionPoints", - .item = &DIST_POINT_it, -}; - -const ASN1_ITEM CRL_DIST_POINTS_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &CRL_DIST_POINTS_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "CRL_DIST_POINTS", -}; -LCRYPTO_ALIAS(CRL_DIST_POINTS_it); - - -CRL_DIST_POINTS * -d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len) -{ - return (CRL_DIST_POINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &CRL_DIST_POINTS_it); -} -LCRYPTO_ALIAS(d2i_CRL_DIST_POINTS); - -int -i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it); -} -LCRYPTO_ALIAS(i2d_CRL_DIST_POINTS); - -CRL_DIST_POINTS * -CRL_DIST_POINTS_new(void) -{ - return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it); -} -LCRYPTO_ALIAS(CRL_DIST_POINTS_new); - -void -CRL_DIST_POINTS_free(CRL_DIST_POINTS *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it); -} -LCRYPTO_ALIAS(CRL_DIST_POINTS_free); - -static const ASN1_TEMPLATE ISSUING_DIST_POINT_seq_tt[] = { - { - .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(ISSUING_DIST_POINT, distpoint), - .field_name = "distpoint", - .item = &DIST_POINT_NAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(ISSUING_DIST_POINT, onlyuser), - .field_name = "onlyuser", - .item = &ASN1_FBOOLEAN_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 2, - .offset = offsetof(ISSUING_DIST_POINT, onlyCA), - .field_name = "onlyCA", - .item = &ASN1_FBOOLEAN_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 3, - .offset = offsetof(ISSUING_DIST_POINT, onlysomereasons), - .field_name = "onlysomereasons", - .item = &ASN1_BIT_STRING_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 4, - .offset = offsetof(ISSUING_DIST_POINT, indirectCRL), - .field_name = "indirectCRL", - .item = &ASN1_FBOOLEAN_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 5, - .offset = offsetof(ISSUING_DIST_POINT, onlyattr), - .field_name = "onlyattr", - .item = &ASN1_FBOOLEAN_it, - }, -}; - -const ASN1_ITEM ISSUING_DIST_POINT_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = ISSUING_DIST_POINT_seq_tt, - .tcount = sizeof(ISSUING_DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(ISSUING_DIST_POINT), - .sname = "ISSUING_DIST_POINT", -}; -LCRYPTO_ALIAS(ISSUING_DIST_POINT_it); - - -ISSUING_DIST_POINT * -d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len) -{ - return (ISSUING_DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ISSUING_DIST_POINT_it); -} -LCRYPTO_ALIAS(d2i_ISSUING_DIST_POINT); - -int -i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it); -} -LCRYPTO_ALIAS(i2d_ISSUING_DIST_POINT); - -ISSUING_DIST_POINT * -ISSUING_DIST_POINT_new(void) -{ - return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it); -} -LCRYPTO_ALIAS(ISSUING_DIST_POINT_new); - -void -ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it); -} -LCRYPTO_ALIAS(ISSUING_DIST_POINT_free); - -static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, - int indent); -static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); - -static const X509V3_EXT_METHOD x509v3_ext_issuing_distribution_point = { - .ext_nid = NID_issuing_distribution_point, - .ext_flags = X509V3_EXT_MULTILINE, - .it = &ISSUING_DIST_POINT_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = v2i_idp, - .i2r = i2r_idp, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_issuing_distribution_point(void) -{ - return &x509v3_ext_issuing_distribution_point; -} - -static void * -v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - ISSUING_DIST_POINT *idp = NULL; - CONF_VALUE *cnf; - char *name, *val; - int i, ret; - - idp = ISSUING_DIST_POINT_new(); - if (!idp) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - name = cnf->name; - val = cnf->value; - ret = set_dist_point_name(&idp->distpoint, ctx, cnf); - if (ret > 0) - continue; - if (ret < 0) - goto err; - if (!strcmp(name, "onlyuser")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) - goto err; - } - else if (!strcmp(name, "onlyCA")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) - goto err; - } - else if (!strcmp(name, "onlyAA")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) - goto err; - } - else if (!strcmp(name, "indirectCRL")) { - if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) - goto err; - } - else if (!strcmp(name, "onlysomereasons")) { - if (!set_reasons(&idp->onlysomereasons, val)) - goto err; - } else { - X509V3error(X509V3_R_INVALID_NAME); - X509V3_conf_err(cnf); - goto err; - } - } - return idp; - -merr: - X509V3error(ERR_R_MALLOC_FAILURE); -err: - ISSUING_DIST_POINT_free(idp); - return NULL; -} - -static int -print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) -{ - int i; - - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - BIO_printf(out, "%*s", indent + 2, ""); - GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); - BIO_puts(out, "\n"); - } - return 1; -} - -static int -print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) -{ - if (dpn->type == 0) { - BIO_printf(out, "%*sFull Name:\n", indent, ""); - print_gens(out, dpn->name.fullname, indent); - } else { - X509_NAME ntmp; - ntmp.entries = dpn->name.relativename; - BIO_printf(out, "%*sRelative Name:\n%*s", - indent, "", indent + 2, ""); - X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); - BIO_puts(out, "\n"); - } - return 1; -} - -static int -i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent) -{ - ISSUING_DIST_POINT *idp = pidp; - - if (idp->distpoint) - print_distpoint(out, idp->distpoint, indent); - if (idp->onlyuser > 0) - BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); - if (idp->onlyCA > 0) - BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); - if (idp->indirectCRL > 0) - BIO_printf(out, "%*sIndirect CRL\n", indent, ""); - if (idp->onlysomereasons) - print_reasons(out, "Only Some Reasons", - idp->onlysomereasons, indent); - if (idp->onlyattr > 0) - BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); - if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) && - (idp->indirectCRL <= 0) && !idp->onlysomereasons && - (idp->onlyattr <= 0)) - BIO_printf(out, "%*s\n", indent, ""); - - return 1; -} - -static int -i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent) -{ - STACK_OF(DIST_POINT) *crld = pcrldp; - DIST_POINT *point; - int i; - - for (i = 0; i < sk_DIST_POINT_num(crld); i++) { - BIO_puts(out, "\n"); - point = sk_DIST_POINT_value(crld, i); - if (point->distpoint) - print_distpoint(out, point->distpoint, indent); - if (point->reasons) - print_reasons(out, "Reasons", point->reasons, - indent); - if (point->CRLissuer) { - BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); - print_gens(out, point->CRLissuer, indent); - } - } - return 1; -} - -int -DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) -{ - int i; - STACK_OF(X509_NAME_ENTRY) *frag; - X509_NAME_ENTRY *ne; - - if (!dpn || (dpn->type != 1)) - return 1; - frag = dpn->name.relativename; - dpn->dpname = X509_NAME_dup(iname); - if (!dpn->dpname) - return 0; - for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { - ne = sk_X509_NAME_ENTRY_value(frag, i); - if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - } - /* generate cached encoding of name */ - if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - return 1; -} -LCRYPTO_ALIAS(DIST_POINT_set_dpname); diff --git a/src/lib/libcrypto/x509/x509_d2.c b/src/lib/libcrypto/x509/x509_d2.c deleted file mode 100644 index bf358ec299..0000000000 --- a/src/lib/libcrypto/x509/x509_d2.c +++ /dev/null @@ -1,131 +0,0 @@ -/* $OpenBSD: x509_d2.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -#include -#include -#include - -int -X509_STORE_set_default_paths(X509_STORE *ctx) -{ - X509_LOOKUP *lookup; - - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return (0); - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); - - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return (0); - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); - - /* clear any errors */ - ERR_clear_error(); - - return (1); -} -LCRYPTO_ALIAS(X509_STORE_set_default_paths); - -int -X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path) -{ - X509_LOOKUP *lookup; - - if (file != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return (0); - if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) - return (0); - } - if (path != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return (0); - if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) - return (0); - } - if ((path == NULL) && (file == NULL)) - return (0); - return (1); -} -LCRYPTO_ALIAS(X509_STORE_load_locations); - -int -X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len) -{ - X509_LOOKUP *lookup; - struct iovec iov; - - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_mem()); - if (lookup == NULL) - return (0); - - iov.iov_base = buf; - iov.iov_len = len; - - if (X509_LOOKUP_add_mem(lookup, &iov, X509_FILETYPE_PEM) != 1) - return (0); - - return (1); -} -LCRYPTO_ALIAS(X509_STORE_load_mem); diff --git a/src/lib/libcrypto/x509/x509_def.c b/src/lib/libcrypto/x509/x509_def.c deleted file mode 100644 index f9b395c206..0000000000 --- a/src/lib/libcrypto/x509/x509_def.c +++ /dev/null @@ -1,103 +0,0 @@ -/* $OpenBSD: x509_def.c,v 1.10 2024/11/05 09:35:40 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include "crypto_local.h" - -const char * -X509_get_default_private_dir(void) -{ - return X509_PRIVATE_DIR; -} -LCRYPTO_ALIAS(X509_get_default_private_dir); - -const char * -X509_get_default_cert_area(void) -{ - return X509_CERT_AREA; -} -LCRYPTO_ALIAS(X509_get_default_cert_area); - -const char * -X509_get_default_cert_dir(void) -{ - return X509_CERT_DIR; -} -LCRYPTO_ALIAS(X509_get_default_cert_dir); - -const char * -X509_get_default_cert_file(void) -{ - return X509_CERT_FILE; -} -LCRYPTO_ALIAS(X509_get_default_cert_file); - -const char * -X509_get_default_cert_dir_env(void) -{ - return X509_CERT_DIR_EVP; -} -LCRYPTO_ALIAS(X509_get_default_cert_dir_env); - -const char * -X509_get_default_cert_file_env(void) -{ - return X509_CERT_FILE_EVP; -} -LCRYPTO_ALIAS(X509_get_default_cert_file_env); diff --git a/src/lib/libcrypto/x509/x509_err.c b/src/lib/libcrypto/x509/x509_err.c deleted file mode 100644 index cff045b105..0000000000 --- a/src/lib/libcrypto/x509/x509_err.c +++ /dev/null @@ -1,215 +0,0 @@ -/* $OpenBSD: x509_err.c,v 1.23 2024/06/24 06:43:23 tb Exp $ */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include - -#include -#include -#include - -#include "err_local.h" - -#ifndef OPENSSL_NO_ERR - -#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) -#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) - -static const ERR_STRING_DATA X509_str_functs[] = { - {ERR_FUNC(0xfff), "CRYPTO_internal"}, - {0, NULL} -}; - -static const ERR_STRING_DATA X509_str_reasons[] = { - {ERR_REASON(X509_R_BAD_X509_FILETYPE) , "bad x509 filetype"}, - {ERR_REASON(X509_R_BASE64_DECODE_ERROR) , "base64 decode error"}, - {ERR_REASON(X509_R_CANT_CHECK_DH_KEY) , "cant check dh key"}, - {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), "cert already in hash table"}, - {ERR_REASON(X509_R_ERR_ASN1_LIB) , "err asn1 lib"}, - {ERR_REASON(X509_R_INVALID_DIRECTORY) , "invalid directory"}, - {ERR_REASON(X509_R_INVALID_FIELD_NAME) , "invalid field name"}, - {ERR_REASON(X509_R_INVALID_TRUST) , "invalid trust"}, - {ERR_REASON(X509_R_INVALID_VERSION) , "invalid x509 version"}, - {ERR_REASON(X509_R_KEY_TYPE_MISMATCH) , "key type mismatch"}, - {ERR_REASON(X509_R_KEY_VALUES_MISMATCH) , "key values mismatch"}, - {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"}, - {ERR_REASON(X509_R_SHOULD_RETRY) , "should retry"}, - {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), "unable to find parameters in chain"}, - {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), "unable to get certs public key"}, - {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE) , "unknown key type"}, - {ERR_REASON(X509_R_UNKNOWN_NID) , "unknown nid"}, - {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID) , "unknown purpose id"}, - {ERR_REASON(X509_R_UNKNOWN_TRUST_ID) , "unknown trust id"}, - {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, - {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) , "wrong lookup type"}, - {ERR_REASON(X509_R_WRONG_TYPE) , "wrong type"}, - {0, NULL} -}; - -#undef ERR_FUNC -#undef ERR_REASON -#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) -#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) - -static const ERR_STRING_DATA X509V3_str_functs[] = { - {ERR_FUNC(0xfff), "CRYPTO_internal"}, - {0, NULL} -}; - -static const ERR_STRING_DATA X509V3_str_reasons[] = { - {ERR_REASON(X509V3_R_BAD_IP_ADDRESS) , "bad ip address"}, - {ERR_REASON(X509V3_R_BAD_OBJECT) , "bad object"}, - {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) , "bn dec2bn error"}, - {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), "bn to asn1 integer error"}, - {ERR_REASON(X509V3_R_DIRNAME_ERROR) , "dirname error"}, - {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, - {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) , "duplicate zone id"}, - {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, - {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), "error creating extension"}, - {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) , "error in extension"}, - {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, - {ERR_REASON(X509V3_R_EXTENSION_EXISTS) , "extension exists"}, - {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, - {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, - {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), "extension setting not supported"}, - {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, - {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, - {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) , "illegal hex digit"}, - {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), "incorrect policy syntax tag"}, - {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, - {ERR_REASON(X509V3_R_INVALID_ASNUMBER) , "invalid asnumber"}, - {ERR_REASON(X509V3_R_INVALID_ASRANGE) , "invalid asrange"}, - {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, - {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), "invalid extension string"}, - {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, - {ERR_REASON(X509V3_R_INVALID_IPADDRESS) , "invalid ipaddress"}, - {ERR_REASON(X509V3_R_INVALID_NAME) , "invalid name"}, - {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, - {ERR_REASON(X509V3_R_INVALID_NULL_NAME) , "invalid null name"}, - {ERR_REASON(X509V3_R_INVALID_NULL_VALUE) , "invalid null value"}, - {ERR_REASON(X509V3_R_INVALID_NUMBER) , "invalid number"}, - {ERR_REASON(X509V3_R_INVALID_NUMBERS) , "invalid numbers"}, - {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), "invalid object identifier"}, - {ERR_REASON(X509V3_R_INVALID_OPTION) , "invalid option"}, - {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), "invalid policy identifier"}, - {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), "invalid proxy policy setting"}, - {ERR_REASON(X509V3_R_INVALID_PURPOSE) , "invalid purpose"}, - {ERR_REASON(X509V3_R_INVALID_SAFI) , "invalid safi"}, - {ERR_REASON(X509V3_R_INVALID_SECTION) , "invalid section"}, - {ERR_REASON(X509V3_R_INVALID_SYNTAX) , "invalid syntax"}, - {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, - {ERR_REASON(X509V3_R_MISSING_VALUE) , "missing value"}, - {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), "need organization and numbers"}, - {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) , "no config database"}, - {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, - {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS) , "no issuer details"}, - {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, - {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), "no proxy cert policy language defined"}, - {ERR_REASON(X509V3_R_NO_PUBLIC_KEY) , "no public key"}, - {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) , "no subject details"}, - {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, - {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, - {ERR_REASON(X509V3_R_OTHERNAME_ERROR) , "othername error"}, - {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), "policy language already defined"}, - {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) , "policy path length"}, - {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), "policy path length already defined"}, - {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), "policy syntax not currently supported"}, - {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), "policy when proxy language requires no policy"}, - {ERR_REASON(X509V3_R_SECTION_NOT_FOUND) , "section not found"}, - {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), "unable to get issuer details"}, - {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), "unable to get issuer keyid"}, - {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), "unknown bit string argument"}, - {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION) , "unknown extension"}, - {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, - {ERR_REASON(X509V3_R_UNKNOWN_OPTION) , "unknown option"}, - {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) , "unsupported option"}, - {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) , "unsupported type"}, - {ERR_REASON(X509V3_R_USER_TOO_LONG) , "user too long"}, - {0, NULL} -}; - -#endif - -void -ERR_load_X509_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { - ERR_load_const_strings(X509_str_functs); - ERR_load_const_strings(X509_str_reasons); - } -#endif -} -LCRYPTO_ALIAS(ERR_load_X509_strings); - - -void -ERR_load_X509V3_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { - ERR_load_const_strings(X509V3_str_functs); - ERR_load_const_strings(X509V3_str_reasons); - } -#endif -} -LCRYPTO_ALIAS(ERR_load_X509V3_strings); diff --git a/src/lib/libcrypto/x509/x509_ext.c b/src/lib/libcrypto/x509/x509_ext.c deleted file mode 100644 index f9a311feff..0000000000 --- a/src/lib/libcrypto/x509/x509_ext.c +++ /dev/null @@ -1,258 +0,0 @@ -/* $OpenBSD: x509_ext.c,v 1.18 2024/05/14 07:39:43 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include - -#include "x509_local.h" - -int -X509_CRL_get_ext_count(const X509_CRL *x) -{ - return X509v3_get_ext_count(x->crl->extensions); -} -LCRYPTO_ALIAS(X509_CRL_get_ext_count); - -int -X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) -{ - return X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos); -} -LCRYPTO_ALIAS(X509_CRL_get_ext_by_NID); - -int -X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, int lastpos) -{ - return X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos); -} -LCRYPTO_ALIAS(X509_CRL_get_ext_by_OBJ); - -int -X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) -{ - return X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos); -} -LCRYPTO_ALIAS(X509_CRL_get_ext_by_critical); - -X509_EXTENSION * -X509_CRL_get_ext(const X509_CRL *x, int loc) -{ - return X509v3_get_ext(x->crl->extensions, loc); -} -LCRYPTO_ALIAS(X509_CRL_get_ext); - -X509_EXTENSION * -X509_CRL_delete_ext(X509_CRL *x, int loc) -{ - return X509v3_delete_ext(x->crl->extensions, loc); -} -LCRYPTO_ALIAS(X509_CRL_delete_ext); - -void * -X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); -} -LCRYPTO_ALIAS(X509_CRL_get_ext_d2i); - -int -X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); -} -LCRYPTO_ALIAS(X509_CRL_add1_ext_i2d); - -int -X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) -{ - return X509v3_add_ext(&x->crl->extensions, ex, loc) != NULL; -} -LCRYPTO_ALIAS(X509_CRL_add_ext); - -int -X509_get_ext_count(const X509 *x) -{ - return X509v3_get_ext_count(x->cert_info->extensions); -} -LCRYPTO_ALIAS(X509_get_ext_count); - -int -X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) -{ - return X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos); -} -LCRYPTO_ALIAS(X509_get_ext_by_NID); - -int -X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) -{ - return X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos); -} -LCRYPTO_ALIAS(X509_get_ext_by_OBJ); - -int -X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) -{ - return X509v3_get_ext_by_critical(x->cert_info->extensions, crit, - lastpos); -} -LCRYPTO_ALIAS(X509_get_ext_by_critical); - -X509_EXTENSION * -X509_get_ext(const X509 *x, int loc) -{ - return X509v3_get_ext(x->cert_info->extensions, loc); -} -LCRYPTO_ALIAS(X509_get_ext); - -X509_EXTENSION * -X509_delete_ext(X509 *x, int loc) -{ - return X509v3_delete_ext(x->cert_info->extensions, loc); -} -LCRYPTO_ALIAS(X509_delete_ext); - -int -X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) -{ - return X509v3_add_ext(&x->cert_info->extensions, ex, loc) != NULL; -} -LCRYPTO_ALIAS(X509_add_ext); - -void * -X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); -} -LCRYPTO_ALIAS(X509_get_ext_d2i); - -int -X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags) -{ - return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, - flags); -} -LCRYPTO_ALIAS(X509_add1_ext_i2d); - -int -X509_REVOKED_get_ext_count(const X509_REVOKED *x) -{ - return X509v3_get_ext_count(x->extensions); -} -LCRYPTO_ALIAS(X509_REVOKED_get_ext_count); - -int -X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) -{ - return X509v3_get_ext_by_NID(x->extensions, nid, lastpos); -} -LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_NID); - -int -X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, - int lastpos) -{ - return X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos); -} -LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_OBJ); - -int -X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos) -{ - return X509v3_get_ext_by_critical(x->extensions, crit, lastpos); -} -LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_critical); - -X509_EXTENSION * -X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) -{ - return X509v3_get_ext(x->extensions, loc); -} -LCRYPTO_ALIAS(X509_REVOKED_get_ext); - -X509_EXTENSION * -X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) -{ - return X509v3_delete_ext(x->extensions, loc); -} -LCRYPTO_ALIAS(X509_REVOKED_delete_ext); - -int -X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) -{ - return X509v3_add_ext(&x->extensions, ex, loc) != NULL; -} -LCRYPTO_ALIAS(X509_REVOKED_add_ext); - -void * -X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->extensions, nid, crit, idx); -} -LCRYPTO_ALIAS(X509_REVOKED_get_ext_d2i); - -int -X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); -} -LCRYPTO_ALIAS(X509_REVOKED_add1_ext_i2d); diff --git a/src/lib/libcrypto/x509/x509_extku.c b/src/lib/libcrypto/x509/x509_extku.c deleted file mode 100644 index da5036a09a..0000000000 --- a/src/lib/libcrypto/x509/x509_extku.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $OpenBSD: x509_extku.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE( - const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist); - -static const X509V3_EXT_METHOD x509v3_ext_ext_key_usage = { - .ext_nid = NID_ext_key_usage, - .ext_flags = 0, - .it = &EXTENDED_KEY_USAGE_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = i2v_EXTENDED_KEY_USAGE, - .v2i = v2i_EXTENDED_KEY_USAGE, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_ext_key_usage(void) -{ - return &x509v3_ext_ext_key_usage; -} - -/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ -static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_acceptableResponses = { - .ext_nid = NID_id_pkix_OCSP_acceptableResponses, - .ext_flags = 0, - .it = &EXTENDED_KEY_USAGE_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = i2v_EXTENDED_KEY_USAGE, - .v2i = v2i_EXTENDED_KEY_USAGE, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_id_pkix_OCSP_acceptableResponses(void) -{ - return &x509v3_ext_id_pkix_OCSP_acceptableResponses; -} - -static const ASN1_TEMPLATE EXTENDED_KEY_USAGE_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "EXTENDED_KEY_USAGE", - .item = &ASN1_OBJECT_it, -}; - -const ASN1_ITEM EXTENDED_KEY_USAGE_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &EXTENDED_KEY_USAGE_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "EXTENDED_KEY_USAGE", -}; -LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_it); - - -EXTENDED_KEY_USAGE * -d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len) -{ - return (EXTENDED_KEY_USAGE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &EXTENDED_KEY_USAGE_it); -} -LCRYPTO_ALIAS(d2i_EXTENDED_KEY_USAGE); - -int -i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &EXTENDED_KEY_USAGE_it); -} -LCRYPTO_ALIAS(i2d_EXTENDED_KEY_USAGE); - -EXTENDED_KEY_USAGE * -EXTENDED_KEY_USAGE_new(void) -{ - return (EXTENDED_KEY_USAGE *)ASN1_item_new(&EXTENDED_KEY_USAGE_it); -} -LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_new); - -void -EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &EXTENDED_KEY_USAGE_it); -} -LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_free); - -static STACK_OF(CONF_VALUE) * -i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a, - STACK_OF(CONF_VALUE) *extlist) -{ - ASN1_OBJECT *obj; - EXTENDED_KEY_USAGE *eku = a; - STACK_OF(CONF_VALUE) *free_extlist = NULL; - char obj_tmp[80]; - int i; - - if (extlist == NULL) { - if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { - if ((obj = sk_ASN1_OBJECT_value(eku, i)) == NULL) - goto err; - if (!i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, obj)) - goto err; - if (!X509V3_add_value(NULL, obj_tmp, &extlist)) - goto err; - } - - return extlist; - - err: - sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); - - return NULL; -} - -static void * -v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - EXTENDED_KEY_USAGE *extku; - char *extval; - ASN1_OBJECT *objtmp; - CONF_VALUE *val; - int i; - - if (!(extku = sk_ASN1_OBJECT_new_null())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (val->value) - extval = val->value; - else - extval = val->name; - if (!(objtmp = OBJ_txt2obj(extval, 0))) { - sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); - X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - if (sk_ASN1_OBJECT_push(extku, objtmp) == 0) { - ASN1_OBJECT_free(objtmp); - sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - } - return extku; -} diff --git a/src/lib/libcrypto/x509/x509_genn.c b/src/lib/libcrypto/x509/x509_genn.c deleted file mode 100644 index 1ea7155795..0000000000 --- a/src/lib/libcrypto/x509/x509_genn.c +++ /dev/null @@ -1,541 +0,0 @@ -/* $OpenBSD: x509_genn.c,v 1.7 2024/07/08 14:47:44 beck Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - -#include - -#include -#include -#include - -static const ASN1_TEMPLATE OTHERNAME_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(OTHERNAME, type_id), - .field_name = "type_id", - .item = &ASN1_OBJECT_it, - }, - /* Maybe have a true ANY DEFINED BY later */ - { - .flags = ASN1_TFLG_EXPLICIT, - .tag = 0, - .offset = offsetof(OTHERNAME, value), - .field_name = "value", - .item = &ASN1_ANY_it, - }, -}; - -const ASN1_ITEM OTHERNAME_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = OTHERNAME_seq_tt, - .tcount = sizeof(OTHERNAME_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(OTHERNAME), - .sname = "OTHERNAME", -}; -LCRYPTO_ALIAS(OTHERNAME_it); - - -OTHERNAME * -d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len) -{ - return (OTHERNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &OTHERNAME_it); -} -LCRYPTO_ALIAS(d2i_OTHERNAME); - -int -i2d_OTHERNAME(OTHERNAME *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it); -} -LCRYPTO_ALIAS(i2d_OTHERNAME); - -OTHERNAME * -OTHERNAME_new(void) -{ - return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it); -} -LCRYPTO_ALIAS(OTHERNAME_new); - -void -OTHERNAME_free(OTHERNAME *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it); -} -LCRYPTO_ALIAS(OTHERNAME_free); - -/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */ -static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = { - { - .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(EDIPARTYNAME, nameAssigner), - .field_name = "nameAssigner", - .item = &DIRECTORYSTRING_it, - }, - { - .flags = ASN1_TFLG_EXPLICIT, - .tag = 1, - .offset = offsetof(EDIPARTYNAME, partyName), - .field_name = "partyName", - .item = &DIRECTORYSTRING_it, - }, -}; - -const ASN1_ITEM EDIPARTYNAME_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = EDIPARTYNAME_seq_tt, - .tcount = sizeof(EDIPARTYNAME_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(EDIPARTYNAME), - .sname = "EDIPARTYNAME", -}; -LCRYPTO_ALIAS(EDIPARTYNAME_it); - - -EDIPARTYNAME * -d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len) -{ - return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &EDIPARTYNAME_it); -} -LCRYPTO_ALIAS(d2i_EDIPARTYNAME); - -int -i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it); -} -LCRYPTO_ALIAS(i2d_EDIPARTYNAME); - -EDIPARTYNAME * -EDIPARTYNAME_new(void) -{ - return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it); -} -LCRYPTO_ALIAS(EDIPARTYNAME_new); - -void -EDIPARTYNAME_free(EDIPARTYNAME *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it); -} -LCRYPTO_ALIAS(EDIPARTYNAME_free); - -static const ASN1_TEMPLATE GENERAL_NAME_ch_tt[] = { - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_OTHERNAME, - .offset = offsetof(GENERAL_NAME, d.otherName), - .field_name = "d.otherName", - .item = &OTHERNAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_EMAIL, - .offset = offsetof(GENERAL_NAME, d.rfc822Name), - .field_name = "d.rfc822Name", - .item = &ASN1_IA5STRING_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_DNS, - .offset = offsetof(GENERAL_NAME, d.dNSName), - .field_name = "d.dNSName", - .item = &ASN1_IA5STRING_it, - }, - /* Don't decode this */ - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_X400, - .offset = offsetof(GENERAL_NAME, d.x400Address), - .field_name = "d.x400Address", - .item = &ASN1_SEQUENCE_it, - }, - /* X509_NAME is a CHOICE type so use EXPLICIT */ - { - .flags = ASN1_TFLG_EXPLICIT, - .tag = GEN_DIRNAME, - .offset = offsetof(GENERAL_NAME, d.directoryName), - .field_name = "d.directoryName", - .item = &X509_NAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_EDIPARTY, - .offset = offsetof(GENERAL_NAME, d.ediPartyName), - .field_name = "d.ediPartyName", - .item = &EDIPARTYNAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_URI, - .offset = offsetof(GENERAL_NAME, d.uniformResourceIdentifier), - .field_name = "d.uniformResourceIdentifier", - .item = &ASN1_IA5STRING_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_IPADD, - .offset = offsetof(GENERAL_NAME, d.iPAddress), - .field_name = "d.iPAddress", - .item = &ASN1_OCTET_STRING_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT, - .tag = GEN_RID, - .offset = offsetof(GENERAL_NAME, d.registeredID), - .field_name = "d.registeredID", - .item = &ASN1_OBJECT_it, - }, -}; - -const ASN1_ITEM GENERAL_NAME_it = { - .itype = ASN1_ITYPE_CHOICE, - .utype = offsetof(GENERAL_NAME, type), - .templates = GENERAL_NAME_ch_tt, - .tcount = sizeof(GENERAL_NAME_ch_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(GENERAL_NAME), - .sname = "GENERAL_NAME", -}; -LCRYPTO_ALIAS(GENERAL_NAME_it); - - -GENERAL_NAME * -d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len) -{ - return (GENERAL_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &GENERAL_NAME_it); -} -LCRYPTO_ALIAS(d2i_GENERAL_NAME); - -int -i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it); -} -LCRYPTO_ALIAS(i2d_GENERAL_NAME); - -GENERAL_NAME * -GENERAL_NAME_new(void) -{ - return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it); -} -LCRYPTO_ALIAS(GENERAL_NAME_new); - -void -GENERAL_NAME_free(GENERAL_NAME *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it); -} -LCRYPTO_ALIAS(GENERAL_NAME_free); - -static const ASN1_TEMPLATE GENERAL_NAMES_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "GeneralNames", - .item = &GENERAL_NAME_it, -}; - -const ASN1_ITEM GENERAL_NAMES_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &GENERAL_NAMES_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "GENERAL_NAMES", -}; -LCRYPTO_ALIAS(GENERAL_NAMES_it); - - -GENERAL_NAMES * -d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len) -{ - return (GENERAL_NAMES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &GENERAL_NAMES_it); -} -LCRYPTO_ALIAS(d2i_GENERAL_NAMES); - -int -i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it); -} -LCRYPTO_ALIAS(i2d_GENERAL_NAMES); - -GENERAL_NAMES * -GENERAL_NAMES_new(void) -{ - return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it); -} -LCRYPTO_ALIAS(GENERAL_NAMES_new); - -void -GENERAL_NAMES_free(GENERAL_NAMES *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it); -} -LCRYPTO_ALIAS(GENERAL_NAMES_free); - -GENERAL_NAME * -GENERAL_NAME_dup(GENERAL_NAME *a) -{ - return ASN1_item_dup(&GENERAL_NAME_it, a); -} -LCRYPTO_ALIAS(GENERAL_NAME_dup); - -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) -{ - int result = -1; - - if (!a || !b || a->type != b->type) - return -1; - switch (a->type) { - case GEN_X400: - result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); - break; - - case GEN_EDIPARTY: - result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName); - break; - - case GEN_OTHERNAME: - result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); - break; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); - break; - - case GEN_DIRNAME: - result = X509_NAME_cmp(a->d.dirn, b->d.dirn); - break; - - case GEN_IPADD: - result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); - break; - - case GEN_RID: - result = OBJ_cmp(a->d.rid, b->d.rid); - break; - } - return result; -} -LCRYPTO_ALIAS(GENERAL_NAME_cmp); - -/* Returns 0 if they are equal, != 0 otherwise. */ -int -OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) -{ - int result = -1; - - if (!a || !b) - return -1; - /* Check their type first. */ - if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) - return result; - /* Check the value. */ - result = ASN1_TYPE_cmp(a->value, b->value); - return result; -} -LCRYPTO_ALIAS(OTHERNAME_cmp); - -void -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.ediPartyName = value; - break; - - case GEN_OTHERNAME: - a->d.otherName = value; - break; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - a->d.ia5 = value; - break; - - case GEN_DIRNAME: - a->d.dirn = value; - break; - - case GEN_IPADD: - a->d.ip = value; - break; - - case GEN_RID: - a->d.rid = value; - break; - } - a->type = type; -} -LCRYPTO_ALIAS(GENERAL_NAME_set0_value); - -void * -GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) -{ - if (ptype) - *ptype = a->type; - switch (a->type) { - case GEN_X400: - return a->d.x400Address; - - case GEN_EDIPARTY: - return a->d.ediPartyName; - - case GEN_OTHERNAME: - return a->d.otherName; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - return a->d.ia5; - - case GEN_DIRNAME: - return a->d.dirn; - - case GEN_IPADD: - return a->d.ip; - - case GEN_RID: - return a->d.rid; - - default: - return NULL; - } -} -LCRYPTO_ALIAS(GENERAL_NAME_get0_value); - -int -GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid, - ASN1_TYPE *value) -{ - OTHERNAME *oth; - - oth = OTHERNAME_new(); - if (!oth) - return 0; - oth->type_id = oid; - oth->value = value; - GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); - return 1; -} -LCRYPTO_ALIAS(GENERAL_NAME_set0_othername); - -int -GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, ASN1_OBJECT **poid, - ASN1_TYPE **pvalue) -{ - if (gen->type != GEN_OTHERNAME) - return 0; - if (poid) - *poid = gen->d.otherName->type_id; - if (pvalue) - *pvalue = gen->d.otherName->value; - return 1; -} -LCRYPTO_ALIAS(GENERAL_NAME_get0_otherName); diff --git a/src/lib/libcrypto/x509/x509_ia5.c b/src/lib/libcrypto/x509/x509_ia5.c deleted file mode 100644 index 4f62a9134c..0000000000 --- a/src/lib/libcrypto/x509/x509_ia5.c +++ /dev/null @@ -1,268 +0,0 @@ -/* $OpenBSD: x509_ia5.c,v 1.2 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include - -static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); -static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); - -static const X509V3_EXT_METHOD x509v3_ext_netscape_base_url = { - .ext_nid = NID_netscape_base_url, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_base_url(void) -{ - return &x509v3_ext_netscape_base_url; -} - -static const X509V3_EXT_METHOD x509v3_ext_netscape_revocation_url = { - .ext_nid = NID_netscape_revocation_url, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_revocation_url(void) -{ - return &x509v3_ext_netscape_revocation_url; -} - -static const X509V3_EXT_METHOD x509v3_ext_netscape_ca_revocation_url = { - .ext_nid = NID_netscape_ca_revocation_url, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_ca_revocation_url(void) -{ - return &x509v3_ext_netscape_ca_revocation_url; -} - -static const X509V3_EXT_METHOD x509v3_ext_netscape_renewal_url = { - .ext_nid = NID_netscape_renewal_url, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_renewal_url(void) -{ - return &x509v3_ext_netscape_renewal_url; -} - -static const X509V3_EXT_METHOD x509v3_ext_netscape_ca_policy_url = { - .ext_nid = NID_netscape_ca_policy_url, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_ca_policy_url(void) -{ - return &x509v3_ext_netscape_ca_policy_url; -} - -static const X509V3_EXT_METHOD x509v3_ext_netscape_ssl_server_name = { - .ext_nid = NID_netscape_ssl_server_name, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_ssl_server_name(void) -{ - return &x509v3_ext_netscape_ssl_server_name; -} - -static const X509V3_EXT_METHOD x509v3_ext_netscape_comment = { - .ext_nid = NID_netscape_comment, - .ext_flags = 0, - .it = &ASN1_IA5STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, - .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_netscape_comment(void) -{ - return &x509v3_ext_netscape_comment; -} - -static char * -i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5) -{ - char *tmp; - - if (!ia5 || !ia5->length) - return NULL; - if (!(tmp = malloc(ia5->length + 1))) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - memcpy(tmp, ia5->data, ia5->length); - tmp[ia5->length] = 0; - return tmp; -} - -static ASN1_IA5STRING * -s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) -{ - ASN1_IA5STRING *ia5; - if (!str) { - X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); - return NULL; - } - if (!(ia5 = ASN1_IA5STRING_new())) - goto err; - if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str, - strlen(str))) { - ASN1_IA5STRING_free(ia5); - goto err; - } - return ia5; - -err: - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; -} diff --git a/src/lib/libcrypto/x509/x509_info.c b/src/lib/libcrypto/x509/x509_info.c deleted file mode 100644 index d1de346ee6..0000000000 --- a/src/lib/libcrypto/x509/x509_info.c +++ /dev/null @@ -1,331 +0,0 @@ -/* $OpenBSD: x509_info.c,v 1.5 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( - X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, - STACK_OF(CONF_VALUE) *ret); -static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS( - X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); - -static const X509V3_EXT_METHOD x509v3_ext_info_access = { - .ext_nid = NID_info_access, - .ext_flags = X509V3_EXT_MULTILINE, - .it = &AUTHORITY_INFO_ACCESS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, - .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_info_access(void) -{ - return &x509v3_ext_info_access; -} - -static const X509V3_EXT_METHOD x509v3_ext_sinfo_access = { - .ext_nid = NID_sinfo_access, - .ext_flags = X509V3_EXT_MULTILINE, - .it = &AUTHORITY_INFO_ACCESS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, - .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_sinfo_access(void) -{ - return &x509v3_ext_sinfo_access; -} - -static const ASN1_TEMPLATE ACCESS_DESCRIPTION_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(ACCESS_DESCRIPTION, method), - .field_name = "method", - .item = &ASN1_OBJECT_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(ACCESS_DESCRIPTION, location), - .field_name = "location", - .item = &GENERAL_NAME_it, - }, -}; - -const ASN1_ITEM ACCESS_DESCRIPTION_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = ACCESS_DESCRIPTION_seq_tt, - .tcount = sizeof(ACCESS_DESCRIPTION_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(ACCESS_DESCRIPTION), - .sname = "ACCESS_DESCRIPTION", -}; -LCRYPTO_ALIAS(ACCESS_DESCRIPTION_it); - - -ACCESS_DESCRIPTION * -d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len) -{ - return (ACCESS_DESCRIPTION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ACCESS_DESCRIPTION_it); -} -LCRYPTO_ALIAS(d2i_ACCESS_DESCRIPTION); - -int -i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ACCESS_DESCRIPTION_it); -} -LCRYPTO_ALIAS(i2d_ACCESS_DESCRIPTION); - -ACCESS_DESCRIPTION * -ACCESS_DESCRIPTION_new(void) -{ - return (ACCESS_DESCRIPTION *)ASN1_item_new(&ACCESS_DESCRIPTION_it); -} -LCRYPTO_ALIAS(ACCESS_DESCRIPTION_new); - -void -ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &ACCESS_DESCRIPTION_it); -} -LCRYPTO_ALIAS(ACCESS_DESCRIPTION_free); - -static const ASN1_TEMPLATE AUTHORITY_INFO_ACCESS_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "GeneralNames", - .item = &ACCESS_DESCRIPTION_it, -}; - -const ASN1_ITEM AUTHORITY_INFO_ACCESS_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &AUTHORITY_INFO_ACCESS_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "AUTHORITY_INFO_ACCESS", -}; -LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_it); - - -AUTHORITY_INFO_ACCESS * -d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len) -{ - return (AUTHORITY_INFO_ACCESS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &AUTHORITY_INFO_ACCESS_it); -} -LCRYPTO_ALIAS(d2i_AUTHORITY_INFO_ACCESS); - -int -i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_INFO_ACCESS_it); -} -LCRYPTO_ALIAS(i2d_AUTHORITY_INFO_ACCESS); - -AUTHORITY_INFO_ACCESS * -AUTHORITY_INFO_ACCESS_new(void) -{ - return (AUTHORITY_INFO_ACCESS *)ASN1_item_new(&AUTHORITY_INFO_ACCESS_it); -} -LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_new); - -void -AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_INFO_ACCESS_it); -} -LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_free); - -static STACK_OF(CONF_VALUE) * -i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, - AUTHORITY_INFO_ACCESS *ainfo, STACK_OF(CONF_VALUE) *ret) -{ - ACCESS_DESCRIPTION *desc; - CONF_VALUE *vtmp; - STACK_OF(CONF_VALUE) *free_ret = NULL; - char objtmp[80], *ntmp; - int i; - - if (ret == NULL) { - if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { - if ((desc = sk_ACCESS_DESCRIPTION_value(ainfo, i)) == NULL) - goto err; - if ((ret = i2v_GENERAL_NAME(method, desc->location, - ret)) == NULL) - goto err; - if ((vtmp = sk_CONF_VALUE_value(ret, i)) == NULL) - goto err; - if (!i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method)) - goto err; - if (asprintf(&ntmp, "%s - %s", objtmp, vtmp->name) == -1) { - ntmp = NULL; - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - free(vtmp->name); - vtmp->name = ntmp; - } - - return ret; - - err: - sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free); - - return NULL; -} - -static AUTHORITY_INFO_ACCESS * -v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - AUTHORITY_INFO_ACCESS *ainfo = NULL; - CONF_VALUE *cnf, ctmp; - ACCESS_DESCRIPTION *acc; - int i, objlen; - char *objtmp, *ptmp; - - if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if ((acc = ACCESS_DESCRIPTION_new()) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - if (sk_ACCESS_DESCRIPTION_push(ainfo, acc) == 0) { - ACCESS_DESCRIPTION_free(acc); - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - ptmp = strchr(cnf->name, ';'); - if (!ptmp) { - X509V3error(X509V3_R_INVALID_SYNTAX); - goto err; - } - objlen = ptmp - cnf->name; - ctmp.name = ptmp + 1; - ctmp.value = cnf->value; - if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) - goto err; - if (!(objtmp = malloc(objlen + 1))) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - strlcpy(objtmp, cnf->name, objlen + 1); - acc->method = OBJ_txt2obj(objtmp, 0); - if (!acc->method) { - X509V3error(X509V3_R_BAD_OBJECT); - ERR_asprintf_error_data("value=%s", objtmp); - free(objtmp); - goto err; - } - free(objtmp); - } - return ainfo; - -err: - sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); - return NULL; -} - -int -i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a) -{ - i2a_ASN1_OBJECT(bp, a->method); - return 2; -} -LCRYPTO_ALIAS(i2a_ACCESS_DESCRIPTION); diff --git a/src/lib/libcrypto/x509/x509_int.c b/src/lib/libcrypto/x509/x509_int.c deleted file mode 100644 index 2236bfe4c4..0000000000 --- a/src/lib/libcrypto/x509/x509_int.c +++ /dev/null @@ -1,136 +0,0 @@ -/* $OpenBSD: x509_int.c,v 1.2 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include - -static const X509V3_EXT_METHOD x509v3_ext_crl_number = { - .ext_nid = NID_crl_number, - .ext_flags = 0, - .it = &ASN1_INTEGER_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_crl_number(void) -{ - return &x509v3_ext_crl_number; -} - -static const X509V3_EXT_METHOD x509v3_ext_delta_crl = { - .ext_nid = NID_delta_crl, - .ext_flags = 0, - .it = &ASN1_INTEGER_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_delta_crl(void) -{ - return &x509v3_ext_delta_crl; -} - -static void * -s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value) -{ - return s2i_ASN1_INTEGER(meth, value); -} - -static const X509V3_EXT_METHOD x509v3_ext_inhibit_any_policy = { - .ext_nid = NID_inhibit_any_policy, - .ext_flags = 0, - .it = &ASN1_INTEGER_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - .s2i = (X509V3_EXT_S2I)s2i_asn1_int, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_inhibit_any_policy(void) -{ - return &x509v3_ext_inhibit_any_policy; -} diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h deleted file mode 100644 index 9b9980ece5..0000000000 --- a/src/lib/libcrypto/x509/x509_internal.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $OpenBSD: x509_internal.h,v 1.28 2024/05/19 07:12:50 jsg Exp $ */ -/* - * Copyright (c) 2020 Bob Beck - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef HEADER_X509_INTERNAL_H -#define HEADER_X509_INTERNAL_H - -/* Internal use only, not public API */ -#include - -#include "bytestring.h" -#include "x509_local.h" -#include "x509_verify.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 */ -#define X509_VERIFY_MAX_SIGCHECKS 256 /* Max signature checks */ - -/* - * Limit the number of names and constraints we will check in a chain - * to avoid a hostile input DOS - */ -#define X509_VERIFY_MAX_CHAIN_NAMES 512 -#define X509_VERIFY_MAX_CHAIN_CONSTRAINTS 512 - -/* - * Hold the parsed and validated result of names from a certificate. - * these typically come from a GENERALNAME, but we store the parsed - * and validated results, not the ASN1 bytes. - */ -struct x509_constraints_name { - int type; /* GEN_* types from GENERAL_NAME */ - char *name; /* Name to check */ - char *local; /* holds the local part of GEN_EMAIL */ - uint8_t *der; /* DER encoded value or NULL*/ - size_t der_len; - int af; /* INET and INET6 are supported */ - uint8_t address[32]; /* Must hold ipv6 + mask */ -}; - -struct x509_constraints_names { - struct x509_constraints_name **names; - 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 */ - time_t *check_time; /* Time for validity checks */ - int purpose; /* Cert purpose we are validating */ - size_t max_chains; /* Max chains to return */ - 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 */ -}; - -int ASN1_time_tm_clamp_notafter(struct tm *tm); - -__BEGIN_HIDDEN_DECLS - -int x509_vfy_check_id(X509_STORE_CTX *ctx); -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); -int x509v3_cache_extensions(X509 *x); -X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); - -int x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter, - time_t *out); - -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(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(CBS *cbs, int permit_ip); -int x509_constraints_valid_sandns(CBS *cbs); -int x509_constraints_domain(char *domain, size_t dlen, char *constraint, - size_t len); -int x509_constraints_parse_mailbox(CBS *candidate, - struct x509_constraints_name *name); -int x509_constraints_valid_domain_constraint(CBS *cbs); -int x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostp); -int x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, - size_t len, int *error); -int x509_constraints_extract_names(struct x509_constraints_names *names, - X509 *cert, int include_cn, int *error); -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); -int x509_vfy_check_security_level(X509_STORE_CTX *ctx); - -__END_HIDDEN_DECLS - -#endif diff --git a/src/lib/libcrypto/x509/x509_issuer_cache.c b/src/lib/libcrypto/x509/x509_issuer_cache.c deleted file mode 100644 index 070e85b0a9..0000000000 --- a/src/lib/libcrypto/x509/x509_issuer_cache.c +++ /dev/null @@ -1,193 +0,0 @@ -/* $OpenBSD: x509_issuer_cache.c,v 1.7 2023/12/30 18:26:13 tb Exp $ */ -/* - * Copyright (c) 2020 Bob Beck - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* x509_issuer_cache */ - -/* - * The issuer cache is a cache of parent and child x509 certificate - * hashes with a signature validation result. - * - * Entries should only be added to the cache with a validation result - * from checking the public key math that "parent" signed "child". - * - * Finding an entry in the cache gets us the result of a previously - * performed validation of the signature of "parent" signing for the - * validity of "child". It allows us to skip doing the public key math - * when validating a certificate chain. It does not allow us to skip - * any other steps of validation (times, names, key usage, etc.) - */ - -#include -#include - -#include "x509_issuer_cache.h" - -static int -x509_issuer_cmp(struct x509_issuer *x1, struct x509_issuer *x2) -{ - int pcmp; - if ((pcmp = memcmp(x1->parent_md, x2->parent_md, EVP_MAX_MD_SIZE)) != 0) - return pcmp; - return memcmp(x1->child_md, x2->child_md, EVP_MAX_MD_SIZE); -} - -static size_t x509_issuer_cache_count; -static size_t x509_issuer_cache_max = X509_ISSUER_CACHE_MAX; -static RB_HEAD(x509_issuer_tree, x509_issuer) x509_issuer_cache = - RB_INITIALIZER(&x509_issuer_cache); -static TAILQ_HEAD(lruqueue, x509_issuer) x509_issuer_lru = - TAILQ_HEAD_INITIALIZER(x509_issuer_lru); -static pthread_mutex_t x509_issuer_tree_mutex = PTHREAD_MUTEX_INITIALIZER; - -RB_PROTOTYPE(x509_issuer_tree, x509_issuer, entry, x509_issuer_cmp); -RB_GENERATE(x509_issuer_tree, x509_issuer, entry, x509_issuer_cmp); - -/* - * Set the maximum number of cached entries. On additions to the cache - * the least recently used entries will be discarded so that the cache - * stays under the maximum number of entries. Setting a maximum of 0 - * disables the cache. - */ -int -x509_issuer_cache_set_max(size_t max) -{ - if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) - return 0; - x509_issuer_cache_max = max; - (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); - - return 1; -} - -/* - * Free the oldest entry in the issuer cache. Returns 1 - * if an entry was successfully freed, 0 otherwise. Must - * be called with x509_issuer_tree_mutex held. - */ -static void -x509_issuer_cache_free_oldest(void) -{ - struct x509_issuer *old; - - if (x509_issuer_cache_count == 0) - return; - old = TAILQ_LAST(&x509_issuer_lru, lruqueue); - TAILQ_REMOVE(&x509_issuer_lru, old, queue); - RB_REMOVE(x509_issuer_tree, &x509_issuer_cache, old); - free(old->parent_md); - free(old->child_md); - free(old); - x509_issuer_cache_count--; -} - -/* - * Free the entire issuer cache, discarding all entries. - */ -void -x509_issuer_cache_free(void) -{ - if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) - return; - while (x509_issuer_cache_count > 0) - x509_issuer_cache_free_oldest(); - (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); -} - -/* - * 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. - */ -int -x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md) -{ - struct x509_issuer candidate, *found; - int ret = -1; - - memset(&candidate, 0, sizeof(candidate)); - candidate.parent_md = parent_md; - candidate.child_md = child_md; - - if (x509_issuer_cache_max == 0) - return -1; - - if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) - return -1; - if ((found = RB_FIND(x509_issuer_tree, &x509_issuer_cache, - &candidate)) != NULL) { - TAILQ_REMOVE(&x509_issuer_lru, found, queue); - TAILQ_INSERT_HEAD(&x509_issuer_lru, found, queue); - ret = found->valid; - } - (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); - - return ret; -} - -/* - * Attempt to add a validation result to the cache. - * - * valid must be: - * 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. - */ -void -x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md, - int valid) -{ - struct x509_issuer *new; - - if (x509_issuer_cache_max == 0) - return; - if (valid != 0 && valid != 1) - return; - - if ((new = calloc(1, sizeof(struct x509_issuer))) == NULL) - return; - if ((new->parent_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL) - goto err; - memcpy(new->parent_md, parent_md, EVP_MAX_MD_SIZE); - if ((new->child_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL) - goto err; - memcpy(new->child_md, child_md, EVP_MAX_MD_SIZE); - - new->valid = valid; - - if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0) - goto err; - while (x509_issuer_cache_count >= x509_issuer_cache_max) - x509_issuer_cache_free_oldest(); - if (RB_INSERT(x509_issuer_tree, &x509_issuer_cache, new) == NULL) { - TAILQ_INSERT_HEAD(&x509_issuer_lru, new, queue); - x509_issuer_cache_count++; - new = NULL; - } - (void) pthread_mutex_unlock(&x509_issuer_tree_mutex); - - err: - if (new != NULL) { - free(new->parent_md); - free(new->child_md); - } - free(new); - return; -} diff --git a/src/lib/libcrypto/x509/x509_issuer_cache.h b/src/lib/libcrypto/x509/x509_issuer_cache.h deleted file mode 100644 index 00b18be0de..0000000000 --- a/src/lib/libcrypto/x509/x509_issuer_cache.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $OpenBSD: x509_issuer_cache.h,v 1.3 2023/12/30 18:06:59 tb Exp $ */ -/* - * Copyright (c) 2020 Bob Beck - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* x509_issuer_cache */ -#ifndef HEADER_X509_ISSUER_CACHE_H -#define HEADER_X509_ISSUER_CACHE_H - -#include -#include - -#include - -__BEGIN_HIDDEN_DECLS - -struct x509_issuer { - RB_ENTRY(x509_issuer) entry; - TAILQ_ENTRY(x509_issuer) queue; /* LRU of entries */ - /* parent_md and child_md must point to EVP_MAX_MD_SIZE of memory */ - unsigned char *parent_md; - unsigned char *child_md; - int valid; /* Result of signature validation. */ -}; - -#define X509_ISSUER_CACHE_MAX 40000 /* Approx 7.5 MB, entries 200 bytes */ - -int x509_issuer_cache_set_max(size_t max); -int x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md); -void x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md, - int valid); -void x509_issuer_cache_free(void); - -__END_HIDDEN_DECLS - -#endif diff --git a/src/lib/libcrypto/x509/x509_lib.c b/src/lib/libcrypto/x509/x509_lib.c deleted file mode 100644 index 6fa66ab88e..0000000000 --- a/src/lib/libcrypto/x509/x509_lib.c +++ /dev/null @@ -1,374 +0,0 @@ -/* $OpenBSD: x509_lib.c,v 1.24 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* X509 v3 extension utilities */ - -#include - -#include -#include -#include - -#include "x509_local.h" - -const X509V3_EXT_METHOD * -X509V3_EXT_get_nid(int nid) -{ - switch (nid) { - case NID_authority_key_identifier: - return x509v3_ext_method_authority_key_identifier(); - case NID_basic_constraints: - return x509v3_ext_method_basic_constraints(); - case NID_certificate_issuer: - return x509v3_ext_method_certificate_issuer(); - case NID_certificate_policies: - return x509v3_ext_method_certificate_policies(); - case NID_crl_distribution_points: - return x509v3_ext_method_crl_distribution_points(); - case NID_crl_number: - return x509v3_ext_method_crl_number(); - case NID_crl_reason: - return x509v3_ext_method_crl_reason(); -#ifndef OPENSSL_NO_CT - case NID_ct_cert_scts: - return x509v3_ext_method_ct_cert_scts(); - case NID_ct_precert_poison: - return x509v3_ext_method_ct_precert_poison(); - case NID_ct_precert_scts: - return x509v3_ext_method_ct_precert_scts(); -#endif - case NID_delta_crl: - return x509v3_ext_method_delta_crl(); - case NID_ext_key_usage: - return x509v3_ext_method_ext_key_usage(); - case NID_freshest_crl: - return x509v3_ext_method_freshest_crl(); -#ifndef OPENSSL_NO_OCSP - case NID_hold_instruction_code: - return x509v3_ext_method_hold_instruction_code(); - case NID_id_pkix_OCSP_CrlID: - return x509v3_ext_method_id_pkix_OCSP_CrlID(); - case NID_id_pkix_OCSP_Nonce: - return x509v3_ext_method_id_pkix_OCSP_Nonce(); - case NID_id_pkix_OCSP_acceptableResponses: - return x509v3_ext_method_id_pkix_OCSP_acceptableResponses(); - case NID_id_pkix_OCSP_archiveCutoff: - return x509v3_ext_method_id_pkix_OCSP_archiveCutoff(); - case NID_id_pkix_OCSP_serviceLocator: - return x509v3_ext_method_id_pkix_OCSP_serviceLocator(); -#endif - case NID_info_access: - return x509v3_ext_method_info_access(); - case NID_inhibit_any_policy: - return x509v3_ext_method_inhibit_any_policy(); - case NID_invalidity_date: - return x509v3_ext_method_invalidity_date(); - case NID_issuer_alt_name: - return x509v3_ext_method_issuer_alt_name(); - case NID_issuing_distribution_point: - return x509v3_ext_method_issuing_distribution_point(); - case NID_key_usage: - return x509v3_ext_method_key_usage(); - case NID_name_constraints: - return x509v3_ext_method_name_constraints(); - case NID_netscape_base_url: - return x509v3_ext_method_netscape_base_url(); - case NID_netscape_ca_policy_url: - return x509v3_ext_method_netscape_ca_policy_url(); - case NID_netscape_ca_revocation_url: - return x509v3_ext_method_netscape_ca_revocation_url(); - case NID_netscape_cert_type: - return x509v3_ext_method_netscape_cert_type(); - case NID_netscape_comment: - return x509v3_ext_method_netscape_comment(); - case NID_netscape_renewal_url: - return x509v3_ext_method_netscape_renewal_url(); - case NID_netscape_revocation_url: - return x509v3_ext_method_netscape_revocation_url(); - case NID_netscape_ssl_server_name: - return x509v3_ext_method_netscape_ssl_server_name(); - case NID_policy_constraints: - return x509v3_ext_method_policy_constraints(); - case NID_policy_mappings: - return x509v3_ext_method_policy_mappings(); - case NID_private_key_usage_period: - return x509v3_ext_method_private_key_usage_period(); -#ifndef OPENSSL_NO_RFC3779 - case NID_sbgp_ipAddrBlock: - return x509v3_ext_method_sbgp_ipAddrBlock(); - case NID_sbgp_autonomousSysNum: - return x509v3_ext_method_sbgp_autonomousSysNum(); -#endif - case NID_sinfo_access: - return x509v3_ext_method_sinfo_access(); - case NID_subject_alt_name: - return x509v3_ext_method_subject_alt_name(); - case NID_subject_key_identifier: - return x509v3_ext_method_subject_key_identifier(); - default: - return NULL; - } -}; -LCRYPTO_ALIAS(X509V3_EXT_get_nid); - -const X509V3_EXT_METHOD * -X509V3_EXT_get(X509_EXTENSION *ext) -{ - int nid; - - if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) - return NULL; - return X509V3_EXT_get_nid(nid); -} -LCRYPTO_ALIAS(X509V3_EXT_get); - -/* Return an extension internal structure */ - -void * -X509V3_EXT_d2i(X509_EXTENSION *ext) -{ - const X509V3_EXT_METHOD *method; - const unsigned char *p; - - if ((method = X509V3_EXT_get(ext)) == NULL) - return NULL; - p = ext->value->data; - if (method->it != NULL) - return ASN1_item_d2i(NULL, &p, ext->value->length, method->it); - return method->d2i(NULL, &p, ext->value->length); -} -LCRYPTO_ALIAS(X509V3_EXT_d2i); - -/* - * This API is only safe to call with known nid, crit != NULL and idx == NULL. - * On NULL return, crit acts as a failure indicator: crit == -1 means an - * extension of type nid was not present, crit != -1 is fatal: crit == -2 - * means multiple extensions of type nid are present; if crit is 0 or 1, this - * implies the extension was found but could not be decoded. - */ - -void * -X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x509_exts, int nid, int *crit, - int *idx) -{ - X509_EXTENSION *ext; - int lastpos = idx == NULL ? -1 : *idx; - - if (crit != NULL) - *crit = -1; - if (idx != NULL) - *idx = -1; - - /* - * Nothing to do if no extensions, unknown nid, or missing extension. - */ - - if (x509_exts == NULL) - return NULL; - if ((lastpos = X509v3_get_ext_by_NID(x509_exts, nid, lastpos)) < 0) - return NULL; - if ((ext = X509v3_get_ext(x509_exts, lastpos)) == NULL) - return NULL; - - /* - * API madness. Only check for a second extension of type nid if - * idx == NULL. Indicate this by setting *crit to -2. If idx != NULL, - * don't care and set *idx to the index of the first extension found. - */ - - if (idx == NULL && X509v3_get_ext_by_NID(x509_exts, nid, lastpos) > 0) { - if (crit != NULL) - *crit = -2; - return NULL; - } - - /* - * Another beautiful API detail: *crit will be set to 0 or 1, so if the - * extension fails to decode, we can deduce this from return value NULL - * and crit != -1. - */ - - if (crit != NULL) - *crit = X509_EXTENSION_get_critical(ext); - if (idx != NULL) - *idx = lastpos; - - return X509V3_EXT_d2i(ext); -} -LCRYPTO_ALIAS(X509V3_get_d2i); - -int -X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x509_exts, int nid, void *value, - int crit, unsigned long flags) -{ - STACK_OF(X509_EXTENSION) *exts = *x509_exts; - X509_EXTENSION *ext = NULL; - X509_EXTENSION *existing; - int extidx; - int errcode = 0; - int ret = 0; - - /* See if the extension already exists. */ - extidx = X509v3_get_ext_by_NID(*x509_exts, nid, -1); - - switch (flags & X509V3_ADD_OP_MASK) { - case X509V3_ADD_DEFAULT: - /* If the extension exists, adding another one is an error. */ - if (extidx >= 0) { - errcode = X509V3_R_EXTENSION_EXISTS; - goto err; - } - break; - case X509V3_ADD_APPEND: - /* - * XXX - Total misfeature. If the extension exists, appending - * another one will invalidate the certificate. Unfortunately - * things use this, in particular Viktor's DANE code. - */ - /* Pretend the extension didn't exist and append the new one. */ - extidx = -1; - break; - case X509V3_ADD_REPLACE: - /* Replace existing extension, otherwise append the new one. */ - break; - case X509V3_ADD_REPLACE_EXISTING: - /* Can't replace a non-existent extension. */ - if (extidx < 0) { - errcode = X509V3_R_EXTENSION_NOT_FOUND; - goto err; - } - break; - case X509V3_ADD_KEEP_EXISTING: - /* If the extension exists, there's nothing to do. */ - if (extidx >= 0) - goto done; - break; - case X509V3_ADD_DELETE: - /* Can't delete a non-existent extension. */ - if (extidx < 0) { - errcode = X509V3_R_EXTENSION_NOT_FOUND; - goto err; - } - if ((existing = sk_X509_EXTENSION_delete(*x509_exts, - extidx)) == NULL) { - ret = -1; - goto err; - } - X509_EXTENSION_free(existing); - existing = NULL; - goto done; - default: - errcode = X509V3_R_UNSUPPORTED_OPTION; /* XXX */ - ret = -1; - goto err; - } - - if ((ext = X509V3_EXT_i2d(nid, crit, value)) == NULL) { - X509V3error(X509V3_R_ERROR_CREATING_EXTENSION); - goto err; - } - - /* From here, errors are fatal. */ - ret = -1; - - /* If extension exists, replace it. */ - if (extidx >= 0) { - existing = sk_X509_EXTENSION_value(*x509_exts, extidx); - X509_EXTENSION_free(existing); - existing = NULL; - if (sk_X509_EXTENSION_set(*x509_exts, extidx, ext) == NULL) { - /* - * XXX - Can't happen. If it did happen, |existing| is - * now a freed pointer. Nothing we can do here. - */ - goto err; - } - goto done; - } - - if (exts == NULL) - exts = sk_X509_EXTENSION_new_null(); - if (exts == NULL) - goto err; - - if (!sk_X509_EXTENSION_push(exts, ext)) - goto err; - ext = NULL; - - *x509_exts = exts; - - done: - return 1; - - err: - if ((flags & X509V3_ADD_SILENT) == 0 && errcode != 0) - X509V3error(errcode); - - if (exts != *x509_exts) - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - X509_EXTENSION_free(ext); - - return ret; -} -LCRYPTO_ALIAS(X509V3_add1_i2d); - -int -X509V3_add_standard_extensions(void) -{ - return 1; -} -LCRYPTO_ALIAS(X509V3_add_standard_extensions); diff --git a/src/lib/libcrypto/x509/x509_local.h b/src/lib/libcrypto/x509/x509_local.h deleted file mode 100644 index 796a2ee718..0000000000 --- a/src/lib/libcrypto/x509/x509_local.h +++ /dev/null @@ -1,503 +0,0 @@ -/* $OpenBSD: x509_local.h,v 1.38 2025/03/06 07:20:01 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2013. - */ -/* ==================================================================== - * Copyright (c) 2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_X509_LOCAL_H -#define HEADER_X509_LOCAL_H - -#include - -#include "bytestring.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 - -#define X509_TRUST_ACCEPT_ALL -1 - -/* check_trust return codes */ -#define X509_TRUST_TRUSTED 1 -#define X509_TRUST_REJECTED 2 -#define X509_TRUST_UNTRUSTED 3 - -int X509_check_trust(X509 *x, int id, int flags); - -struct X509_val_st { - ASN1_TIME *notBefore; - ASN1_TIME *notAfter; -} /* X509_VAL */; - -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; - STACK_OF(ASN1_TYPE) *set; -} /* 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. - */ -typedef 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; - -X509_CERT_AUX *X509_CERT_AUX_new(void); -void X509_CERT_AUX_free(X509_CERT_AUX *a); -X509_CERT_AUX *d2i_X509_CERT_AUX(X509_CERT_AUX **a, const unsigned char **in, long len); -int i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **out); -extern const ASN1_ITEM X509_CERT_AUX_it; -int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); - -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 references; - CRYPTO_EX_DATA ex_data; - /* These contain copies of various extension values */ - long ex_pathlen; - unsigned long ex_flags; - unsigned long ex_kusage; - unsigned long ex_xkusage; - unsigned long ex_nscert; - ASN1_OCTET_STRING *skid; - AUTHORITY_KEYID *akid; - STACK_OF(DIST_POINT) *crldp; - STACK_OF(GENERAL_NAME) *altname; - NAME_CONSTRAINTS *nc; -#ifndef OPENSSL_NO_RFC3779 - STACK_OF(IPAddressFamily) *rfc3779_addr; - ASIdentifiers *rfc3779_asid; -#endif - unsigned char hash[X509_CERT_HASH_LEN]; - 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; -} /* 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 (*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); -} /* 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 */ - int security_level; /* 'Security level', see SP800-57. */ - STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ - STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ - unsigned int hostflags; /* Flags to control matching features */ - char *peername; /* Matching hostname in peer certificate */ - char *email; /* If not NULL email address to match */ - size_t emaillen; - unsigned char *ip; /* If not NULL IP address to match */ - size_t iplen; /* Length of IP address */ - int poisoned; -} /* 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 (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ - - CRYPTO_EX_DATA ex_data; - int references; -} /* X509_STORE */; - -/* This is the functions plus an instance of the local variables. */ -struct x509_lookup_st { - const X509_LOOKUP_METHOD *method; /* the functions */ - void *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) *trusted; /* trusted stack for use with get_issuer() */ - STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ - - 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 */ - - /* 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 */ - - 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); - -int X509_ALGOR_set_evp_md(X509_ALGOR *alg, const EVP_MD *md); -int X509_ALGOR_set0_by_nid(X509_ALGOR *alg, int nid, int parameter_type, - void *parameter_value); - -int X509_policy_check(const STACK_OF(X509) *certs, - const STACK_OF(ASN1_OBJECT) *user_policies, unsigned long flags, - X509 **out_current_cert); - -PBEPARAM *PBEPARAM_new(void); -void PBEPARAM_free(PBEPARAM *a); -PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, const unsigned char **in, long len); -int i2d_PBEPARAM(PBEPARAM *a, unsigned char **out); - -/* Password based encryption V2 structures */ -typedef struct PBE2PARAM_st { - X509_ALGOR *keyfunc; - X509_ALGOR *encryption; -} PBE2PARAM; - -PBE2PARAM *PBE2PARAM_new(void); -void PBE2PARAM_free(PBE2PARAM *a); -PBE2PARAM *d2i_PBE2PARAM(PBE2PARAM **a, const unsigned char **in, long len); -int i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **out); -extern const ASN1_ITEM PBE2PARAM_it; - -typedef struct PBKDF2PARAM_st { - /* Usually OCTET STRING but could be anything */ - ASN1_TYPE *salt; - ASN1_INTEGER *iter; - ASN1_INTEGER *keylength; - X509_ALGOR *prf; -} PBKDF2PARAM; - -PBKDF2PARAM *PBKDF2PARAM_new(void); -void PBKDF2PARAM_free(PBKDF2PARAM *a); -PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, const unsigned char **in, long len); -int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **out); -extern const ASN1_ITEM PBKDF2PARAM_it; - -int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, - const unsigned char *salt, int saltlen); -X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen); -X509_ALGOR *PKCS5_pbe_set(int alg, int iter, const unsigned char *salt, - int saltlen); -X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, - int prf_nid, int keylen); - -int X509_PURPOSE_get_by_id(int id); -int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); - -int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, - int lastpos); -int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, - const ASN1_OBJECT *obj, int lastpos); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, - X509_ATTRIBUTE *attr); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, - const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, - int nid, int type, const unsigned char *bytes, int len); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, - const char *attrname, int type, const unsigned char *bytes, int len); -void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, - const ASN1_OBJECT *obj, int lastpos, int type); - -int X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne); - -int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_add_value_uchar(const char *name, const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist); - -int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool); -int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); - -STACK_OF(CONF_VALUE) *X509V3_get0_section(X509V3_CTX *ctx, const char *section); - -const X509V3_EXT_METHOD *x509v3_ext_method_authority_key_identifier(void); -const X509V3_EXT_METHOD *x509v3_ext_method_basic_constraints(void); -const X509V3_EXT_METHOD *x509v3_ext_method_certificate_issuer(void); -const X509V3_EXT_METHOD *x509v3_ext_method_certificate_policies(void); -const X509V3_EXT_METHOD *x509v3_ext_method_crl_distribution_points(void); -const X509V3_EXT_METHOD *x509v3_ext_method_crl_number(void); -const X509V3_EXT_METHOD *x509v3_ext_method_crl_reason(void); -const X509V3_EXT_METHOD *x509v3_ext_method_ct_cert_scts(void); -const X509V3_EXT_METHOD *x509v3_ext_method_ct_precert_poison(void); -const X509V3_EXT_METHOD *x509v3_ext_method_ct_precert_scts(void); -const X509V3_EXT_METHOD *x509v3_ext_method_delta_crl(void); -const X509V3_EXT_METHOD *x509v3_ext_method_ext_key_usage(void); -const X509V3_EXT_METHOD *x509v3_ext_method_freshest_crl(void); -const X509V3_EXT_METHOD *x509v3_ext_method_hold_instruction_code(void); -const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_CrlID(void); -const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_Nonce(void); -const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_acceptableResponses(void); -const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_archiveCutoff(void); -const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_serviceLocator(void); -const X509V3_EXT_METHOD *x509v3_ext_method_info_access(void); -const X509V3_EXT_METHOD *x509v3_ext_method_inhibit_any_policy(void); -const X509V3_EXT_METHOD *x509v3_ext_method_invalidity_date(void); -const X509V3_EXT_METHOD *x509v3_ext_method_issuer_alt_name(void); -const X509V3_EXT_METHOD *x509v3_ext_method_issuing_distribution_point(void); -const X509V3_EXT_METHOD *x509v3_ext_method_key_usage(void); -const X509V3_EXT_METHOD *x509v3_ext_method_name_constraints(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_base_url(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_ca_policy_url(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_ca_revocation_url(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_cert_type(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_comment(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_renewal_url(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_revocation_url(void); -const X509V3_EXT_METHOD *x509v3_ext_method_netscape_ssl_server_name(void); -const X509V3_EXT_METHOD *x509v3_ext_method_policy_constraints(void); -const X509V3_EXT_METHOD *x509v3_ext_method_policy_mappings(void); -const X509V3_EXT_METHOD *x509v3_ext_method_private_key_usage_period(void); -const X509V3_EXT_METHOD *x509v3_ext_method_sbgp_ipAddrBlock(void); -const X509V3_EXT_METHOD *x509v3_ext_method_sbgp_autonomousSysNum(void); -const X509V3_EXT_METHOD *x509v3_ext_method_sinfo_access(void); -const X509V3_EXT_METHOD *x509v3_ext_method_subject_alt_name(void); -const X509V3_EXT_METHOD *x509v3_ext_method_subject_key_identifier(void); - -__END_HIDDEN_DECLS - -#endif /* !HEADER_X509_LOCAL_H */ diff --git a/src/lib/libcrypto/x509/x509_lu.c b/src/lib/libcrypto/x509/x509_lu.c deleted file mode 100644 index 0367794fca..0000000000 --- a/src/lib/libcrypto/x509/x509_lu.c +++ /dev/null @@ -1,883 +0,0 @@ -/* $OpenBSD: x509_lu.c,v 1.67 2025/03/09 15:20:20 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -static int X509_OBJECT_up_ref_count(X509_OBJECT *a); - -static X509_LOOKUP * -X509_LOOKUP_new(const X509_LOOKUP_METHOD *method) -{ - X509_LOOKUP *lu; - - if ((lu = calloc(1, sizeof(*lu))) == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - lu->method = method; - - if (method->new_item != NULL && !method->new_item(lu)) { - free(lu); - return NULL; - } - - return lu; -} - -void -X509_LOOKUP_free(X509_LOOKUP *ctx) -{ - if (ctx == NULL) - return; - if (ctx->method != NULL && ctx->method->free != NULL) - ctx->method->free(ctx); - free(ctx); -} -LCRYPTO_ALIAS(X509_LOOKUP_free); - -int -X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret) -{ - if (ctx->method == NULL) - return -1; - if (ctx->method->ctrl == NULL) - return 1; - return ctx->method->ctrl(ctx, cmd, argc, argl, ret); -} -LCRYPTO_ALIAS(X509_LOOKUP_ctrl); - -static int -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 0; - return ctx->method->get_by_subject(ctx, type, name, ret); -} - -static int -x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) -{ - int ret; - - if ((ret = (*a)->type - (*b)->type) != 0) - return ret; - - switch ((*a)->type) { - case X509_LU_X509: - return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); - case X509_LU_CRL: - return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); - } - return 0; -} - -X509_STORE * -X509_STORE_new(void) -{ - X509_STORE *store; - - if ((store = calloc(1, sizeof(*store))) == NULL) - goto err; - - 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; - - 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); - - return NULL; -} -LCRYPTO_ALIAS(X509_STORE_new); - -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; -} -LCRYPTO_ALIAS(X509_OBJECT_new); - -void -X509_OBJECT_free(X509_OBJECT *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); -} -LCRYPTO_ALIAS(X509_OBJECT_free); - -static X509_OBJECT * -x509_object_dup(const X509_OBJECT *obj) -{ - X509_OBJECT *copy; - - if ((copy = X509_OBJECT_new()) == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - copy->type = obj->type; - copy->data = obj->data; - - X509_OBJECT_up_ref_count(copy); - - return copy; -} - -void -X509_STORE_free(X509_STORE *store) -{ - if (store == NULL) - return; - - if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0) - return; - - sk_X509_LOOKUP_pop_free(store->get_cert_methods, X509_LOOKUP_free); - sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data); - X509_VERIFY_PARAM_free(store->param); - free(store); -} -LCRYPTO_ALIAS(X509_STORE_free); - -int -X509_STORE_up_ref(X509_STORE *store) -{ - return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1; -} -LCRYPTO_ALIAS(X509_STORE_up_ref); - -X509_LOOKUP * -X509_STORE_add_lookup(X509_STORE *store, const X509_LOOKUP_METHOD *method) -{ - STACK_OF(X509_LOOKUP) *sk; - X509_LOOKUP *lu; - int i; - - sk = store->get_cert_methods; - for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { - lu = sk_X509_LOOKUP_value(sk, i); - if (method == lu->method) { - return lu; - } - } - - 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; - } - - return lu; -} -LCRYPTO_ALIAS(X509_STORE_add_lookup); - -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; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_obj_by_subject); - -int -X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret) -{ - X509_STORE *ctx = vs->store; - X509_LOOKUP *lu; - X509_OBJECT stmp, *tmp; - 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 = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { - lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); - if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) { - tmp = &stmp; - break; - } - } - if (tmp == NULL) - return 0; - } - - if (!X509_OBJECT_up_ref_count(tmp)) - return 0; - - *ret = *tmp; - - return 1; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_by_subject); - -/* 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 *store, X509 *x) -{ - X509_OBJECT *obj; - - if (x == NULL) - return 0; - - 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; - - return X509_STORE_add_object(store, obj); -} -LCRYPTO_ALIAS(X509_STORE_add_cert); - -int -X509_STORE_add_crl(X509_STORE *store, X509_CRL *x) -{ - X509_OBJECT *obj; - - if (x == NULL) - return 0; - - 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; - - return X509_STORE_add_object(store, obj); -} -LCRYPTO_ALIAS(X509_STORE_add_crl); - -static int -X509_OBJECT_up_ref_count(X509_OBJECT *a) -{ - switch (a->type) { - case X509_LU_X509: - return X509_up_ref(a->data.x509); - case X509_LU_CRL: - return X509_CRL_up_ref(a->data.crl); - } - return 1; -} - -X509_LOOKUP_TYPE -X509_OBJECT_get_type(const X509_OBJECT *a) -{ - return a->type; -} -LCRYPTO_ALIAS(X509_OBJECT_get_type); - -static int -x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, - X509_NAME *name, int *pnmatch) -{ - X509_OBJECT stmp; - X509 x509_s; - X509_CINF cinf_s; - X509_CRL crl_s; - X509_CRL_INFO crl_info_s; - int idx; - - stmp.type = type; - switch (type) { - case X509_LU_X509: - stmp.data.x509 = &x509_s; - x509_s.cert_info = &cinf_s; - cinf_s.subject = name; - break; - case X509_LU_CRL: - stmp.data.crl = &crl_s; - crl_s.crl = &crl_info_s; - crl_info_s.issuer = name; - break; - default: - return -1; - } - - idx = sk_X509_OBJECT_find(h, &stmp); - 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++) { - tobj = sk_X509_OBJECT_value(h, tidx); - if (x509_object_cmp(&tobj, &pstmp)) - break; - (*pnmatch)++; - } - } - return idx; -} - -int -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); -} -LCRYPTO_ALIAS(X509_OBJECT_idx_by_subject); - -X509_OBJECT * -X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, - X509_NAME *name) -{ - int idx; - - idx = X509_OBJECT_idx_by_subject(h, type, name); - if (idx == -1) - return NULL; - return sk_X509_OBJECT_value(h, idx); -} -LCRYPTO_ALIAS(X509_OBJECT_retrieve_by_subject); - -X509 * -X509_OBJECT_get0_X509(const X509_OBJECT *xo) -{ - if (xo != NULL && xo->type == X509_LU_X509) - return xo->data.x509; - return NULL; -} -LCRYPTO_ALIAS(X509_OBJECT_get0_X509); - -X509_CRL * -X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo) -{ - if (xo != NULL && xo->type == X509_LU_CRL) - return xo->data.crl; - return NULL; -} -LCRYPTO_ALIAS(X509_OBJECT_get0_X509_CRL); - -static STACK_OF(X509) * -X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name) -{ - STACK_OF(X509) *sk = NULL; - X509 *x = NULL; - X509_OBJECT *obj; - int i, idx, cnt; - - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - - 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(store->objs, idx); - - x = obj->data.x509; - 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_CTX_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); -} -LCRYPTO_ALIAS(X509_STORE_CTX_get1_certs); - -STACK_OF(X509_CRL) * -X509_STORE_CTX_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; - - if (store == NULL) - return NULL; - - /* 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(obj); - obj = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - 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(store->objs, idx); - - x = obj->data.crl; - 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; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get1_crls); - -X509_OBJECT * -X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) -{ - int idx, i; - X509_OBJECT *obj; - - idx = sk_X509_OBJECT_find(h, x); - if (idx == -1) - return NULL; - if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) - return sk_X509_OBJECT_value(h, idx); - for (i = idx; i < sk_X509_OBJECT_num(h); i++) { - obj = sk_X509_OBJECT_value(h, i); - if (x509_object_cmp((const X509_OBJECT **)&obj, - (const X509_OBJECT **)&x)) - return NULL; - if (x->type == X509_LU_X509) { - if (!X509_cmp(obj->data.x509, x->data.x509)) - return obj; - } else if (x->type == X509_LU_CRL) { - if (!X509_CRL_match(obj->data.crl, x->data.crl)) - return obj; - } else - return obj; - } - return NULL; -} -LCRYPTO_ALIAS(X509_OBJECT_retrieve_match); - -/* Try to get issuer certificate from store. Due to limitations - * of the API this can only retrieve a single certificate matching - * a given subject name. However it will fill the cache with all - * matching certificates, so we can examine the cache for all - * matches. - * - * Return values are: - * 1 lookup successful. - * 0 certificate not found. - * -1 some other error. - */ -int -X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x) -{ - X509_NAME *xn; - X509_OBJECT *obj, *pobj; - X509 *issuer = NULL; - int i, idx, ret; - - *out_issuer = NULL; - - xn = X509_get_issuer_name(x); - 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, issuer)) { - if (x509_check_cert_time(ctx, issuer, -1)) { - *out_issuer = issuer; - X509_OBJECT_free(obj); - return 1; - } - } - 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' */ - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - 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->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; - if (X509_NAME_cmp(xn, - X509_get_subject_name(pobj->data.x509))) - break; - if (ctx->check_issued(ctx, x, pobj->data.x509)) { - 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)) - 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); - return ret; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get1_issuer); - -STACK_OF(X509_OBJECT) * -X509_STORE_get0_objects(X509_STORE *xs) -{ - return xs->objs; -} -LCRYPTO_ALIAS(X509_STORE_get0_objects); - -static STACK_OF(X509_OBJECT) * -sk_X509_OBJECT_deep_copy(const STACK_OF(X509_OBJECT) *objs) -{ - STACK_OF(X509_OBJECT) *copy = NULL; - X509_OBJECT *obj = NULL; - int i; - - if ((copy = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - goto err; - } - - for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { - if ((obj = x509_object_dup(sk_X509_OBJECT_value(objs, i))) == NULL) - goto err; - if (!sk_X509_OBJECT_push(copy, obj)) - goto err; - obj = NULL; - } - - return copy; - - err: - X509_OBJECT_free(obj); - sk_X509_OBJECT_pop_free(copy, X509_OBJECT_free); - - return NULL; -} - -STACK_OF(X509_OBJECT) * -X509_STORE_get1_objects(X509_STORE *store) -{ - STACK_OF(X509_OBJECT) *objs; - - if (store == NULL) { - X509error(ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); - objs = sk_X509_OBJECT_deep_copy(store->objs); - CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); - - return objs; -} -LCRYPTO_ALIAS(X509_STORE_get1_objects); - -void * -X509_STORE_get_ex_data(X509_STORE *xs, int idx) -{ - return CRYPTO_get_ex_data(&xs->ex_data, idx); -} -LCRYPTO_ALIAS(X509_STORE_get_ex_data); - -int -X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data) -{ - return CRYPTO_set_ex_data(&xs->ex_data, idx, data); -} -LCRYPTO_ALIAS(X509_STORE_set_ex_data); - -int -X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) -{ - return X509_VERIFY_PARAM_set_flags(ctx->param, flags); -} -LCRYPTO_ALIAS(X509_STORE_set_flags); - -int -X509_STORE_set_depth(X509_STORE *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); - return 1; -} -LCRYPTO_ALIAS(X509_STORE_set_depth); - -int -X509_STORE_set_purpose(X509_STORE *ctx, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); -} -LCRYPTO_ALIAS(X509_STORE_set_purpose); - -int -X509_STORE_set_trust(X509_STORE *ctx, int trust) -{ - return X509_VERIFY_PARAM_set_trust(ctx->param, trust); -} -LCRYPTO_ALIAS(X509_STORE_set_trust); - -int -X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) -{ - return X509_VERIFY_PARAM_set1(ctx->param, param); -} -LCRYPTO_ALIAS(X509_STORE_set1_param); - -X509_VERIFY_PARAM * -X509_STORE_get0_param(X509_STORE *ctx) -{ - return ctx->param; -} -LCRYPTO_ALIAS(X509_STORE_get0_param); - -void -X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify) -{ - store->verify = verify; -} -LCRYPTO_ALIAS(X509_STORE_set_verify); - -X509_STORE_CTX_verify_fn -X509_STORE_get_verify(X509_STORE *store) -{ - return store->verify; -} -LCRYPTO_ALIAS(X509_STORE_get_verify); - -void -X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb) -{ - store->verify_cb = verify_cb; -} -LCRYPTO_ALIAS(X509_STORE_set_verify_cb); - -X509_STORE_CTX_verify_cb -X509_STORE_get_verify_cb(X509_STORE *store) -{ - return store->verify_cb; -} -LCRYPTO_ALIAS(X509_STORE_get_verify_cb); diff --git a/src/lib/libcrypto/x509/x509_ncons.c b/src/lib/libcrypto/x509/x509_ncons.c deleted file mode 100644 index 148a66e887..0000000000 --- a/src/lib/libcrypto/x509/x509_ncons.c +++ /dev/null @@ -1,569 +0,0 @@ -/* $OpenBSD: x509_ncons.c,v 1.11 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include - -#include "x509_local.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, - void *a, BIO *bp, int ind); -static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name); -static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); - -static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); -static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); -static int nc_dn(X509_NAME *sub, X509_NAME *nm); -static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); -static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); -static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); - -static const X509V3_EXT_METHOD x509v3_ext_name_constraints = { - .ext_nid = NID_name_constraints, - .ext_flags = 0, - .it = &NAME_CONSTRAINTS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = v2i_NAME_CONSTRAINTS, - .i2r = i2r_NAME_CONSTRAINTS, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_name_constraints(void) -{ - return &x509v3_ext_name_constraints; -} - -static const ASN1_TEMPLATE GENERAL_SUBTREE_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(GENERAL_SUBTREE, base), - .field_name = "base", - .item = &GENERAL_NAME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(GENERAL_SUBTREE, minimum), - .field_name = "minimum", - .item = &ASN1_INTEGER_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(GENERAL_SUBTREE, maximum), - .field_name = "maximum", - .item = &ASN1_INTEGER_it, - }, -}; - -const ASN1_ITEM GENERAL_SUBTREE_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = GENERAL_SUBTREE_seq_tt, - .tcount = sizeof(GENERAL_SUBTREE_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(GENERAL_SUBTREE), - .sname = "GENERAL_SUBTREE", -}; -LCRYPTO_ALIAS(GENERAL_SUBTREE_it); - -static const ASN1_TEMPLATE NAME_CONSTRAINTS_seq_tt[] = { - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(NAME_CONSTRAINTS, permittedSubtrees), - .field_name = "permittedSubtrees", - .item = &GENERAL_SUBTREE_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(NAME_CONSTRAINTS, excludedSubtrees), - .field_name = "excludedSubtrees", - .item = &GENERAL_SUBTREE_it, - }, -}; - -const ASN1_ITEM NAME_CONSTRAINTS_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = NAME_CONSTRAINTS_seq_tt, - .tcount = sizeof(NAME_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(NAME_CONSTRAINTS), - .sname = "NAME_CONSTRAINTS", -}; -LCRYPTO_ALIAS(NAME_CONSTRAINTS_it); - - -GENERAL_SUBTREE * -GENERAL_SUBTREE_new(void) -{ - return (GENERAL_SUBTREE*)ASN1_item_new(&GENERAL_SUBTREE_it); -} -LCRYPTO_ALIAS(GENERAL_SUBTREE_new); - -void -GENERAL_SUBTREE_free(GENERAL_SUBTREE *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &GENERAL_SUBTREE_it); -} -LCRYPTO_ALIAS(GENERAL_SUBTREE_free); - -NAME_CONSTRAINTS * -NAME_CONSTRAINTS_new(void) -{ - return (NAME_CONSTRAINTS*)ASN1_item_new(&NAME_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(NAME_CONSTRAINTS_new); - -void -NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &NAME_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(NAME_CONSTRAINTS_free); - -static void * -v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - int i; - CONF_VALUE tval, *val; - STACK_OF(GENERAL_SUBTREE) **ptree = NULL; - NAME_CONSTRAINTS *ncons = NULL; - GENERAL_SUBTREE *sub = NULL; - - ncons = NAME_CONSTRAINTS_new(); - if (!ncons) - goto memerr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!strncmp(val->name, "permitted", 9) && val->name[9]) { - ptree = &ncons->permittedSubtrees; - tval.name = val->name + 10; - } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { - ptree = &ncons->excludedSubtrees; - tval.name = val->name + 9; - } else { - X509V3error(X509V3_R_INVALID_SYNTAX); - goto err; - } - tval.value = val->value; - sub = GENERAL_SUBTREE_new(); - if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) - goto err; - if (!*ptree) - *ptree = sk_GENERAL_SUBTREE_new_null(); - if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) - goto memerr; - sub = NULL; - } - - return ncons; - -memerr: - X509V3error(ERR_R_MALLOC_FAILURE); -err: - NAME_CONSTRAINTS_free(ncons); - GENERAL_SUBTREE_free(sub); - return NULL; -} - -static int -i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind) -{ - NAME_CONSTRAINTS *ncons = a; - - do_i2r_name_constraints(method, ncons->permittedSubtrees, - bp, ind, "Permitted"); - do_i2r_name_constraints(method, ncons->excludedSubtrees, - bp, ind, "Excluded"); - return 1; -} - -static int -do_i2r_name_constraints(const X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name) -{ - GENERAL_SUBTREE *tree; - int i; - - if (sk_GENERAL_SUBTREE_num(trees) > 0) - BIO_printf(bp, "%*s%s:\n", ind, "", name); - for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { - tree = sk_GENERAL_SUBTREE_value(trees, i); - BIO_printf(bp, "%*s", ind + 2, ""); - if (tree->base->type == GEN_IPADD) - print_nc_ipadd(bp, tree->base->d.ip); - else - GENERAL_NAME_print(bp, tree->base); - BIO_puts(bp, "\n"); - } - return 1; -} - -static int -print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) -{ - int i, len; - unsigned char *p; - - p = ip->data; - len = ip->length; - BIO_puts(bp, "IP:"); - if (len == 8) { - BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - } else if (len == 32) { - for (i = 0; i < 16; i++) { - BIO_printf(bp, "%X", p[0] << 8 | p[1]); - p += 2; - if (i == 7) - BIO_puts(bp, "/"); - else if (i != 15) - BIO_puts(bp, ":"); - } - } else - BIO_printf(bp, "IP Address:"); - return 1; -} - -/* Check a certificate conforms to a specified set of constraints. - * Return values: - * X509_V_OK: All constraints obeyed. - * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. - * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. - * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. - * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. - * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. - * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name - */ - -int -NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) -{ - int r, i; - X509_NAME *nm; - - nm = X509_get_subject_name(x); - - if (X509_NAME_entry_count(nm) > 0) { - GENERAL_NAME gntmp; - gntmp.type = GEN_DIRNAME; - gntmp.d.directoryName = nm; - - r = nc_match(&gntmp, nc); - - if (r != X509_V_OK) - return r; - - gntmp.type = GEN_EMAIL; - - /* Process any email address attributes in subject name */ - - for (i = -1;;) { - X509_NAME_ENTRY *ne; - i = X509_NAME_get_index_by_NID(nm, - NID_pkcs9_emailAddress, i); - if (i == -1) - break; - ne = X509_NAME_get_entry(nm, i); - gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); - if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - - r = nc_match(&gntmp, nc); - - if (r != X509_V_OK) - return r; - } - - } - - for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); - r = nc_match(gen, nc); - if (r != X509_V_OK) - return r; - } - return X509_V_OK; -} -LCRYPTO_ALIAS(NAME_CONSTRAINTS_check); -static int -nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) -{ - GENERAL_SUBTREE *sub; - int i, r, match = 0; - - /* Permitted subtrees: if any subtrees exist of matching the type - * at least one subtree must match. - */ - - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { - sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); - if (gen->type != sub->base->type) - continue; - if (sub->minimum || sub->maximum) - return X509_V_ERR_SUBTREE_MINMAX; - /* If we already have a match don't bother trying any more */ - if (match == 2) - continue; - if (match == 0) - match = 1; - r = nc_match_single(gen, sub->base); - if (r == X509_V_OK) - match = 2; - else if (r != X509_V_ERR_PERMITTED_VIOLATION) - return r; - } - - if (match == 1) - return X509_V_ERR_PERMITTED_VIOLATION; - - /* Excluded subtrees: must not match any of these */ - - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { - sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); - if (gen->type != sub->base->type) - continue; - if (sub->minimum || sub->maximum) - return X509_V_ERR_SUBTREE_MINMAX; - - r = nc_match_single(gen, sub->base); - if (r == X509_V_OK) - return X509_V_ERR_EXCLUDED_VIOLATION; - else if (r != X509_V_ERR_PERMITTED_VIOLATION) - return r; - - } - - return X509_V_OK; -} - -static int -nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) -{ - switch (base->type) { - case GEN_DIRNAME: - return nc_dn(gen->d.directoryName, base->d.directoryName); - - case GEN_DNS: - return nc_dns(gen->d.dNSName, base->d.dNSName); - - case GEN_EMAIL: - return nc_email(gen->d.rfc822Name, base->d.rfc822Name); - - case GEN_URI: - return nc_uri(gen->d.uniformResourceIdentifier, - base->d.uniformResourceIdentifier); - - default: - return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; - } -} - -/* directoryName name constraint matching. - * The canonical encoding of X509_NAME makes this comparison easy. It is - * matched if the subtree is a subset of the name. - */ - -static int -nc_dn(X509_NAME *nm, X509_NAME *base) -{ - /* Ensure canonical encodings are up to date. */ - if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) - return X509_V_ERR_OUT_OF_MEM; - if (base->modified && i2d_X509_NAME(base, NULL) < 0) - return X509_V_ERR_OUT_OF_MEM; - if (base->canon_enclen > nm->canon_enclen) - return X509_V_ERR_PERMITTED_VIOLATION; - if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) - return X509_V_ERR_PERMITTED_VIOLATION; - return X509_V_OK; -} - -static int -nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) -{ - char *baseptr = (char *)base->data; - char *dnsptr = (char *)dns->data; - - /* Empty matches everything */ - if (!*baseptr) - return X509_V_OK; - /* Otherwise can add zero or more components on the left so - * compare RHS and if dns is longer and expect '.' as preceding - * character. - */ - if (dns->length > base->length) { - dnsptr += dns->length - base->length; - if (baseptr[0] != '.' && dnsptr[-1] != '.') - return X509_V_ERR_PERMITTED_VIOLATION; - } - - if (strcasecmp(baseptr, dnsptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - - return X509_V_OK; -} - -static int -nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) -{ - const char *baseptr = (char *)base->data; - const char *emlptr = (char *)eml->data; - const char *baseat = strchr(baseptr, '@'); - const char *emlat = strchr(emlptr, '@'); - - if (!emlat) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - /* Special case: initial '.' is RHS match */ - if (!baseat && (*baseptr == '.')) { - if (eml->length > base->length) { - emlptr += eml->length - base->length; - if (!strcasecmp(baseptr, emlptr)) - return X509_V_OK; - } - return X509_V_ERR_PERMITTED_VIOLATION; - } - - /* If we have anything before '@' match local part */ - - if (baseat) { - if (baseat != baseptr) { - if ((baseat - baseptr) != (emlat - emlptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - /* Case sensitive match of local part */ - if (strncmp(baseptr, emlptr, emlat - emlptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - } - /* Position base after '@' */ - baseptr = baseat + 1; - } - emlptr = emlat + 1; - /* Just have hostname left to match: case insensitive */ - if (strcasecmp(baseptr, emlptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - - return X509_V_OK; -} - -static int -nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) -{ - const char *baseptr = (char *)base->data; - const char *hostptr = (char *)uri->data; - const char *p = strchr(hostptr, ':'); - int hostlen; - - /* Check for foo:// and skip past it */ - if (!p || (p[1] != '/') || (p[2] != '/')) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - hostptr = p + 3; - - /* Determine length of hostname part of URI */ - - /* Look for a port indicator as end of hostname first */ - - p = strchr(hostptr, ':'); - /* Otherwise look for trailing slash */ - if (!p) - p = strchr(hostptr, '/'); - - if (!p) - hostlen = strlen(hostptr); - else - hostlen = p - hostptr; - - if (hostlen == 0) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - - /* Special case: initial '.' is RHS match */ - if (*baseptr == '.') { - if (hostlen > base->length) { - p = hostptr + hostlen - base->length; - if (!strncasecmp(p, baseptr, base->length)) - return X509_V_OK; - } - return X509_V_ERR_PERMITTED_VIOLATION; - } - - if ((base->length != (int)hostlen) || - strncasecmp(hostptr, baseptr, hostlen)) - return X509_V_ERR_PERMITTED_VIOLATION; - - return X509_V_OK; -} diff --git a/src/lib/libcrypto/x509/x509_obj.c b/src/lib/libcrypto/x509/x509_obj.c deleted file mode 100644 index db1741cc9e..0000000000 --- a/src/lib/libcrypto/x509/x509_obj.c +++ /dev/null @@ -1,198 +0,0 @@ -/* $OpenBSD: x509_obj.c,v 1.25 2025/01/27 04:24:46 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "bytestring.h" -#include "x509_local.h" - -static int -X509_NAME_ENTRY_add_object_cbb(CBB *cbb, const ASN1_OBJECT *aobj) -{ - const char *str; - char buf[80]; - int nid; - - /* Prefer SN over LN, and fall back to textual representation of OID. */ - if ((nid = OBJ_obj2nid(aobj)) != NID_undef) { - if ((str = OBJ_nid2sn(nid)) != NULL) - return CBB_add_bytes(cbb, str, strlen(str)); - if ((str = OBJ_nid2ln(nid)) != NULL) - return CBB_add_bytes(cbb, str, strlen(str)); - } - if (OBJ_obj2txt(buf, sizeof(buf), aobj, 1) == 0) - return 0; - return CBB_add_bytes(cbb, buf, strlen(buf)); -} - -static int -X509_NAME_ENTRY_add_u8_cbb(CBB *cbb, uint8_t u8) -{ - static const char hex[] = "0123456789ABCDEF"; - - if (' ' <= u8 && u8 <= '~') - return CBB_add_u8(cbb, u8); - - if (!CBB_add_u8(cbb, '\\')) - return 0; - if (!CBB_add_u8(cbb, 'x')) - return 0; - if (!CBB_add_u8(cbb, hex[u8 >> 4])) - return 0; - if (!CBB_add_u8(cbb, hex[u8 & 0xf])) - return 0; - return 1; -} - -static int -X509_NAME_ENTRY_add_value_cbb(CBB *cbb, const ASN1_STRING *astr) -{ - CBS cbs; - uint8_t u8; - size_t i; - int mask[4] = { 1, 1, 1, 1 }; - - if (astr->type == V_ASN1_GENERALSTRING && astr->length % 4 == 0) { - int gs_mask[4] = { 0, 0, 0, 0 }; - - i = 0; - CBS_init(&cbs, astr->data, astr->length); - while (CBS_len(&cbs) > 0) { - if (!CBS_get_u8(&cbs, &u8)) - return 0; - - gs_mask[i++ & 0x3] |= u8; - } - - if (gs_mask[0] == 0 && gs_mask[1] == 0 && gs_mask[2] == 0) - mask[0] = mask[1] = mask[2] = 0; - } - - i = 0; - CBS_init(&cbs, astr->data, astr->length); - while (CBS_len(&cbs) > 0) { - if (!CBS_get_u8(&cbs, &u8)) - return 0; - if (mask[i++ & 0x3] == 0) - continue; - if (!X509_NAME_ENTRY_add_u8_cbb(cbb, u8)) - return 0; - } - - return 1; -} - -int -X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne) -{ - if (!X509_NAME_ENTRY_add_object_cbb(cbb, ne->object)) - return 0; - if (!CBB_add_u8(cbb, '=')) - return 0; - if (!X509_NAME_ENTRY_add_value_cbb(cbb, ne->value)) - return 0; - return 1; -} - -char * -X509_NAME_oneline(const X509_NAME *a, char *buf, int len) -{ - CBB cbb; - const X509_NAME_ENTRY *ne; - uint8_t *line = NULL; - size_t line_len = 0; - int i; - - if (!CBB_init(&cbb, 0)) - goto err; - - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - ne = sk_X509_NAME_ENTRY_value(a->entries, i); - if (!CBB_add_u8(&cbb, '/')) - goto err; - if (!X509_NAME_ENTRY_add_cbb(&cbb, ne)) - goto err; - } - - if (!CBB_add_u8(&cbb, '\0')) - goto err; - - if (!CBB_finish(&cbb, &line, &line_len)) - goto err; - - if (buf == NULL) - return line; - - strlcpy(buf, line, len); - free(line); - - return buf; - - err: - CBB_cleanup(&cbb); - - return NULL; -} -LCRYPTO_ALIAS(X509_NAME_oneline); diff --git a/src/lib/libcrypto/x509/x509_ocsp.c b/src/lib/libcrypto/x509/x509_ocsp.c deleted file mode 100644 index 6531b4c420..0000000000 --- a/src/lib/libcrypto/x509/x509_ocsp.c +++ /dev/null @@ -1,424 +0,0 @@ -/* $OpenBSD: x509_ocsp.c,v 1.4 2024/12/24 09:14:33 schwarze Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include - -#ifndef OPENSSL_NO_OCSP - -#include -#include -#include -#include -#include - -#include "ocsp_local.h" - -/* OCSP extensions and a couple of CRL entry extensions - */ - -static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent); -static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent); -static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, - int indent); - -static void *ocsp_nonce_new(void); -static int i2d_ocsp_nonce(void *a, unsigned char **pp); -static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); -static void ocsp_nonce_free(void *a); -static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent); - -static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, - void *nocheck, BIO *out, int indent); -static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const char *str); -static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, - BIO *bp, int ind); - -static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_CrlID = { - .ext_nid = NID_id_pkix_OCSP_CrlID, - .ext_flags = 0, - .it = &OCSP_CRLID_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_ocsp_crlid, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_id_pkix_OCSP_CrlID(void) -{ - return &x509v3_ext_id_pkix_OCSP_CrlID; -} - -static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_archiveCutoff = { - .ext_nid = NID_id_pkix_OCSP_archiveCutoff, - .ext_flags = 0, - .it = &ASN1_GENERALIZEDTIME_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_ocsp_acutoff, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_id_pkix_OCSP_archiveCutoff(void) -{ - return &x509v3_ext_id_pkix_OCSP_archiveCutoff; -} - -static const X509V3_EXT_METHOD x509v3_ext_invalidity_date = { - .ext_nid = NID_invalidity_date, - .ext_flags = 0, - .it = &ASN1_GENERALIZEDTIME_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_ocsp_acutoff, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_invalidity_date(void) -{ - return &x509v3_ext_invalidity_date; -} - -static const X509V3_EXT_METHOD x509v3_ext_hold_instruction_code = { - .ext_nid = NID_hold_instruction_code, - .ext_flags = 0, - .it = &ASN1_OBJECT_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_object, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_hold_instruction_code(void) -{ - return &x509v3_ext_hold_instruction_code; -} - -static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_Nonce = { - .ext_nid = NID_id_pkix_OCSP_Nonce, - .ext_flags = 0, - .it = NULL, - .ext_new = ocsp_nonce_new, - .ext_free = ocsp_nonce_free, - .d2i = d2i_ocsp_nonce, - .i2d = i2d_ocsp_nonce, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_ocsp_nonce, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_id_pkix_OCSP_Nonce(void) -{ - return &x509v3_ext_id_pkix_OCSP_Nonce; -} - -static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_noCheck = { - .ext_nid = NID_id_pkix_OCSP_noCheck, - .ext_flags = 0, - .it = &ASN1_NULL_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = s2i_ocsp_nocheck, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_ocsp_nocheck, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_id_pkix_OCSP_noCheck(void) -{ - return &x509v3_ext_id_pkix_OCSP_noCheck; -} - -static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_serviceLocator = { - .ext_nid = NID_id_pkix_OCSP_serviceLocator, - .ext_flags = 0, - .it = &OCSP_SERVICELOC_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = i2r_ocsp_serviceloc, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_id_pkix_OCSP_serviceLocator(void) -{ - return &x509v3_ext_id_pkix_OCSP_serviceLocator; -} - -static int -i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) -{ - OCSP_CRLID *a = in; - if (a->crlUrl) { - if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) - goto err; - if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (a->crlNum) { - if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) - goto err; - if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (a->crlTime) { - if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - return 1; - -err: - return 0; -} - -static int -i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, - int ind) -{ - if (BIO_printf(bp, "%*s", ind, "") <= 0) - return 0; - if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) - return 0; - return 1; -} - -static int -i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) -{ - if (BIO_printf(bp, "%*s", ind, "") <= 0) - return 0; - if (i2a_ASN1_OBJECT(bp, oid) <= 0) - return 0; - return 1; -} - -/* OCSP nonce. This is needs special treatment because it doesn't have - * an ASN1 encoding at all: it just contains arbitrary data. - */ - -static void * -ocsp_nonce_new(void) -{ - return ASN1_OCTET_STRING_new(); -} - -static int -i2d_ocsp_nonce(void *a, unsigned char **pp) -{ - ASN1_OCTET_STRING *os = a; - - if (pp) { - memcpy(*pp, os->data, os->length); - *pp += os->length; - } - return os->length; -} - -static void * -d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) -{ - ASN1_OCTET_STRING *os, **pos; - - pos = a; - if (pos == NULL || *pos == NULL) { - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - goto err; - } else - os = *pos; - if (ASN1_OCTET_STRING_set(os, *pp, length) == 0) - goto err; - - *pp += length; - - if (pos != NULL) - *pos = os; - return os; - -err: - if (pos == NULL || *pos != os) - ASN1_OCTET_STRING_free(os); - OCSPerror(ERR_R_MALLOC_FAILURE); - return NULL; -} - -static void -ocsp_nonce_free(void *a) -{ - ASN1_OCTET_STRING_free(a); -} - -static int -i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, BIO *out, - int indent) -{ - if (BIO_printf(out, "%*s", indent, "") <= 0) - return 0; - if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) - return 0; - return 1; -} - -/* Nocheck is just a single NULL. Don't print anything and always set it */ - -static int -i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, BIO *out, - int indent) -{ - return 1; -} - -static void * -s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const char *str) -{ - return ASN1_NULL_new(); -} - -static int -i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) -{ - int i; - OCSP_SERVICELOC *a = in; - ACCESS_DESCRIPTION *ad; - - if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) - goto err; - if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) - goto err; - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) { - ad = sk_ACCESS_DESCRIPTION_value(a->locator, i); - if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, ad->method) <= 0) - goto err; - if (BIO_puts(bp, " - ") <= 0) - goto err; - if (GENERAL_NAME_print(bp, ad->location) <= 0) - goto err; - } - return 1; - -err: - return 0; -} -#endif diff --git a/src/lib/libcrypto/x509/x509_pcons.c b/src/lib/libcrypto/x509/x509_pcons.c deleted file mode 100644 index 66dc57abf6..0000000000 --- a/src/lib/libcrypto/x509/x509_pcons.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $OpenBSD: x509_pcons.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "x509_local.h" - -static STACK_OF(CONF_VALUE) * -i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons, - STACK_OF(CONF_VALUE) *extlist); -static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); - -static const X509V3_EXT_METHOD x509v3_ext_policy_constraints = { - .ext_nid = NID_policy_constraints, - .ext_flags = 0, - .it = &POLICY_CONSTRAINTS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = i2v_POLICY_CONSTRAINTS, - .v2i = v2i_POLICY_CONSTRAINTS, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_policy_constraints(void) -{ - return &x509v3_ext_policy_constraints; -} - -static const ASN1_TEMPLATE POLICY_CONSTRAINTS_seq_tt[] = { - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(POLICY_CONSTRAINTS, requireExplicitPolicy), - .field_name = "requireExplicitPolicy", - .item = &ASN1_INTEGER_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(POLICY_CONSTRAINTS, inhibitPolicyMapping), - .field_name = "inhibitPolicyMapping", - .item = &ASN1_INTEGER_it, - }, -}; - -const ASN1_ITEM POLICY_CONSTRAINTS_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = POLICY_CONSTRAINTS_seq_tt, - .tcount = sizeof(POLICY_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(POLICY_CONSTRAINTS), - .sname = "POLICY_CONSTRAINTS", -}; -LCRYPTO_ALIAS(POLICY_CONSTRAINTS_it); - - -POLICY_CONSTRAINTS * -POLICY_CONSTRAINTS_new(void) -{ - return (POLICY_CONSTRAINTS*)ASN1_item_new(&POLICY_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(POLICY_CONSTRAINTS_new); - -void -POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &POLICY_CONSTRAINTS_it); -} -LCRYPTO_ALIAS(POLICY_CONSTRAINTS_free); - -static STACK_OF(CONF_VALUE) * -i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, - STACK_OF(CONF_VALUE) *extlist) -{ - POLICY_CONSTRAINTS *pcons = a; - STACK_OF(CONF_VALUE) *free_extlist = NULL; - - if (extlist == NULL) { - if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - if (!X509V3_add_value_int("Require Explicit Policy", - pcons->requireExplicitPolicy, &extlist)) - goto err; - if (!X509V3_add_value_int("Inhibit Policy Mapping", - pcons->inhibitPolicyMapping, &extlist)) - goto err; - - return extlist; - - err: - sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); - - return NULL; -} - -static void * -v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - POLICY_CONSTRAINTS *pcons = NULL; - CONF_VALUE *val; - int i; - - if (!(pcons = POLICY_CONSTRAINTS_new())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - val = sk_CONF_VALUE_value(values, i); - if (!strcmp(val->name, "requireExplicitPolicy")) { - if (!X509V3_get_value_int(val, - &pcons->requireExplicitPolicy)) goto err; - } else if (!strcmp(val->name, "inhibitPolicyMapping")) { - if (!X509V3_get_value_int(val, - &pcons->inhibitPolicyMapping)) goto err; - } else { - X509V3error(X509V3_R_INVALID_NAME); - X509V3_conf_err(val); - goto err; - } - } - if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { - X509V3error(X509V3_R_ILLEGAL_EMPTY_EXTENSION); - goto err; - } - - return pcons; - -err: - POLICY_CONSTRAINTS_free(pcons); - return NULL; -} diff --git a/src/lib/libcrypto/x509/x509_pku.c b/src/lib/libcrypto/x509/x509_pku.c deleted file mode 100644 index 6753f0f733..0000000000 --- a/src/lib/libcrypto/x509/x509_pku.c +++ /dev/null @@ -1,165 +0,0 @@ -/* $OpenBSD: x509_pku.c,v 1.5 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include -#include -#include - -static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, - PKEY_USAGE_PERIOD *usage, BIO *out, int indent); - -static const X509V3_EXT_METHOD x509v3_ext_private_key_usage_period = { - .ext_nid = NID_private_key_usage_period, - .ext_flags = 0, - .it = &PKEY_USAGE_PERIOD_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = NULL, - .v2i = NULL, - .i2r = (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_private_key_usage_period(void) -{ - return &x509v3_ext_private_key_usage_period; -} - -static const ASN1_TEMPLATE PKEY_USAGE_PERIOD_seq_tt[] = { - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 0, - .offset = offsetof(PKEY_USAGE_PERIOD, notBefore), - .field_name = "notBefore", - .item = &ASN1_GENERALIZEDTIME_it, - }, - { - .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, - .tag = 1, - .offset = offsetof(PKEY_USAGE_PERIOD, notAfter), - .field_name = "notAfter", - .item = &ASN1_GENERALIZEDTIME_it, - }, -}; - -const ASN1_ITEM PKEY_USAGE_PERIOD_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = PKEY_USAGE_PERIOD_seq_tt, - .tcount = sizeof(PKEY_USAGE_PERIOD_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(PKEY_USAGE_PERIOD), - .sname = "PKEY_USAGE_PERIOD", -}; -LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_it); - - -PKEY_USAGE_PERIOD * -d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len) -{ - return (PKEY_USAGE_PERIOD *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &PKEY_USAGE_PERIOD_it); -} -LCRYPTO_ALIAS(d2i_PKEY_USAGE_PERIOD); - -int -i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKEY_USAGE_PERIOD_it); -} -LCRYPTO_ALIAS(i2d_PKEY_USAGE_PERIOD); - -PKEY_USAGE_PERIOD * -PKEY_USAGE_PERIOD_new(void) -{ - return (PKEY_USAGE_PERIOD *)ASN1_item_new(&PKEY_USAGE_PERIOD_it); -} -LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_new); - -void -PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &PKEY_USAGE_PERIOD_it); -} -LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_free); - -static int -i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, - BIO *out, int indent) -{ - BIO_printf(out, "%*s", indent, ""); - if (usage->notBefore) { - BIO_write(out, "Not Before: ", 12); - ASN1_GENERALIZEDTIME_print(out, usage->notBefore); - if (usage->notAfter) - BIO_write(out, ", ", 2); - } - if (usage->notAfter) { - BIO_write(out, "Not After: ", 11); - ASN1_GENERALIZEDTIME_print(out, usage->notAfter); - } - return 1; -} diff --git a/src/lib/libcrypto/x509/x509_pmaps.c b/src/lib/libcrypto/x509/x509_pmaps.c deleted file mode 100644 index 5039f65f2e..0000000000 --- a/src/lib/libcrypto/x509/x509_pmaps.c +++ /dev/null @@ -1,247 +0,0 @@ -/* $OpenBSD: x509_pmaps.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS( - const X509V3_EXT_METHOD *method, void *pmps, STACK_OF(CONF_VALUE) *extlist); - -static const X509V3_EXT_METHOD x509v3_ext_policy_mappings = { - .ext_nid = NID_policy_mappings, - .ext_flags = 0, - .it = &POLICY_MAPPINGS_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = NULL, - .s2i = NULL, - .i2v = i2v_POLICY_MAPPINGS, - .v2i = v2i_POLICY_MAPPINGS, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_policy_mappings(void) -{ - return &x509v3_ext_policy_mappings; -} - -static const ASN1_TEMPLATE POLICY_MAPPING_seq_tt[] = { - { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICY_MAPPING, issuerDomainPolicy), - .field_name = "issuerDomainPolicy", - .item = &ASN1_OBJECT_it, - }, - { - .flags = 0, - .tag = 0, - .offset = offsetof(POLICY_MAPPING, subjectDomainPolicy), - .field_name = "subjectDomainPolicy", - .item = &ASN1_OBJECT_it, - }, -}; - -const ASN1_ITEM POLICY_MAPPING_it = { - .itype = ASN1_ITYPE_SEQUENCE, - .utype = V_ASN1_SEQUENCE, - .templates = POLICY_MAPPING_seq_tt, - .tcount = sizeof(POLICY_MAPPING_seq_tt) / sizeof(ASN1_TEMPLATE), - .funcs = NULL, - .size = sizeof(POLICY_MAPPING), - .sname = "POLICY_MAPPING", -}; -LCRYPTO_ALIAS(POLICY_MAPPING_it); - -static const ASN1_TEMPLATE POLICY_MAPPINGS_item_tt = { - .flags = ASN1_TFLG_SEQUENCE_OF, - .tag = 0, - .offset = 0, - .field_name = "POLICY_MAPPINGS", - .item = &POLICY_MAPPING_it, -}; - -const ASN1_ITEM POLICY_MAPPINGS_it = { - .itype = ASN1_ITYPE_PRIMITIVE, - .utype = -1, - .templates = &POLICY_MAPPINGS_item_tt, - .tcount = 0, - .funcs = NULL, - .size = 0, - .sname = "POLICY_MAPPINGS", -}; -LCRYPTO_ALIAS(POLICY_MAPPINGS_it); - - -POLICY_MAPPING * -POLICY_MAPPING_new(void) -{ - return (POLICY_MAPPING*)ASN1_item_new(&POLICY_MAPPING_it); -} -LCRYPTO_ALIAS(POLICY_MAPPING_new); - -void -POLICY_MAPPING_free(POLICY_MAPPING *a) -{ - ASN1_item_free((ASN1_VALUE *)a, &POLICY_MAPPING_it); -} -LCRYPTO_ALIAS(POLICY_MAPPING_free); - -static STACK_OF(CONF_VALUE) * -i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a, - STACK_OF(CONF_VALUE) *extlist) -{ - STACK_OF(CONF_VALUE) *free_extlist = NULL; - POLICY_MAPPINGS *pmaps = a; - POLICY_MAPPING *pmap; - char issuer[80], subject[80]; - int i; - - if (extlist == NULL) { - if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL) - return NULL; - } - - for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { - if ((pmap = sk_POLICY_MAPPING_value(pmaps, i)) == NULL) - goto err; - if (!i2t_ASN1_OBJECT(issuer, sizeof issuer, - pmap->issuerDomainPolicy)) - goto err; - if (!i2t_ASN1_OBJECT(subject, sizeof subject, - pmap->subjectDomainPolicy)) - goto err; - if (!X509V3_add_value(issuer, subject, &extlist)) - goto err; - } - - return extlist; - - err: - sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free); - - return NULL; -} - -static void * -v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - POLICY_MAPPINGS *pmaps = NULL; - POLICY_MAPPING *pmap = NULL; - ASN1_OBJECT *obj1 = NULL, *obj2 = NULL; - CONF_VALUE *val; - int i, rc; - - if (!(pmaps = sk_POLICY_MAPPING_new_null())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!val->value || !val->name) { - rc = X509V3_R_INVALID_OBJECT_IDENTIFIER; - goto err; - } - obj1 = OBJ_txt2obj(val->name, 0); - obj2 = OBJ_txt2obj(val->value, 0); - if (!obj1 || !obj2) { - rc = X509V3_R_INVALID_OBJECT_IDENTIFIER; - goto err; - } - pmap = POLICY_MAPPING_new(); - if (!pmap) { - rc = ERR_R_MALLOC_FAILURE; - goto err; - } - pmap->issuerDomainPolicy = obj1; - pmap->subjectDomainPolicy = obj2; - obj1 = obj2 = NULL; - if (sk_POLICY_MAPPING_push(pmaps, pmap) == 0) { - rc = ERR_R_MALLOC_FAILURE; - goto err; - } - pmap = NULL; - } - return pmaps; - -err: - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - X509V3error(rc); - if (rc == X509V3_R_INVALID_OBJECT_IDENTIFIER) - X509V3_conf_err(val); - ASN1_OBJECT_free(obj1); - ASN1_OBJECT_free(obj2); - POLICY_MAPPING_free(pmap); - return NULL; -} diff --git a/src/lib/libcrypto/x509/x509_policy.c b/src/lib/libcrypto/x509/x509_policy.c deleted file mode 100644 index d93760755d..0000000000 --- a/src/lib/libcrypto/x509/x509_policy.c +++ /dev/null @@ -1,1018 +0,0 @@ -/* $OpenBSD: x509_policy.c,v 1.31 2025/03/28 13:11:57 tb Exp $ */ -/* - * Copyright (c) 2022, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include -#include -#include -#include -#include - -#include "stack_local.h" -#include "x509_internal.h" -#include "x509_local.h" - -/* XXX move to proper place */ -#define X509_R_INVALID_POLICY_EXTENSION 201 - -/* - * This file computes the X.509 policy tree, as described in RFC 5280, - * section 6.1 and RFC 9618. It differs in that: - * - * (1) It does not track "qualifier_set". This is not needed as it is not - * output by this implementation. - * - * (2) It builds a directed acyclic graph, rather than a tree. When a given - * policy matches multiple parents, RFC 5280 makes a separate node for - * each parent. This representation condenses them into one node with - * multiple parents. Thus we refer to this structure as a "policy graph", - * rather than a "policy tree". - * - * (3) "expected_policy_set" is not tracked explicitly and built temporarily - * as part of building the graph. - * - * (4) anyPolicy nodes are not tracked explicitly. - * - * (5) Some pruning steps are deferred to when policies are evaluated, as a - * reachability pass. - */ - -/* - * An X509_POLICY_NODE is a node in the policy graph. It corresponds to a node - * from RFC 5280, section 6.1.2, step (a), but we store some fields differently. - */ -typedef struct x509_policy_node_st { - /* policy is the "valid_policy" field from RFC 5280. */ - ASN1_OBJECT *policy; - - /* - * parent_policies, if non-empty, is the list of "valid_policy" values - * for all nodes which are a parent of this node. In this case, no entry - * in this list will be anyPolicy. This list is in no particular order - * and may contain duplicates if the corresponding certificate had - * duplicate mappings. - * - * If empty, this node has a single parent, anyPolicy. The node is then - * a root policies, and is in authorities-constrained-policy-set if it - * has a path to a leaf node. - * - * Note it is not possible for a policy to have both anyPolicy and a - * concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs - * if there was no match in step (d.1.i). We do not need to represent a - * parent list of, say, {anyPolicy, OID1, OID2}. - */ - STACK_OF(ASN1_OBJECT) *parent_policies; - - /* - * mapped is one if this node matches a policy mapping in the - * certificate and zero otherwise. - */ - int mapped; - - /* - * reachable is one if this node is reachable from some valid policy in - * the end-entity certificate. It is computed during |has_explicit_policy|. - */ - int reachable; -} X509_POLICY_NODE; - -DECLARE_STACK_OF(X509_POLICY_NODE) - -#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) -#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) -#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) -#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) -#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) -#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) -#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) -#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) -#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) -#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) -#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) -#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) -#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) -#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) -#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) - -/* - * An X509_POLICY_LEVEL is the collection of nodes at the same depth in the - * policy graph. This structure can also be used to represent a level's - * "expected_policy_set" values. See |process_policy_mappings|. - */ -typedef struct x509_policy_level_st { - /* - * nodes is the list of nodes at this depth, except for the anyPolicy - * node, if any. This list is sorted by policy OID for efficient lookup. - */ - STACK_OF(X509_POLICY_NODE) *nodes; - - /* - * has_any_policy is one if there is an anyPolicy node at this depth, - * and zero otherwise. - */ - int has_any_policy; -} X509_POLICY_LEVEL; - -DECLARE_STACK_OF(X509_POLICY_LEVEL) - -#define sk_X509_POLICY_LEVEL_new(cmp) SKM_sk_new(X509_POLICY_LEVEL, (cmp)) -#define sk_X509_POLICY_LEVEL_new_null() SKM_sk_new_null(X509_POLICY_LEVEL) -#define sk_X509_POLICY_LEVEL_free(st) SKM_sk_free(X509_POLICY_LEVEL, (st)) -#define sk_X509_POLICY_LEVEL_num(st) SKM_sk_num(X509_POLICY_LEVEL, (st)) -#define sk_X509_POLICY_LEVEL_value(st, i) SKM_sk_value(X509_POLICY_LEVEL, (st), (i)) -#define sk_X509_POLICY_LEVEL_set(st, i, val) SKM_sk_set(X509_POLICY_LEVEL, (st), (i), (val)) -#define sk_X509_POLICY_LEVEL_zero(st) SKM_sk_zero(X509_POLICY_LEVEL, (st)) -#define sk_X509_POLICY_LEVEL_push(st, val) SKM_sk_push(X509_POLICY_LEVEL, (st), (val)) -#define sk_X509_POLICY_LEVEL_unshift(st, val) SKM_sk_unshift(X509_POLICY_LEVEL, (st), (val)) -#define sk_X509_POLICY_LEVEL_find(st, val) SKM_sk_find(X509_POLICY_LEVEL, (st), (val)) -#define sk_X509_POLICY_LEVEL_delete(st, i) SKM_sk_delete(X509_POLICY_LEVEL, (st), (i)) -#define sk_X509_POLICY_LEVEL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_LEVEL, (st), (ptr)) -#define sk_X509_POLICY_LEVEL_insert(st, val, i) SKM_sk_insert(X509_POLICY_LEVEL, (st), (val), (i)) -#define sk_X509_POLICY_LEVEL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_LEVEL, (st), (cmp)) -#define sk_X509_POLICY_LEVEL_dup(st) SKM_sk_dup(X509_POLICY_LEVEL, st) -#define sk_X509_POLICY_LEVEL_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_LEVEL, (st), (free_func)) -#define sk_X509_POLICY_LEVEL_shift(st) SKM_sk_shift(X509_POLICY_LEVEL, (st)) -#define sk_X509_POLICY_LEVEL_pop(st) SKM_sk_pop(X509_POLICY_LEVEL, (st)) -#define sk_X509_POLICY_LEVEL_sort(st) SKM_sk_sort(X509_POLICY_LEVEL, (st)) -#define sk_X509_POLICY_LEVEL_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_LEVEL, (st)) - -/* - * Don't look Ethel, but you would really not want to look if we did - * this the OpenSSL way either, and we are not using this boringsslism - * anywhere else. Callers should ensure that the stack in data is sorted. - */ -void -sk_X509_POLICY_NODE_delete_if(STACK_OF(X509_POLICY_NODE) *nodes, - int (*delete_if)(X509_POLICY_NODE *, void *), void *data) -{ - _STACK *sk = (_STACK *)nodes; - X509_POLICY_NODE *node; - int new_num = 0; - int i; - - for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { - node = sk_X509_POLICY_NODE_value(nodes, i); - if (!delete_if(node, data)) - sk->data[new_num++] = (char *)node; - } - sk->num = new_num; -} - -static int -is_any_policy(const ASN1_OBJECT *obj) -{ - return OBJ_obj2nid(obj) == NID_any_policy; -} - -static void -x509_policy_node_free(X509_POLICY_NODE *node) -{ - if (node == NULL) - return; - - ASN1_OBJECT_free(node->policy); - sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free); - free(node); -} - -static X509_POLICY_NODE * -x509_policy_node_new(const ASN1_OBJECT *policy) -{ - X509_POLICY_NODE *node = NULL; - - if (is_any_policy(policy)) - goto err; - if ((node = calloc(1, sizeof(*node))) == NULL) - goto err; - if ((node->policy = OBJ_dup(policy)) == NULL) - goto err; - if ((node->parent_policies = sk_ASN1_OBJECT_new_null()) == NULL) - goto err; - - return node; - - err: - x509_policy_node_free(node); - return NULL; -} - -static int -x509_policy_node_cmp(const X509_POLICY_NODE *const *a, - const X509_POLICY_NODE *const *b) -{ - return OBJ_cmp((*a)->policy, (*b)->policy); -} - -static void -x509_policy_level_free(X509_POLICY_LEVEL *level) -{ - if (level == NULL) - return; - - sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free); - free(level); -} - -static X509_POLICY_LEVEL * -x509_policy_level_new(void) -{ - X509_POLICY_LEVEL *level; - - if ((level = calloc(1, sizeof(*level))) == NULL) - goto err; - level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); - if (level->nodes == NULL) - goto err; - - return level; - - err: - x509_policy_level_free(level); - return NULL; -} - -static int -x509_policy_level_is_empty(const X509_POLICY_LEVEL *level) -{ - if (level->has_any_policy) - return 0; - - return sk_X509_POLICY_NODE_num(level->nodes) == 0; -} - -static void -x509_policy_level_clear(X509_POLICY_LEVEL *level) -{ - X509_POLICY_NODE *node; - int i; - - level->has_any_policy = 0; - for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { - node = sk_X509_POLICY_NODE_value(level->nodes, i); - x509_policy_node_free(node); - } - sk_X509_POLICY_NODE_zero(level->nodes); -} - -/* - * x509_policy_level_find returns the node in |level| corresponding to |policy|, - * or NULL if none exists. Callers should ensure that level->nodes is sorted - * to avoid the cost of sorting it in sk_find(). - */ -static X509_POLICY_NODE * -x509_policy_level_find(X509_POLICY_LEVEL *level, const ASN1_OBJECT *policy) -{ - X509_POLICY_NODE node; - node.policy = (ASN1_OBJECT *)policy; - int idx; - - if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) - return NULL; - return sk_X509_POLICY_NODE_value(level->nodes, idx); -} - -/* - * x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns - * one on success and zero on error. No policy in |nodes| may already be present - * in |level|. This function modifies |nodes| to avoid making a copy, but the - * caller is still responsible for releasing |nodes| itself. - * - * This function is used to add nodes to |level| in bulk, and avoid resorting - * |level| after each addition. - */ -static int -x509_policy_level_add_nodes(X509_POLICY_LEVEL *level, - STACK_OF(X509_POLICY_NODE) *nodes) -{ - int i; - - for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { - X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); - if (!sk_X509_POLICY_NODE_push(level->nodes, node)) - return 0; - sk_X509_POLICY_NODE_set(nodes, i, NULL); - } - sk_X509_POLICY_NODE_sort(level->nodes); - - return 1; -} - -static int -policyinfo_cmp(const POLICYINFO *const *a, - const POLICYINFO *const *b) -{ - return OBJ_cmp((*a)->policyid, (*b)->policyid); -} - -static int -delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) -{ - const CERTIFICATEPOLICIES *policies = data; - POLICYINFO info; - info.policyid = node->policy; - - if (sk_POLICYINFO_find(policies, &info) >= 0) - return 0; - x509_policy_node_free(node); - return 1; -} - -/* - * process_certificate_policies updates |level| to incorporate |x509|'s - * certificate policies extension. This implements steps (d) and (e) of RFC - * 5280, section 6.1.3. |level| must contain the previous level's - * "expected_policy_set" information. For all but the top-most level, this is - * the output of |process_policy_mappings|. |any_policy_allowed| specifies - * whether anyPolicy is allowed or inhibited, taking into account the exception - * for self-issued certificates. - */ -static int -process_certificate_policies(const X509 *x509, X509_POLICY_LEVEL *level, - int any_policy_allowed) -{ - STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; - CERTIFICATEPOLICIES *policies; - const POLICYINFO *policy; - X509_POLICY_NODE *node; - int cert_has_any_policy, critical, i, previous_level_has_any_policy; - int ret = 0; - - policies = X509_get_ext_d2i(x509, NID_certificate_policies, &critical, - NULL); - if (policies == NULL) { - if (critical != -1) - return 0; /* Syntax error in the extension. */ - - /* RFC 5280, section 6.1.3, step (e). */ - x509_policy_level_clear(level); - return 1; - } - - /* - * certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4. - * TODO(https://crbug.com/boringssl/443): Move this check into the parser. - */ - if (sk_POLICYINFO_num(policies) == 0) { - X509error(X509_R_INVALID_POLICY_EXTENSION); - goto err; - } - - (void)sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp); - sk_POLICYINFO_sort(policies); - cert_has_any_policy = 0; - for (i = 0; i < sk_POLICYINFO_num(policies); i++) { - policy = sk_POLICYINFO_value(policies, i); - if (is_any_policy(policy->policyid)) - cert_has_any_policy = 1; - if (i > 0 && - OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, - policy->policyid) == 0) { - /* - * Per RFC 5280, section 4.2.1.4, |policies| may not - * have duplicates. - */ - X509error(X509_R_INVALID_POLICY_EXTENSION); - goto err; - } - } - - /* - * This does the same thing as RFC 5280, section 6.1.3, step (d), - * though in a slightly different order. |level| currently contains - * "expected_policy_set" values of the previous level. - * See |process_policy_mappings| for details. - */ - previous_level_has_any_policy = level->has_any_policy; - - /* - * First, we handle steps (d.1.i) and (d.2). The net effect of these - * two steps is to intersect |level| with |policies|, ignoring - * anyPolicy if it is inhibited. - */ - if (!cert_has_any_policy || !any_policy_allowed) { - if (!sk_POLICYINFO_is_sorted(policies)) - goto err; - sk_X509_POLICY_NODE_delete_if(level->nodes, - delete_if_not_in_policies, policies); - level->has_any_policy = 0; - } - - /* - * Step (d.1.ii) may attach new nodes to the previous level's anyPolicy - * node. - */ - if (previous_level_has_any_policy) { - new_nodes = sk_X509_POLICY_NODE_new_null(); - if (new_nodes == NULL) - goto err; - for (i = 0; i < sk_POLICYINFO_num(policies); i++) { - policy = sk_POLICYINFO_value(policies, i); - /* - * Though we've reordered the steps slightly, |policy| - * is in |level| if and only if it would have been a - * match in step (d.1.ii). - */ - if (is_any_policy(policy->policyid)) - continue; - if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) - goto err; - if (x509_policy_level_find(level, policy->policyid) != NULL) - continue; - node = x509_policy_node_new(policy->policyid); - if (node == NULL || - !sk_X509_POLICY_NODE_push(new_nodes, node)) { - x509_policy_node_free(node); - goto err; - } - } - if (!x509_policy_level_add_nodes(level, new_nodes)) - goto err; - } - - ret = 1; - -err: - sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); - CERTIFICATEPOLICIES_free(policies); - return ret; -} - -static int -compare_issuer_policy(const POLICY_MAPPING *const *a, - const POLICY_MAPPING *const *b) -{ - return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy); -} - -static int -compare_subject_policy(const POLICY_MAPPING *const *a, - const POLICY_MAPPING *const *b) -{ - return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); -} - -static int -delete_if_mapped(X509_POLICY_NODE *node, void *data) -{ - const POLICY_MAPPINGS *mappings = data; - POLICY_MAPPING mapping; - mapping.issuerDomainPolicy = node->policy; - if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0) - return 0; - x509_policy_node_free(node); - return 1; -} - -/* - * process_policy_mappings processes the policy mappings extension of |cert|, - * whose corresponding graph level is |level|. |mapping_allowed| specifies - * whether policy mapping is inhibited at this point. On success, it returns an - * |X509_POLICY_LEVEL| containing the "expected_policy_set" for |level|. On - * error, it returns NULL. This implements steps (a) and (b) of RFC 5280, - * section 6.1.4. - * - * We represent the "expected_policy_set" as an |X509_POLICY_LEVEL|. - * |has_any_policy| indicates whether there is an anyPolicy node with - * "expected_policy_set" of {anyPolicy}. If a node with policy oid P1 contains - * P2 in its "expected_policy_set", the level will contain a node of policy P2 - * with P1 in |parent_policies|. - * - * This is equivalent to the |X509_POLICY_LEVEL| that would result if the next - * certificate contained anyPolicy. |process_certificate_policies| will filter - * this result down to compute the actual level. - */ -static X509_POLICY_LEVEL * -process_policy_mappings(const X509 *cert, - X509_POLICY_LEVEL *level, - int mapping_allowed) -{ - STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; - POLICY_MAPPINGS *mappings; - const ASN1_OBJECT *last_policy; - POLICY_MAPPING *mapping; - X509_POLICY_LEVEL *next = NULL; - X509_POLICY_NODE *node; - int critical, i; - int ok = 0; - - mappings = X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); - if (mappings == NULL && critical != -1) { - /* Syntax error in the policy mappings extension. */ - goto err; - } - - if (mappings != NULL) { - /* - * PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5. - * TODO(https://crbug.com/boringssl/443): Move this check into - * the parser. - */ - if (sk_POLICY_MAPPING_num(mappings) == 0) { - X509error(X509_R_INVALID_POLICY_EXTENSION); - goto err; - } - - /* RFC 5280, section 6.1.4, step (a). */ - for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { - mapping = sk_POLICY_MAPPING_value(mappings, i); - if (is_any_policy(mapping->issuerDomainPolicy) || - is_any_policy(mapping->subjectDomainPolicy)) - goto err; - } - - /* Sort to group by issuerDomainPolicy. */ - (void)sk_POLICY_MAPPING_set_cmp_func(mappings, - compare_issuer_policy); - sk_POLICY_MAPPING_sort(mappings); - - if (mapping_allowed) { - /* - * Mark nodes as mapped, and add any nodes to |level| - * which may be needed as part of RFC 5280, - * section 6.1.4, step (b.1). - */ - new_nodes = sk_X509_POLICY_NODE_new_null(); - if (new_nodes == NULL) - goto err; - last_policy = NULL; - for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { - mapping = sk_POLICY_MAPPING_value(mappings, i); - /* - * There may be multiple mappings with the same - * |issuerDomainPolicy|. - */ - if (last_policy != NULL && - OBJ_cmp(mapping->issuerDomainPolicy, - last_policy) == 0) - continue; - last_policy = mapping->issuerDomainPolicy; - - if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) - goto err; - node = x509_policy_level_find(level, - mapping->issuerDomainPolicy); - if (node == NULL) { - if (!level->has_any_policy) - continue; - node = x509_policy_node_new( - mapping->issuerDomainPolicy); - if (node == NULL || - !sk_X509_POLICY_NODE_push(new_nodes, - node)) { - x509_policy_node_free(node); - goto err; - } - } - node->mapped = 1; - } - if (!x509_policy_level_add_nodes(level, new_nodes)) - goto err; - } else { - /* - * RFC 5280, section 6.1.4, step (b.2). If mapping is - * inhibited, delete all mapped nodes. - */ - if (!sk_POLICY_MAPPING_is_sorted(mappings)) - goto err; - sk_X509_POLICY_NODE_delete_if(level->nodes, - delete_if_mapped, mappings); - sk_POLICY_MAPPING_pop_free(mappings, - POLICY_MAPPING_free); - mappings = NULL; - } - } - - /* - * If a node was not mapped, it retains the original "explicit_policy_set" - * value, itself. Add those to |mappings|. - */ - if (mappings == NULL) { - mappings = sk_POLICY_MAPPING_new_null(); - if (mappings == NULL) - goto err; - } - for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { - node = sk_X509_POLICY_NODE_value(level->nodes, i); - if (!node->mapped) { - mapping = POLICY_MAPPING_new(); - if (mapping == NULL) - goto err; - mapping->issuerDomainPolicy = OBJ_dup(node->policy); - mapping->subjectDomainPolicy = OBJ_dup(node->policy); - if (mapping->issuerDomainPolicy == NULL || - mapping->subjectDomainPolicy == NULL || - !sk_POLICY_MAPPING_push(mappings, mapping)) { - POLICY_MAPPING_free(mapping); - goto err; - } - } - } - - /* Sort to group by subjectDomainPolicy. */ - (void)sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy); - sk_POLICY_MAPPING_sort(mappings); - - /* Convert |mappings| to our "expected_policy_set" representation. */ - next = x509_policy_level_new(); - if (next == NULL) - goto err; - next->has_any_policy = level->has_any_policy; - - X509_POLICY_NODE *last_node = NULL; - for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { - mapping = sk_POLICY_MAPPING_value(mappings, i); - /* - * Skip mappings where |issuerDomainPolicy| does not appear in - * the graph. - */ - if (!level->has_any_policy) { - if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) - goto err; - if (x509_policy_level_find(level, - mapping->issuerDomainPolicy) == NULL) - continue; - } - - if (last_node == NULL || - OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != - 0) { - last_node = x509_policy_node_new( - mapping->subjectDomainPolicy); - if (last_node == NULL || - !sk_X509_POLICY_NODE_push(next->nodes, last_node)) { - x509_policy_node_free(last_node); - goto err; - } - } - - if (!sk_ASN1_OBJECT_push(last_node->parent_policies, - mapping->issuerDomainPolicy)) - goto err; - mapping->issuerDomainPolicy = NULL; - } - - sk_X509_POLICY_NODE_sort(next->nodes); - ok = 1; - -err: - if (!ok) { - x509_policy_level_free(next); - next = NULL; - } - - sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); - sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); - return next; -} - -/* - * apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum - * of its current value and |skip_certs|. It returns one on success and zero if - * |skip_certs| is negative. - */ -static int -apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) -{ - if (skip_certs == NULL) - return 1; - - /* TODO(https://crbug.com/boringssl/443): Move this check into the parser. */ - if (skip_certs->type & V_ASN1_NEG) { - X509error(X509_R_INVALID_POLICY_EXTENSION); - return 0; - } - - /* If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. */ - uint64_t u64; - if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) - *value = (size_t)u64; - ERR_clear_error(); - return 1; -} - -/* - * process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and - * |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit - * anyPolicy extensions. It returns one on success and zero on error. This - * implements steps (i) and (j) of RFC 5280, section 6.1.4. - */ -static int -process_policy_constraints(const X509 *x509, size_t *explicit_policy, - size_t *policy_mapping, - size_t *inhibit_any_policy) -{ - ASN1_INTEGER *inhibit_any_policy_ext; - POLICY_CONSTRAINTS *constraints; - int critical; - int ok = 0; - - constraints = X509_get_ext_d2i(x509, NID_policy_constraints, &critical, - NULL); - if (constraints == NULL && critical != -1) - return 0; - if (constraints != NULL) { - if (constraints->requireExplicitPolicy == NULL && - constraints->inhibitPolicyMapping == NULL) { - /* - * Per RFC 5280, section 4.2.1.11, at least one of the - * fields must be - */ - X509error(X509_R_INVALID_POLICY_EXTENSION); - POLICY_CONSTRAINTS_free(constraints); - return 0; - } - ok = apply_skip_certs(constraints->requireExplicitPolicy, - explicit_policy) && - apply_skip_certs(constraints->inhibitPolicyMapping, - policy_mapping); - POLICY_CONSTRAINTS_free(constraints); - if (!ok) - return 0; - } - - inhibit_any_policy_ext = X509_get_ext_d2i(x509, NID_inhibit_any_policy, - &critical, NULL); - if (inhibit_any_policy_ext == NULL && critical != -1) - return 0; - ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); - ASN1_INTEGER_free(inhibit_any_policy_ext); - return ok; -} - -/* - * has_explicit_policy returns one if the set of authority-space policy OIDs - * |levels| has some non-empty intersection with |user_policies|, and zero - * otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This - * function modifies |levels| and should only be called at the end of policy - * evaluation. - */ -static int -has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, - const STACK_OF(ASN1_OBJECT) *user_policies) -{ - X509_POLICY_LEVEL *level, *prev; - X509_POLICY_NODE *node, *parent; - int num_levels, user_has_any_policy; - int i, j, k; - - if (!sk_ASN1_OBJECT_is_sorted(user_policies)) - return 0; - - /* Step (g.i). If the policy graph is empty, the intersection is empty. */ - num_levels = sk_X509_POLICY_LEVEL_num(levels); - level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1); - if (x509_policy_level_is_empty(level)) - return 0; - - /* - * If |user_policies| is empty, we interpret it as having a single - * anyPolicy value. The caller may also have supplied anyPolicy - * explicitly. - */ - user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) <= 0; - for (i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) { - if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) { - user_has_any_policy = 1; - break; - } - } - - /* - * Step (g.ii). If the policy graph is not empty and the user set - * contains anyPolicy, the intersection is the entire (non-empty) graph. - */ - if (user_has_any_policy) - return 1; - - /* - * Step (g.iii) does not delete anyPolicy nodes, so if the graph has - * anyPolicy, some explicit policy will survive. The actual intersection - * may synthesize some nodes in step (g.iii.3), but we do not return the - * policy list itself, so we skip actually computing this. - */ - if (level->has_any_policy) - return 1; - - /* - * We defer pruning the tree, so as we look for nodes with parent - * anyPolicy, step (g.iii.1), we must limit to nodes reachable from the - * bottommost level. Start by marking each of those nodes as reachable. - */ - for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) - sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; - - for (i = num_levels - 1; i >= 0; i--) { - level = sk_X509_POLICY_LEVEL_value(levels, i); - for (j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) { - node = sk_X509_POLICY_NODE_value(level->nodes, j); - if (!node->reachable) - continue; - if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { - /* - * |node|'s parent is anyPolicy and is part of - * "valid_policy_node_set". If it exists in - * |user_policies|, the intersection is - * non-empty and we * can return immediately. - */ - if (sk_ASN1_OBJECT_find(user_policies, - node->policy) >= 0) - return 1; - } else if (i > 0) { - int num_parent_policies = - sk_ASN1_OBJECT_num(node->parent_policies); - /* - * |node|'s parents are concrete policies. Mark - * the parents reachable, to be inspected by the - * next loop iteration. - */ - prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); - for (k = 0; k < num_parent_policies; k++) { - if (!sk_X509_POLICY_NODE_is_sorted(prev->nodes)) - return 0; - parent = x509_policy_level_find(prev, - sk_ASN1_OBJECT_value(node->parent_policies, - k)); - if (parent != NULL) - parent->reachable = 1; - } - } - } - } - - return 0; -} - -static int -asn1_object_cmp(const ASN1_OBJECT *const *a, const ASN1_OBJECT *const *b) -{ - return OBJ_cmp(*a, *b); -} - -int -X509_policy_check(const STACK_OF(X509) *certs, - const STACK_OF(ASN1_OBJECT) *user_policies, - unsigned long flags, X509 **out_current_cert) -{ - *out_current_cert = NULL; - int ret = X509_V_ERR_OUT_OF_MEM; - X509 *cert; - X509_POLICY_LEVEL *level = NULL; - X509_POLICY_LEVEL *current_level; - STACK_OF(X509_POLICY_LEVEL) *levels = NULL; - STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL; - int num_certs = sk_X509_num(certs); - int is_self_issued, any_policy_allowed; - int i; - - /* Skip policy checking if the chain is just the trust anchor. */ - if (num_certs <= 1) - return X509_V_OK; - - /* See RFC 5280, section 6.1.2, steps (d) through (f). */ - size_t explicit_policy = - (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1; - size_t inhibit_any_policy = - (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1; - size_t policy_mapping = - (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; - - levels = sk_X509_POLICY_LEVEL_new_null(); - if (levels == NULL) - goto err; - - for (i = num_certs - 2; i >= 0; i--) { - cert = sk_X509_value(certs, i); - if (!x509v3_cache_extensions(cert)) - goto err; - is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; - - if (level == NULL) { - if (i != num_certs - 2) - goto err; - level = x509_policy_level_new(); - if (level == NULL) - goto err; - level->has_any_policy = 1; - } - - /* - * RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| - * is computed as in step (d.2). - */ - any_policy_allowed = - inhibit_any_policy > 0 || (i > 0 && is_self_issued); - if (!process_certificate_policies(cert, level, - any_policy_allowed)) { - ret = X509_V_ERR_INVALID_POLICY_EXTENSION; - *out_current_cert = cert; - goto err; - } - - /* RFC 5280, section 6.1.3, step (f). */ - if (explicit_policy == 0 && x509_policy_level_is_empty(level)) { - ret = X509_V_ERR_NO_EXPLICIT_POLICY; - goto err; - } - - /* Insert into the list. */ - if (!sk_X509_POLICY_LEVEL_push(levels, level)) - goto err; - current_level = level; - level = NULL; - - /* - * If this is not the leaf certificate, we go to section 6.1.4. - * If it is the leaf certificate, we go to section 6.1.5 instead. - */ - if (i != 0) { - /* RFC 5280, section 6.1.4, steps (a) and (b). */ - level = process_policy_mappings(cert, current_level, - policy_mapping > 0); - if (level == NULL) { - ret = X509_V_ERR_INVALID_POLICY_EXTENSION; - *out_current_cert = cert; - goto err; - } - } - - /* - * RFC 5280, section 6.1.4, step (h-j) for non-leaves, and - * section 6.1.5, step (a-b) for leaves. In the leaf case, - * RFC 5280 says only to update |explicit_policy|, but - * |policy_mapping| and |inhibit_any_policy| are no - * longer read at this point, so we use the same process. - */ - if (i == 0 || !is_self_issued) { - if (explicit_policy > 0) - explicit_policy--; - if (policy_mapping > 0) - policy_mapping--; - if (inhibit_any_policy > 0) - inhibit_any_policy--; - } - if (!process_policy_constraints(cert, &explicit_policy, - &policy_mapping, &inhibit_any_policy)) { - ret = X509_V_ERR_INVALID_POLICY_EXTENSION; - *out_current_cert = cert; - goto err; - } - } - - /* - * RFC 5280, section 6.1.5, step (g). We do not output the policy set, - * so it is only necessary to check if the user-constrained-policy-set - * is not empty. - */ - if (explicit_policy == 0) { - /* - * Build a sorted copy of |user_policies| for more efficient - * lookup. - */ - if (user_policies != NULL) { - user_policies_sorted = sk_ASN1_OBJECT_dup( - user_policies); - if (user_policies_sorted == NULL) - goto err; - (void)sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, - asn1_object_cmp); - sk_ASN1_OBJECT_sort(user_policies_sorted); - } - - if (!has_explicit_policy(levels, user_policies_sorted)) { - ret = X509_V_ERR_NO_EXPLICIT_POLICY; - goto err; - } - } - - ret = X509_V_OK; - -err: - x509_policy_level_free(level); - /* - * |user_policies_sorted|'s contents are owned by |user_policies|, so - * we do not use |sk_ASN1_OBJECT_pop_free|. - */ - sk_ASN1_OBJECT_free(user_policies_sorted); - sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free); - return ret; -} diff --git a/src/lib/libcrypto/x509/x509_prn.c b/src/lib/libcrypto/x509/x509_prn.c deleted file mode 100644 index 3bf7c803e5..0000000000 --- a/src/lib/libcrypto/x509/x509_prn.c +++ /dev/null @@ -1,231 +0,0 @@ -/* $OpenBSD: x509_prn.c,v 1.6 2023/05/08 05:30:38 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* X509 v3 extension utilities */ - -#include - -#include -#include - -#include "x509_local.h" - -/* Extension printing routines */ - -static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, - int indent, int supported); - -/* Print out a name+value stack */ - -void -X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml) -{ - int i; - CONF_VALUE *nval; - - if (!val) - return; - if (!ml || !sk_CONF_VALUE_num(val)) { - BIO_printf(out, "%*s", indent, ""); - if (!sk_CONF_VALUE_num(val)) - BIO_puts(out, "\n"); - } - for (i = 0; i < sk_CONF_VALUE_num(val); i++) { - if (ml) - BIO_printf(out, "%*s", indent, ""); - else if (i > 0) BIO_printf(out, ", "); - nval = sk_CONF_VALUE_value(val, i); - if (!nval->name) - BIO_puts(out, nval->value); - else if (!nval->value) - BIO_puts(out, nval->name); - else - BIO_printf(out, "%s:%s", nval->name, nval->value); - if (ml) - BIO_puts(out, "\n"); - } -} -LCRYPTO_ALIAS(X509V3_EXT_val_prn); - -/* Main routine: print out a general extension */ - -int -X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent) -{ - void *ext_str = NULL; - char *value = NULL; - const unsigned char *p; - const X509V3_EXT_METHOD *method; - STACK_OF(CONF_VALUE) *nval = NULL; - int ok = 1; - - if (!(method = X509V3_EXT_get(ext))) - return unknown_ext_print(out, ext, flag, indent, 0); - p = ext->value->data; - if (method->it) - ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, - method->it); - else - ext_str = method->d2i(NULL, &p, ext->value->length); - - if (!ext_str) - return unknown_ext_print(out, ext, flag, indent, 1); - - if (method->i2s) { - if (!(value = method->i2s(method, ext_str))) { - ok = 0; - goto err; - } - BIO_printf(out, "%*s%s", indent, "", value); - } else if (method->i2v) { - if (!(nval = method->i2v(method, ext_str, NULL))) { - ok = 0; - goto err; - } - X509V3_EXT_val_prn(out, nval, indent, - method->ext_flags & X509V3_EXT_MULTILINE); - } else if (method->i2r) { - if (!method->i2r(method, ext_str, out, indent)) - ok = 0; - } else - ok = 0; - -err: - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - free(value); - if (method->it) - ASN1_item_free(ext_str, method->it); - else - method->ext_free(ext_str); - return ok; -} -LCRYPTO_ALIAS(X509V3_EXT_print); - -int -X509V3_extensions_print(BIO *bp, const char *title, - const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent) -{ - int i, j; - - if (sk_X509_EXTENSION_num(exts) <= 0) - return 1; - - if (title) { - BIO_printf(bp, "%*s%s:\n",indent, "", title); - indent += 4; - } - - for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - ASN1_OBJECT *obj; - X509_EXTENSION *ex; - ex = sk_X509_EXTENSION_value(exts, i); - if (indent && BIO_printf(bp, "%*s",indent, "") <= 0) - return 0; - obj = X509_EXTENSION_get_object(ex); - i2a_ASN1_OBJECT(bp, obj); - j = X509_EXTENSION_get_critical(ex); - if (BIO_printf(bp, ":%s\n", j ? " critical" : "") <= 0) - return 0; - if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { - BIO_printf(bp, "%*s", indent + 4, ""); - ASN1_STRING_print(bp, ex->value); - } - if (BIO_write(bp, "\n",1) <= 0) - return 0; - } - return 1; -} -LCRYPTO_ALIAS(X509V3_extensions_print); - -static int -unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, - int indent, int supported) -{ - switch (flag & X509V3_EXT_UNKNOWN_MASK) { - case X509V3_EXT_DEFAULT: - return 0; - case X509V3_EXT_ERROR_UNKNOWN: - if (supported) - BIO_printf(out, "%*s", indent, ""); - else - BIO_printf(out, "%*s", indent, ""); - return 1; - case X509V3_EXT_PARSE_UNKNOWN: - return ASN1_parse_dump(out, - ext->value->data, ext->value->length, indent, -1); - case X509V3_EXT_DUMP_UNKNOWN: - return BIO_dump_indent(out, (char *)ext->value->data, - ext->value->length, indent); - default: - return 1; - } -} - - -int -X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) -{ - BIO *bio_tmp; - int ret; - - if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) - return 0; - ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); - BIO_free(bio_tmp); - return ret; -} -LCRYPTO_ALIAS(X509V3_EXT_print_fp); diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c deleted file mode 100644 index 619a4b890a..0000000000 --- a/src/lib/libcrypto/x509/x509_purp.c +++ /dev/null @@ -1,930 +0,0 @@ -/* $OpenBSD: x509_purp.c,v 1.43 2024/07/12 18:15:10 beck Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include - -#include -#include -#include - -#include "x509_internal.h" -#include "x509_local.h" - -struct x509_purpose_st { - int purpose; - int trust; /* Default trust ID */ - int flags; - int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); - char *name; - char *sname; - void *usr_data; -} /* X509_PURPOSE */; - -#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -#define xku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) -#define ns_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) - -static int check_ssl_ca(const X509 *x); -static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int purpose_smime(const X509 *x, int ca); -static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); -static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); - -static const X509_PURPOSE xstandard[] = { - { - .purpose = X509_PURPOSE_SSL_CLIENT, - .trust = X509_TRUST_SSL_CLIENT, - .check_purpose = check_purpose_ssl_client, - .name = "SSL client", - .sname = "sslclient", - }, - { - .purpose = X509_PURPOSE_SSL_SERVER, - .trust = X509_TRUST_SSL_SERVER, - .check_purpose = check_purpose_ssl_server, - .name = "SSL server", - .sname = "sslserver", - }, - { - .purpose = X509_PURPOSE_NS_SSL_SERVER, - .trust = X509_TRUST_SSL_SERVER, - .check_purpose = check_purpose_ns_ssl_server, - .name = "Netscape SSL server", - .sname = "nssslserver", - }, - { - .purpose = X509_PURPOSE_SMIME_SIGN, - .trust = X509_TRUST_EMAIL, - .check_purpose = check_purpose_smime_sign, - .name = "S/MIME signing", - .sname = "smimesign", - }, - { - .purpose = X509_PURPOSE_SMIME_ENCRYPT, - .trust = X509_TRUST_EMAIL, - .check_purpose = check_purpose_smime_encrypt, - .name = "S/MIME encryption", - .sname = "smimeencrypt", - }, - { - .purpose = X509_PURPOSE_CRL_SIGN, - .trust = X509_TRUST_COMPAT, - .check_purpose = check_purpose_crl_sign, - .name = "CRL signing", - .sname = "crlsign", - }, - { - .purpose = X509_PURPOSE_ANY, - .trust = X509_TRUST_ACCEPT_ALL, - .check_purpose = no_check, - .name = "Any Purpose", - .sname = "any", - }, - { - .purpose = X509_PURPOSE_OCSP_HELPER, - .trust = X509_TRUST_COMPAT, - .check_purpose = ocsp_helper, - .name = "OCSP helper", - .sname = "ocsphelper", - }, - { - .purpose = X509_PURPOSE_TIMESTAMP_SIGN, - .trust = X509_TRUST_TSA, - .check_purpose = check_purpose_timestamp_sign, - .name = "Time Stamp signing", - .sname = "timestampsign", - }, -}; - -#define X509_PURPOSE_COUNT (sizeof(xstandard) / sizeof(xstandard[0])) - -/* As much as I'd like to make X509_check_purpose use a "const" X509* - * I really can't because it does recalculate hashes and do other non-const - * things. */ -int -X509_check_purpose(X509 *x, int id, int ca) -{ - int idx; - const X509_PURPOSE *pt; - - if (!x509v3_cache_extensions(x)) - return -1; - - if (id == -1) - return 1; - - if ((idx = X509_PURPOSE_get_by_id(id)) == -1) - return -1; - if ((pt = X509_PURPOSE_get0(idx)) == NULL) - return -1; - - return pt->check_purpose(pt, x, ca); -} -LCRYPTO_ALIAS(X509_check_purpose); - -int -X509_PURPOSE_get_count(void) -{ - return X509_PURPOSE_COUNT; -} -LCRYPTO_ALIAS(X509_PURPOSE_get_count); - -const X509_PURPOSE * -X509_PURPOSE_get0(int idx) -{ - if (idx < 0 || (size_t)idx >= X509_PURPOSE_COUNT) - return NULL; - - return &xstandard[idx]; -} -LCRYPTO_ALIAS(X509_PURPOSE_get0); - -int -X509_PURPOSE_get_by_sname(const char *sname) -{ - int i; - const X509_PURPOSE *xptmp; - - for (i = 0; i < X509_PURPOSE_get_count(); i++) { - xptmp = X509_PURPOSE_get0(i); - if (!strcmp(xptmp->sname, sname)) - return i; - } - return -1; -} -LCRYPTO_ALIAS(X509_PURPOSE_get_by_sname); - -int -X509_PURPOSE_get_by_id(int purpose) -{ - /* - * Ensure the purpose identifier is between MIN and MAX inclusive. - * If so, translate it to an index into the xstandard[] table. - */ - if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) - return -1; - - return purpose - X509_PURPOSE_MIN; -} - -int -X509_PURPOSE_get_id(const X509_PURPOSE *xp) -{ - return xp->purpose; -} -LCRYPTO_ALIAS(X509_PURPOSE_get_id); - -const char * -X509_PURPOSE_get0_name(const X509_PURPOSE *xp) -{ - return xp->name; -} -LCRYPTO_ALIAS(X509_PURPOSE_get0_name); - -const char * -X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) -{ - return xp->sname; -} -LCRYPTO_ALIAS(X509_PURPOSE_get0_sname); - -int -X509_PURPOSE_get_trust(const X509_PURPOSE *xp) -{ - return xp->trust; -} - -/* - * List of NIDs of extensions supported by the verifier. If an extension - * is critical and doesn't appear in this list, then the certificate will - * normally be rejected. - */ -int -X509_supported_extension(X509_EXTENSION *ext) -{ - switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext))) { - case NID_basic_constraints: - case NID_certificate_policies: - case NID_ext_key_usage: - case NID_inhibit_any_policy: - case NID_key_usage: - case NID_name_constraints: - case NID_netscape_cert_type: - case NID_policy_constraints: - case NID_policy_mappings: -#ifndef OPENSSL_NO_RFC3779 - case NID_sbgp_ipAddrBlock: - case NID_sbgp_autonomousSysNum: -#endif - case NID_subject_alt_name: - return 1; - default: - return 0; - } -} -LCRYPTO_ALIAS(X509_supported_extension); - -static void -setup_dp(X509 *x, DIST_POINT *dp) -{ - X509_NAME *iname = NULL; - int i; - - if (dp->reasons) { - if (dp->reasons->length > 0) - dp->dp_reasons = dp->reasons->data[0]; - if (dp->reasons->length > 1) - dp->dp_reasons |= (dp->reasons->data[1] << 8); - dp->dp_reasons &= CRLDP_ALL_REASONS; - } else - dp->dp_reasons = CRLDP_ALL_REASONS; - if (!dp->distpoint || (dp->distpoint->type != 1)) - return; - for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); - if (gen->type == GEN_DIRNAME) { - iname = gen->d.directoryName; - break; - } - } - if (!iname) - iname = X509_get_issuer_name(x); - - DIST_POINT_set_dpname(dp->distpoint, iname); -} - -static void -setup_crldp(X509 *x) -{ - int i; - - 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)); -} - -static int -x509_extension_oid_cmp(const X509_EXTENSION *const *a, - const X509_EXTENSION *const *b) -{ - return OBJ_cmp((*a)->object, (*b)->object); -} - -static int -x509_extension_oids_are_unique(X509 *x509) -{ - STACK_OF(X509_EXTENSION) *exts = NULL; - const X509_EXTENSION *prev_ext, *curr_ext; - int i; - int ret = 0; - - if (X509_get_ext_count(x509) <= 1) - goto done; - - if ((exts = sk_X509_EXTENSION_dup(x509->cert_info->extensions)) == NULL) - goto err; - - (void)sk_X509_EXTENSION_set_cmp_func(exts, x509_extension_oid_cmp); - sk_X509_EXTENSION_sort(exts); - - prev_ext = sk_X509_EXTENSION_value(exts, 0); - for (i = 1; i < sk_X509_EXTENSION_num(exts); i++) { - curr_ext = sk_X509_EXTENSION_value(exts, i); - if (x509_extension_oid_cmp(&prev_ext, &curr_ext) == 0) - goto err; - prev_ext = curr_ext; - } - - done: - ret = 1; - - err: - sk_X509_EXTENSION_free(exts); - - return ret; -} - -static void -x509v3_cache_extensions_internal(X509 *x) -{ - BASIC_CONSTRAINTS *bs; - ASN1_BIT_STRING *usage; - ASN1_BIT_STRING *ns; - EXTENDED_KEY_USAGE *extusage; - X509_EXTENSION *ex; - long version; - int i; - - if (x->ex_flags & EXFLAG_SET) - return; - - /* - * XXX - this should really only set EXFLAG_INVALID if extensions are - * invalid. However, the X509_digest() failure matches OpenSSL/BoringSSL - * behavior and the version checks are at least vaguely related to - * extensions. - */ - - if (!X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL)) - x->ex_flags |= EXFLAG_INVALID; - - version = X509_get_version(x); - if (version < 0 || version > 2) - x->ex_flags |= EXFLAG_INVALID; - if (version == 0) { - x->ex_flags |= EXFLAG_V1; - /* UIDs may only appear in v2 or v3 certs */ - if (x->cert_info->issuerUID != NULL || - x->cert_info->subjectUID != NULL) - x->ex_flags |= EXFLAG_INVALID; - } - if (version != 2 && X509_get_ext_count(x) != 0) - x->ex_flags |= EXFLAG_INVALID; - - /* Handle basic constraints */ - if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) { - if (bs->ca) - x->ex_flags |= EXFLAG_CA; - if (bs->pathlen) { - if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) || - !bs->ca) { - x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; - } else - x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); - } else - x->ex_pathlen = -1; - BASIC_CONSTRAINTS_free(bs); - x->ex_flags |= EXFLAG_BCONS; - } else if (i != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - - /* Handle key usage */ - 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) - x->ex_kusage |= usage->data[1] << 8; - } else - 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, &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))) { - case NID_server_auth: - x->ex_xkusage |= XKU_SSL_SERVER; - break; - - case NID_client_auth: - x->ex_xkusage |= XKU_SSL_CLIENT; - break; - - case NID_email_protect: - x->ex_xkusage |= XKU_SMIME; - break; - - case NID_code_sign: - x->ex_xkusage |= XKU_CODE_SIGN; - break; - - case NID_ms_sgc: - case NID_ns_sgc: - x->ex_xkusage |= XKU_SGC; - break; - - case NID_OCSP_sign: - x->ex_xkusage |= XKU_OCSP_SIGN; - break; - - case NID_time_stamp: - x->ex_xkusage |= XKU_TIMESTAMP; - break; - - 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, &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, &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))) { - x->ex_flags |= EXFLAG_SI; - /* If SKID matches AKID also indicate self signed. */ - if (X509_check_akid(x, x->akid) == X509_V_OK && - !ku_reject(x, KU_KEY_CERT_SIGN)) - x->ex_flags |= EXFLAG_SS; - } - - 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; - if (!X509v3_addr_is_canonical(x->rfc3779_addr)) - 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; - if (!X509v3_asid_is_canonical(x->rfc3779_asid)) - 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)) == - NID_freshest_crl) - x->ex_flags |= EXFLAG_FRESHEST; - if (!X509_EXTENSION_get_critical(ex)) - continue; - if (!X509_supported_extension(ex)) { - x->ex_flags |= EXFLAG_CRITICAL; - break; - } - } - - if (!x509_extension_oids_are_unique(x)) - x->ex_flags |= EXFLAG_INVALID; - - x->ex_flags |= EXFLAG_SET; -} - -int -x509v3_cache_extensions(X509 *x) -{ - if ((x->ex_flags & EXFLAG_SET) == 0) { - CRYPTO_w_lock(CRYPTO_LOCK_X509); - x509v3_cache_extensions_internal(x); - CRYPTO_w_unlock(CRYPTO_LOCK_X509); - } - - return (x->ex_flags & EXFLAG_INVALID) == 0; -} - -/* CA checks common to all purposes - * return codes: - * 0 not a CA - * 1 is a CA - * 2 basicConstraints absent so "maybe" a CA - * 3 basicConstraints absent but self signed V1. - * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. - */ - -static int -check_ca(const X509 *x) -{ - /* keyUsage if present should allow cert signing */ - if (ku_reject(x, KU_KEY_CERT_SIGN)) - return 0; - if (x->ex_flags & EXFLAG_BCONS) { - if (x->ex_flags & EXFLAG_CA) - return 1; - /* If basicConstraints says not a CA then say so */ - else - return 0; - } else { - /* we support V1 roots for... uh, I don't really know why. */ - if ((x->ex_flags & V1_ROOT) == V1_ROOT) - return 3; - /* If key usage present it must have certSign so tolerate it */ - else if (x->ex_flags & EXFLAG_KUSAGE) - return 4; - /* Older certificates could have Netscape-specific CA types */ - else if (x->ex_flags & EXFLAG_NSCERT && - x->ex_nscert & NS_ANY_CA) - return 5; - /* can this still be regarded a CA certificate? I doubt it */ - return 0; - } -} - -int -X509_check_ca(X509 *x) -{ - x509v3_cache_extensions(x); - - return check_ca(x); -} -LCRYPTO_ALIAS(X509_check_ca); - -/* Check SSL CA: common checks for SSL client and server */ -static int -check_ssl_ca(const X509 *x) -{ - int ca_ret; - - ca_ret = check_ca(x); - if (!ca_ret) - return 0; - /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) - return ca_ret; - else - return 0; -} - -static int -check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - if (xku_reject(x, XKU_SSL_CLIENT)) - return 0; - if (ca) - return check_ssl_ca(x); - /* We need to do digital signatures with it */ - if (ku_reject(x, KU_DIGITAL_SIGNATURE)) - return 0; - /* nsCertType if present should allow SSL client use */ - if (ns_reject(x, NS_SSL_CLIENT)) - return 0; - return 1; -} - -static int -check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - if (xku_reject(x, XKU_SSL_SERVER|XKU_SGC)) - return 0; - if (ca) - return check_ssl_ca(x); - - if (ns_reject(x, NS_SSL_SERVER)) - return 0; - /* Now as for keyUsage: we'll at least need to sign OR encipher */ - if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) - return 0; - - return 1; -} - -static int -check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - int ret; - - ret = check_purpose_ssl_server(xp, x, ca); - if (!ret || ca) - return ret; - /* We need to encipher or Netscape complains */ - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; - return ret; -} - -/* common S/MIME checks */ -static int -purpose_smime(const X509 *x, int ca) -{ - if (xku_reject(x, XKU_SMIME)) - return 0; - if (ca) { - int ca_ret; - ca_ret = check_ca(x); - if (!ca_ret) - return 0; - /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) - return ca_ret; - else - return 0; - } - if (x->ex_flags & EXFLAG_NSCERT) { - if (x->ex_nscert & NS_SMIME) - return 1; - /* Workaround for some buggy certificates */ - if (x->ex_nscert & NS_SSL_CLIENT) - return 2; - return 0; - } - return 1; -} - -static int -check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - int ret; - - ret = purpose_smime(x, ca); - if (!ret || ca) - return ret; - if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) - return 0; - return ret; -} - -static int -check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - int ret; - - ret = purpose_smime(x, ca); - if (!ret || ca) - return ret; - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; - return ret; -} - -static int -check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - if (ca) { - int ca_ret; - if ((ca_ret = check_ca(x)) != 2) - return ca_ret; - else - return 0; - } - if (ku_reject(x, KU_CRL_SIGN)) - return 0; - return 1; -} - -/* OCSP helper: this is *not* a full OCSP check. It just checks that - * each CA is valid. Additional checks must be made on the chain. - */ -static int -ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - /* Must be a valid CA. Should we really support the "I don't know" - value (2)? */ - if (ca) - return check_ca(x); - /* leaf certificate is checked in OCSP_verify() */ - return 1; -} - -static int -check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - int i_ext; - - /* If ca is true we must return if this is a valid CA certificate. */ - if (ca) - return check_ca(x); - - /* - * Check the optional key usage field: - * if Key Usage is present, it must be one of digitalSignature - * and/or nonRepudiation (other values are not consistent and shall - * be rejected). - */ - if ((x->ex_flags & EXFLAG_KUSAGE) && - ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || - !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) - return 0; - - /* Only time stamp key usage is permitted and it's required. */ - if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) - return 0; - - /* Extended Key Usage MUST be critical */ - i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1); - if (i_ext >= 0) { - X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext); - if (!X509_EXTENSION_get_critical(ext)) - return 0; - } - - return 1; -} - -static int -no_check(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - return 1; -} - -/* Various checks to see if one certificate issued the second. - * This can be used to prune a set of possible issuer certificates - * which have been looked up using some simple method such as by - * subject name. - * These are: - * 1. Check issuer_name(subject) == subject_name(issuer) - * 2. If akid(subject) exists check it matches issuer - * 3. If key_usage(issuer) exists check it supports certificate signing - * returns 0 for OK, positive for reason for mismatch, reasons match - * codes for X509_verify_cert() - */ - -int -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; - - if (!x509v3_cache_extensions(issuer)) - return X509_V_ERR_UNSPECIFIED; - if (!x509v3_cache_extensions(subject)) - return X509_V_ERR_UNSPECIFIED; - - if (subject->akid) { - int ret = X509_check_akid(issuer, subject->akid); - if (ret != X509_V_OK) - return ret; - } - - if (ku_reject(issuer, KU_KEY_CERT_SIGN)) - return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; - return X509_V_OK; -} -LCRYPTO_ALIAS(X509_check_issued); - -int -X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) -{ - if (!akid) - return X509_V_OK; - - /* Check key ids (if present) */ - if (akid->keyid && issuer->skid && - ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) - return X509_V_ERR_AKID_SKID_MISMATCH; - /* Check serial number */ - if (akid->serial && - ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; - /* Check issuer name */ - if (akid->issuer) { - /* Ugh, for some peculiar reason AKID includes - * SEQUENCE OF GeneralName. So look for a DirName. - * There may be more than one but we only take any - * notice of the first. - */ - GENERAL_NAMES *gens; - GENERAL_NAME *gen; - X509_NAME *nm = NULL; - int i; - gens = akid->issuer; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type == GEN_DIRNAME) { - nm = gen->d.dirn; - break; - } - } - if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; - } - return X509_V_OK; -} -LCRYPTO_ALIAS(X509_check_akid); - -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 EXFLAG_INVALID; - - return x->ex_flags; -} -LCRYPTO_ALIAS(X509_get_extension_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; -} -LCRYPTO_ALIAS(X509_get_key_usage); - -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; -} -LCRYPTO_ALIAS(X509_get_extended_key_usage); diff --git a/src/lib/libcrypto/x509/x509_r2x.c b/src/lib/libcrypto/x509/x509_r2x.c deleted file mode 100644 index 39b392259b..0000000000 --- a/src/lib/libcrypto/x509/x509_r2x.c +++ /dev/null @@ -1,117 +0,0 @@ -/* $OpenBSD: x509_r2x.c,v 1.17 2023/04/25 09:46:36 job Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "x509_local.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); - goto err; - } - - /* duplicate the request */ - xi = ret->cert_info; - - if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { - if (!X509_set_version(ret, 2)) - goto err; - } - - xn = X509_REQ_get_subject_name(r); - if (X509_set_subject_name(ret, xn) == 0) - goto err; - if (X509_set_issuer_name(ret, xn) == 0) - goto err; - - if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) - goto err; - if (X509_gmtime_adj(xi->validity->notAfter, - (long)60 * 60 * 24 * days) == NULL) - goto err; - - 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; - return ret; - -err: - X509_free(ret); - return NULL; -} -LCRYPTO_ALIAS(X509_REQ_to_X509); diff --git a/src/lib/libcrypto/x509/x509_req.c b/src/lib/libcrypto/x509/x509_req.c deleted file mode 100644 index 704acbd897..0000000000 --- a/src/lib/libcrypto/x509/x509_req.c +++ /dev/null @@ -1,320 +0,0 @@ -/* $OpenBSD: x509_req.c,v 1.43 2024/08/31 10:16:52 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "asn1_local.h" -#include "evp_local.h" -#include "x509_local.h" - -X509_REQ * -X509_to_X509_REQ(X509 *x509, EVP_PKEY *signing_key, const EVP_MD *signing_md) -{ - X509_REQ *req; - X509_NAME *subject; - EVP_PKEY *public_key; - - if ((req = X509_REQ_new()) == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((subject = X509_get_subject_name(x509)) == NULL) - goto err; - if (!X509_REQ_set_subject_name(req, subject)) - goto err; - - if ((public_key = X509_get0_pubkey(x509)) == NULL) - goto err; - if (!X509_REQ_set_pubkey(req, public_key)) - goto err; - - if (signing_key != NULL) { - if (!X509_REQ_sign(req, signing_key, signing_md)) - goto err; - } - - return req; - - err: - X509_REQ_free(req); - - return NULL; -} -LCRYPTO_ALIAS(X509_to_X509_REQ); - -EVP_PKEY * -X509_REQ_get_pubkey(X509_REQ *req) -{ - if (req == NULL || req->req_info == NULL) - return NULL; - return X509_PUBKEY_get(req->req_info->pubkey); -} -LCRYPTO_ALIAS(X509_REQ_get_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); -} -LCRYPTO_ALIAS(X509_REQ_get0_pubkey); - -int -X509_REQ_check_private_key(X509_REQ *req, EVP_PKEY *pkey) -{ - EVP_PKEY *req_pubkey = NULL; - int ret; - - if ((req_pubkey = X509_REQ_get0_pubkey(req)) == NULL) - return 0; - - if ((ret = EVP_PKEY_cmp(req_pubkey, pkey)) == 1) - return 1; - - switch (ret) { - case 0: - X509error(X509_R_KEY_VALUES_MISMATCH); - return 0; - case -1: - X509error(X509_R_KEY_TYPE_MISMATCH); - return 0; - case -2: -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - X509error(ERR_R_EC_LIB); - return 0; - } -#endif -#ifndef OPENSSL_NO_DH - if (pkey->type == EVP_PKEY_DH) { - /* No idea */ - X509error(X509_R_CANT_CHECK_DH_KEY); - return 0; - } -#endif - X509error(X509_R_UNKNOWN_KEY_TYPE); - return 0; - } - - return 0; -} -LCRYPTO_ALIAS(X509_REQ_check_private_key); - -int -X509_REQ_extension_nid(int nid) -{ - return nid == NID_ext_req || nid == NID_ms_ext_req; -} -LCRYPTO_ALIAS(X509_REQ_extension_nid); - -STACK_OF(X509_EXTENSION) * -X509_REQ_get_extensions(X509_REQ *req) -{ - X509_ATTRIBUTE *attr; - ASN1_TYPE *ext = NULL; - int idx; - - if (req == NULL || req->req_info == NULL) - return NULL; - - if ((idx = X509_REQ_get_attr_by_NID(req, NID_ext_req, -1)) == -1) - idx = X509_REQ_get_attr_by_NID(req, NID_ms_ext_req, -1); - if (idx == -1) - return NULL; - - if ((attr = X509_REQ_get_attr(req, idx)) == NULL) - return NULL; - if ((ext = X509_ATTRIBUTE_get0_type(attr, 0)) == NULL) - return NULL; - - return ASN1_TYPE_unpack_sequence(&X509_EXTENSIONS_it, ext); -} -LCRYPTO_ALIAS(X509_REQ_get_extensions); - -/* - * 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) -{ - unsigned char *ext = NULL; - int extlen; - int ret; - - if ((extlen = i2d_X509_EXTENSIONS(exts, &ext)) <= 0) - return 0; - - ret = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); - free(ext); - - return ret; -} -LCRYPTO_ALIAS(X509_REQ_add_extensions_nid); - -/* This is the normal usage: use the "official" OID */ -int -X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) -{ - return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); -} -LCRYPTO_ALIAS(X509_REQ_add_extensions); - -/* Request attribute functions */ - -int -X509_REQ_get_attr_count(const X509_REQ *req) -{ - return sk_X509_ATTRIBUTE_num(req->req_info->attributes); -} -LCRYPTO_ALIAS(X509_REQ_get_attr_count); - -int -X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) -{ - return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); -} -LCRYPTO_ALIAS(X509_REQ_get_attr_by_NID); - -int -X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, - int lastpos) -{ - return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); -} -LCRYPTO_ALIAS(X509_REQ_get_attr_by_OBJ); - -X509_ATTRIBUTE * -X509_REQ_get_attr(const X509_REQ *req, int loc) -{ - return sk_X509_ATTRIBUTE_value(req->req_info->attributes, loc); -} -LCRYPTO_ALIAS(X509_REQ_get_attr); - -X509_ATTRIBUTE * -X509_REQ_delete_attr(X509_REQ *req, int loc) -{ - return sk_X509_ATTRIBUTE_delete(req->req_info->attributes, loc); -} -LCRYPTO_ALIAS(X509_REQ_delete_attr); - -int -X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) -{ - if (X509at_add1_attr(&req->req_info->attributes, attr)) - return 1; - return 0; -} -LCRYPTO_ALIAS(X509_REQ_add1_attr); - -int -X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, - type, bytes, len)) - return 1; - return 0; -} -LCRYPTO_ALIAS(X509_REQ_add1_attr_by_OBJ); - -int -X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, - type, bytes, len)) - return 1; - return 0; -} -LCRYPTO_ALIAS(X509_REQ_add1_attr_by_NID); - -int -X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, - type, bytes, len)) - return 1; - return 0; -} -LCRYPTO_ALIAS(X509_REQ_add1_attr_by_txt); - -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); -} -LCRYPTO_ALIAS(i2d_re_X509_REQ_tbs); diff --git a/src/lib/libcrypto/x509/x509_set.c b/src/lib/libcrypto/x509/x509_set.c deleted file mode 100644 index 442bc12827..0000000000 --- a/src/lib/libcrypto/x509/x509_set.c +++ /dev/null @@ -1,268 +0,0 @@ -/* $OpenBSD: x509_set.c,v 1.29 2024/03/26 23:21:36 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -const STACK_OF(X509_EXTENSION) * -X509_get0_extensions(const X509 *x) -{ - return x->cert_info->extensions; -} -LCRYPTO_ALIAS(X509_get0_extensions); - -const X509_ALGOR * -X509_get0_tbs_sigalg(const X509 *x) -{ - return x->cert_info->signature; -} -LCRYPTO_ALIAS(X509_get0_tbs_sigalg); - -int -X509_set_version(X509 *x, long version) -{ - if (x == NULL) - return 0; - /* - * RFC 5280, 4.1: versions 1 - 3 are specified as follows. - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - if (version < 0 || version > 2) - return 0; - if (x->cert_info->version == NULL) { - if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL) - return 0; - } - x->cert_info->enc.modified = 1; - return ASN1_INTEGER_set(x->cert_info->version, version); -} -LCRYPTO_ALIAS(X509_set_version); - -long -X509_get_version(const X509 *x) -{ - return ASN1_INTEGER_get(x->cert_info->version); -} -LCRYPTO_ALIAS(X509_get_version); - -int -X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in; - - if (x == NULL) - return 0; - in = x->cert_info->serialNumber; - if (in != serial) { - in = ASN1_INTEGER_dup(serial); - if (in != NULL) { - x->cert_info->enc.modified = 1; - ASN1_INTEGER_free(x->cert_info->serialNumber); - x->cert_info->serialNumber = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_set_serialNumber); - -int -X509_set_issuer_name(X509 *x, X509_NAME *name) -{ - if (x == NULL || x->cert_info == NULL) - return 0; - x->cert_info->enc.modified = 1; - return X509_NAME_set(&x->cert_info->issuer, name); -} -LCRYPTO_ALIAS(X509_set_issuer_name); - -int -X509_set_subject_name(X509 *x, X509_NAME *name) -{ - if (x == NULL || x->cert_info == NULL) - return 0; - x->cert_info->enc.modified = 1; - return X509_NAME_set(&x->cert_info->subject, name); -} -LCRYPTO_ALIAS(X509_set_subject_name); - -const ASN1_TIME * -X509_get0_notBefore(const X509 *x) -{ - return X509_getm_notBefore(x); -} -LCRYPTO_ALIAS(X509_get0_notBefore); - -ASN1_TIME * -X509_getm_notBefore(const X509 *x) -{ - if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL) - return NULL; - return x->cert_info->validity->notBefore; -} -LCRYPTO_ALIAS(X509_getm_notBefore); - -int -X509_set_notBefore(X509 *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL || x->cert_info->validity == NULL) - return 0; - in = x->cert_info->validity->notBefore; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - x->cert_info->enc.modified = 1; - ASN1_TIME_free(x->cert_info->validity->notBefore); - x->cert_info->validity->notBefore = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_set_notBefore); - -int -X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) -{ - return X509_set_notBefore(x, tm); -} -LCRYPTO_ALIAS(X509_set1_notBefore); - -const ASN1_TIME * -X509_get0_notAfter(const X509 *x) -{ - return X509_getm_notAfter(x); -} -LCRYPTO_ALIAS(X509_get0_notAfter); - -ASN1_TIME * -X509_getm_notAfter(const X509 *x) -{ - if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL) - return NULL; - return x->cert_info->validity->notAfter; -} -LCRYPTO_ALIAS(X509_getm_notAfter); - -int -X509_set_notAfter(X509 *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL || x->cert_info->validity == NULL) - return 0; - in = x->cert_info->validity->notAfter; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - x->cert_info->enc.modified = 1; - ASN1_TIME_free(x->cert_info->validity->notAfter); - x->cert_info->validity->notAfter = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_set_notAfter); - -int -X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) -{ - return X509_set_notAfter(x, tm); -} -LCRYPTO_ALIAS(X509_set1_notAfter); - -int -X509_set_pubkey(X509 *x, EVP_PKEY *pkey) -{ - if (x == NULL || x->cert_info == NULL) - return 0; - x->cert_info->enc.modified = 1; - return X509_PUBKEY_set(&x->cert_info->key, pkey); -} -LCRYPTO_ALIAS(X509_set_pubkey); - -int -X509_get_signature_type(const X509 *x) -{ - return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm)); -} -LCRYPTO_ALIAS(X509_get_signature_type); - -X509_PUBKEY * -X509_get_X509_PUBKEY(const X509 *x) -{ - return x->cert_info->key; -} -LCRYPTO_ALIAS(X509_get_X509_PUBKEY); - -void -X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **issuerUID, - const ASN1_BIT_STRING **subjectUID) -{ - if (issuerUID != NULL) - *issuerUID = x->cert_info->issuerUID; - if (subjectUID != NULL) - *subjectUID = x->cert_info->subjectUID; -} -LCRYPTO_ALIAS(X509_get0_uids); diff --git a/src/lib/libcrypto/x509/x509_siginfo.c b/src/lib/libcrypto/x509/x509_siginfo.c deleted file mode 100644 index 9bbb133216..0000000000 --- a/src/lib/libcrypto/x509/x509_siginfo.c +++ /dev/null @@ -1,113 +0,0 @@ -/* $OpenBSD: x509_siginfo.c,v 1.1 2024/08/28 07:15:04 tb Exp $ */ - -/* - * Copyright (c) 2024 Theo Buehler - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include "evp_local.h" - -#include "x509_internal.h" - -static int -x509_find_sigid_algs(const X509 *x509, int *out_md_nid, int *out_pkey_nid) -{ - const ASN1_OBJECT *aobj; - int nid; - - *out_md_nid = NID_undef; - *out_pkey_nid = NID_undef; - - X509_ALGOR_get0(&aobj, NULL, NULL, x509->sig_alg); - if ((nid = OBJ_obj2nid(aobj)) == NID_undef) - return 0; - - return OBJ_find_sigid_algs(nid, out_md_nid, out_pkey_nid); -} - -int -X509_get_signature_info(X509 *x509, int *out_md_nid, int *out_pkey_nid, - int *out_security_bits, uint32_t *out_flags) -{ - const EVP_MD *md; - int md_nid = NID_undef, pkey_nid = NID_undef, security_bits = -1; - uint32_t flags = 0; - - if (out_md_nid != NULL) - *out_md_nid = md_nid; - if (out_pkey_nid != NULL) - *out_pkey_nid = pkey_nid; - if (out_security_bits != NULL) - *out_security_bits = security_bits; - if (out_flags != NULL) - *out_flags = flags; - - if (!x509v3_cache_extensions(x509)) - goto err; - - if (!x509_find_sigid_algs(x509, &md_nid, &pkey_nid)) - goto err; - - /* - * If md_nid == NID_undef, this means we need to consult the ameth. - * Handlers are available for EdDSA and RSA-PSS. No other signature - * algorithm with NID_undef should appear in a certificate. - */ - if (md_nid == NID_undef) { - const EVP_PKEY_ASN1_METHOD *ameth; - - if ((ameth = EVP_PKEY_asn1_find(NULL, pkey_nid)) == NULL || - ameth->signature_info == NULL) - goto err; - - if (!ameth->signature_info(x509->sig_alg, &md_nid, &pkey_nid, - &security_bits, &flags)) - goto err; - - goto done; - } - - /* XXX - OpenSSL 3 special cases SHA-1 (63 bits) and MD5 (39 bits). */ - if ((md = EVP_get_digestbynid(md_nid)) == NULL) - goto err; - - /* Assume 4 bits of collision resistance per octet. */ - if ((security_bits = EVP_MD_size(md)) <= 0) - goto err; - security_bits *= 4; - - if (md_nid == NID_sha1 || md_nid == NID_sha256 || - md_nid == NID_sha384 || md_nid == NID_sha512) - flags |= X509_SIG_INFO_TLS; - - flags |= X509_SIG_INFO_VALID; - - done: - if (out_md_nid != NULL) - *out_md_nid = md_nid; - if (out_pkey_nid != NULL) - *out_pkey_nid = pkey_nid; - if (out_security_bits != NULL) - *out_security_bits = security_bits; - if (out_flags != NULL) - *out_flags = flags; - - err: - return (flags & X509_SIG_INFO_VALID) != 0; -} -LCRYPTO_ALIAS(X509_get_signature_info); diff --git a/src/lib/libcrypto/x509/x509_skey.c b/src/lib/libcrypto/x509/x509_skey.c deleted file mode 100644 index d2c90b6f1c..0000000000 --- a/src/lib/libcrypto/x509/x509_skey.c +++ /dev/null @@ -1,171 +0,0 @@ -/* $OpenBSD: x509_skey.c,v 1.6 2024/07/13 15:08:58 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include - -#include "x509_local.h" - -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); - -static const X509V3_EXT_METHOD x509v3_ext_subject_key_identifier = { - .ext_nid = NID_subject_key_identifier, - .ext_flags = 0, - .it = &ASN1_OCTET_STRING_it, - .ext_new = NULL, - .ext_free = NULL, - .d2i = NULL, - .i2d = NULL, - .i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, - .s2i = (X509V3_EXT_S2I)s2i_skey_id, - .i2v = NULL, - .v2i = NULL, - .i2r = NULL, - .r2i = NULL, - .usr_data = NULL, -}; - -const X509V3_EXT_METHOD * -x509v3_ext_method_subject_key_identifier(void) -{ - return &x509v3_ext_subject_key_identifier; -} - -char * -i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, const ASN1_OCTET_STRING *oct) -{ - return hex_to_string(oct->data, oct->length); -} -LCRYPTO_ALIAS(i2s_ASN1_OCTET_STRING); - -ASN1_OCTET_STRING * -s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - const char *str) -{ - ASN1_OCTET_STRING *oct; - long length; - - if (!(oct = ASN1_OCTET_STRING_new())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!(oct->data = string_to_hex(str, &length))) { - ASN1_OCTET_STRING_free(oct); - return NULL; - } - - oct->length = length; - - return oct; -} -LCRYPTO_ALIAS(s2i_ASN1_OCTET_STRING); - -static ASN1_OCTET_STRING * -s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) -{ - ASN1_OCTET_STRING *oct; - ASN1_BIT_STRING *pk; - unsigned char pkey_dig[EVP_MAX_MD_SIZE]; - unsigned int diglen; - - if (strcmp(str, "hash")) - return s2i_ASN1_OCTET_STRING(method, ctx, str); - - if (!(oct = ASN1_OCTET_STRING_new())) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (ctx && (ctx->flags == CTX_TEST)) - return oct; - - if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { - X509V3error(X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - if (ctx->subject_req) - pk = ctx->subject_req->req_info->pubkey->public_key; - else - pk = ctx->subject_cert->cert_info->key->public_key; - - if (!pk) { - X509V3error(X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, - EVP_sha1(), NULL)) - goto err; - - if (!ASN1_STRING_set(oct, pkey_dig, diglen)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - - return oct; - -err: - ASN1_OCTET_STRING_free(oct); - return NULL; -} diff --git a/src/lib/libcrypto/x509/x509_trs.c b/src/lib/libcrypto/x509/x509_trs.c deleted file mode 100644 index e7e42a83cd..0000000000 --- a/src/lib/libcrypto/x509/x509_trs.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $OpenBSD: x509_trs.c,v 1.58 2024/08/31 10:12:23 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include -#include -#include -#include - -#include "x509_internal.h" -#include "x509_local.h" - -static int -trust_if_self_signed(const X509 *x) -{ - /* Extensions already cached in X509_check_trust(). */ - if ((x->ex_flags & EXFLAG_SS) != 0) - return X509_TRUST_TRUSTED; - - return X509_TRUST_UNTRUSTED; -} - -static int -trust_was_set(const X509 *x) -{ - return x->aux != NULL && (x->aux->trust != NULL || - x->aux->reject != NULL); -} - -static int -obj_trust(int id, const X509 *x) -{ - const X509_CERT_AUX *aux; - ASN1_OBJECT *obj; - int i, nid; - - if ((aux = x->aux) == NULL) - return X509_TRUST_UNTRUSTED; - - for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { - obj = sk_ASN1_OBJECT_value(aux->reject, i); - nid = OBJ_obj2nid(obj); - if (nid == id || nid == NID_anyExtendedKeyUsage) - return X509_TRUST_REJECTED; - } - - for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { - obj = sk_ASN1_OBJECT_value(aux->trust, i); - nid = OBJ_obj2nid(obj); - if (nid == id || nid == NID_anyExtendedKeyUsage) - return X509_TRUST_TRUSTED; - } - - return X509_TRUST_UNTRUSTED; -} - -static int -nid_from_trust_id(int trust_id) -{ - OPENSSL_assert(trust_id == 0 || - (trust_id >= X509_TRUST_MIN && trust_id <= X509_TRUST_MAX)); - - switch (trust_id) { - case X509_TRUST_COMPAT: - return NID_undef; - case X509_TRUST_SSL_CLIENT: - return NID_client_auth; - case X509_TRUST_SSL_SERVER: - return NID_server_auth; - case X509_TRUST_EMAIL: - return NID_email_protect; - case X509_TRUST_OBJECT_SIGN: - return NID_code_sign; - case X509_TRUST_OCSP_SIGN: - return NID_OCSP_sign; - case X509_TRUST_OCSP_REQUEST: - return NID_ad_OCSP; - case X509_TRUST_TSA: - return NID_time_stamp; - default: - return NID_undef; - } -} - -int -X509_check_trust(X509 *x, int trust_id, int flags) -{ - int rv; - - /* Call early so the trust handlers don't need to modify the certs. */ - if (!x509v3_cache_extensions(x)) - return X509_TRUST_UNTRUSTED; - - if (trust_id == X509_TRUST_ACCEPT_ALL) - return 1; - - switch (trust_id) { - case X509_TRUST_COMPAT: - return trust_if_self_signed(x); - case X509_TRUST_EMAIL: - case X509_TRUST_OBJECT_SIGN: - case X509_TRUST_SSL_SERVER: - case X509_TRUST_SSL_CLIENT: - case X509_TRUST_TSA: - if (trust_was_set(x)) - return obj_trust(nid_from_trust_id(trust_id), x); - return trust_if_self_signed(x); - case X509_TRUST_OCSP_SIGN: - case X509_TRUST_OCSP_REQUEST: - return obj_trust(nid_from_trust_id(trust_id), x); - default: - rv = obj_trust(NID_anyExtendedKeyUsage, x); - if (rv != X509_TRUST_UNTRUSTED) - return rv; - return trust_if_self_signed(x); - } -} diff --git a/src/lib/libcrypto/x509/x509_txt.c b/src/lib/libcrypto/x509/x509_txt.c deleted file mode 100644 index 5f5bc5ae84..0000000000 --- a/src/lib/libcrypto/x509/x509_txt.c +++ /dev/null @@ -1,196 +0,0 @@ -/* $OpenBSD: x509_txt.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -const char * -X509_verify_cert_error_string(long n) -{ - switch ((int)n) { - case X509_V_OK: - return "ok"; - case X509_V_ERR_UNSPECIFIED: - return "Unspecified certificate verification error"; - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - return "unable to get issuer certificate"; - case X509_V_ERR_UNABLE_TO_GET_CRL: - return "unable to get certificate CRL"; - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - return "unable to decrypt certificate's signature"; - case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - return "unable to decrypt CRL's signature"; - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - return "unable to decode issuer public key"; - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - return "certificate signature failure"; - case X509_V_ERR_CRL_SIGNATURE_FAILURE: - return "CRL signature failure"; - case X509_V_ERR_CERT_NOT_YET_VALID: - return "certificate is not yet valid"; - case X509_V_ERR_CERT_HAS_EXPIRED: - return "certificate has expired"; - case X509_V_ERR_CRL_NOT_YET_VALID: - return "CRL is not yet valid"; - case X509_V_ERR_CRL_HAS_EXPIRED: - return "CRL has expired"; - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - return "format error in certificate's notBefore field"; - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - return "format error in certificate's notAfter field"; - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - return "format error in CRL's lastUpdate field"; - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - return "format error in CRL's nextUpdate field"; - case X509_V_ERR_OUT_OF_MEM: - return "out of memory"; - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - return "self signed certificate"; - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - return "self signed certificate in certificate chain"; - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - return "unable to get local issuer certificate"; - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - return "unable to verify the first certificate"; - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - return "certificate chain too long"; - case X509_V_ERR_CERT_REVOKED: - return "certificate revoked"; - case X509_V_ERR_INVALID_CA: - return "invalid CA certificate"; - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - return "path length constraint exceeded"; - case X509_V_ERR_INVALID_PURPOSE: - return "unsupported certificate purpose"; - case X509_V_ERR_CERT_UNTRUSTED: - return "certificate not trusted"; - case X509_V_ERR_CERT_REJECTED: - return "certificate rejected"; - case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: - return "subject issuer mismatch"; - case X509_V_ERR_AKID_SKID_MISMATCH: - return "authority and subject key identifier mismatch"; - case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: - return "authority and issuer serial number mismatch"; - case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: - return "key usage does not include certificate signing"; - case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: - return "unable to get CRL issuer certificate"; - case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: - return "unhandled critical extension"; - case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: - return "key usage does not include CRL signing"; - case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: - return "unhandled critical CRL extension"; - case X509_V_ERR_INVALID_NON_CA: - return "invalid non-CA certificate (has CA markings)"; - case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: - return "proxy path length constraint exceeded"; - case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: - return "key usage does not include digital signature"; - case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: - return "proxy certificates not allowed, " - "please set the appropriate flag"; - case X509_V_ERR_INVALID_EXTENSION: - return "invalid or inconsistent certificate extension"; - case X509_V_ERR_INVALID_POLICY_EXTENSION: - return "invalid or inconsistent certificate policy extension"; - case X509_V_ERR_NO_EXPLICIT_POLICY: - return "no explicit policy"; - case X509_V_ERR_DIFFERENT_CRL_SCOPE: - return "Different CRL scope"; - case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: - return "Unsupported extension feature"; - case X509_V_ERR_UNNESTED_RESOURCE: - return "RFC 3779 resource not subset of parent's resources"; - case X509_V_ERR_PERMITTED_VIOLATION: - return "permitted subtree violation"; - case X509_V_ERR_EXCLUDED_VIOLATION: - return "excluded subtree violation"; - case X509_V_ERR_SUBTREE_MINMAX: - return "name constraints minimum and maximum not supported"; - case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: - return "unsupported name constraint type"; - case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: - return "unsupported or invalid name constraint syntax"; - case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: - return "unsupported or invalid name syntax"; - case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: - return "CRL path validation error"; - case X509_V_ERR_APPLICATION_VERIFICATION: - return "application verification failure"; - case X509_V_ERR_HOSTNAME_MISMATCH: - return "Hostname mismatch"; - case X509_V_ERR_EMAIL_MISMATCH: - return "Email address mismatch"; - case X509_V_ERR_IP_ADDRESS_MISMATCH: - return "IP address mismatch"; - case X509_V_ERR_INVALID_CALL: - return "Invalid certificate verification context"; - case X509_V_ERR_STORE_LOOKUP: - return "Issuer certificate lookup error"; - case X509_V_ERR_EE_KEY_TOO_SMALL: - return "EE certificate key too weak"; - case X509_V_ERR_CA_KEY_TOO_SMALL: - return "CA certificate key too weak"; - case X509_V_ERR_CA_MD_TOO_WEAK: - return "CA signature digest algorithm too weak"; - default: - return "Unknown certificate verification error"; - } -} -LCRYPTO_ALIAS(X509_verify_cert_error_string); diff --git a/src/lib/libcrypto/x509/x509_utl.c b/src/lib/libcrypto/x509/x509_utl.c deleted file mode 100644 index 08383849c9..0000000000 --- a/src/lib/libcrypto/x509/x509_utl.c +++ /dev/null @@ -1,1494 +0,0 @@ -/* $OpenBSD: x509_utl.c,v 1.26 2025/01/26 13:51:41 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "bytestring.h" -#include "conf_local.h" - -/* - * Match reference identifiers starting with "." to any sub-domain. This - * flag is set implicitly when the subject reference identity is a DNS name. - */ -#define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 - -static char *bn_to_string(const BIGNUM *bn); -static char *strip_spaces(char *name); -static int sk_strcmp(const char * const *a, const char * const *b); -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, - GENERAL_NAMES *gens); -static void str_free(OPENSSL_STRING str); -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); - -static int ipv4_from_asc(unsigned char *v4, const char *in); -static int ipv6_from_asc(unsigned char *v6, const char *in); -static int ipv6_cb(const char *elem, int len, void *usr); -static int ipv6_hex(unsigned char *out, const char *in, int inlen); - -/* Add a CONF_VALUE name-value pair to stack. */ -int -X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **out_extlist) -{ - STACK_OF(CONF_VALUE) *extlist = NULL; - CONF_VALUE *conf_value = NULL; - int ret = 0; - - if ((conf_value = calloc(1, sizeof(*conf_value))) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - if (name != NULL) { - if ((conf_value->name = strdup(name)) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - } - if (value != NULL) { - if ((conf_value->value = strdup(value)) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if ((extlist = *out_extlist) == NULL) - extlist = sk_CONF_VALUE_new_null(); - if (extlist == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!sk_CONF_VALUE_push(extlist, conf_value)) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - conf_value = NULL; - - *out_extlist = extlist; - extlist = NULL; - - ret = 1; - - err: - if (extlist != *out_extlist) - sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free); - X509V3_conf_free(conf_value); - - return ret; -} - -int -X509V3_add_value_uchar(const char *name, const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist) -{ - return X509V3_add_value(name, (const char *)value, extlist); -} - -/* Free function for STACK_OF(CONF_VALUE) */ - -void -X509V3_conf_free(CONF_VALUE *conf) -{ - if (!conf) - return; - free(conf->name); - free(conf->value); - free(conf->section); - free(conf); -} -LCRYPTO_ALIAS(X509V3_conf_free); - -int -X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist) -{ - if (asn1_bool) - return X509V3_add_value(name, "TRUE", extlist); - return X509V3_add_value(name, "FALSE", extlist); -} - -static char * -bn_to_string(const BIGNUM *bn) -{ - const char *sign = ""; - char *bnstr, *hex; - char *ret = NULL; - - /* Only display small numbers in decimal, as conversion is quadratic. */ - if (BN_num_bits(bn) < 128) - return BN_bn2dec(bn); - - if ((hex = bnstr = BN_bn2hex(bn)) == NULL) - goto err; - - if (BN_is_negative(bn)) { - sign = "-"; - hex++; - } - - if (asprintf(&ret, "%s0x%s", sign, hex) == -1) - ret = NULL; - - err: - free(bnstr); - return ret; -} - -char * -i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) -{ - BIGNUM *bntmp; - char *strtmp = NULL; - - if (a == NULL) - return NULL; - if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL || - (strtmp = bn_to_string(bntmp)) == NULL) - X509V3error(ERR_R_MALLOC_FAILURE); - BN_free(bntmp); - return strtmp; -} -LCRYPTO_ALIAS(i2s_ASN1_ENUMERATED); - -char * -i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *e) -{ - const BIT_STRING_BITNAME *enam; - long strval; - - strval = ASN1_ENUMERATED_get(e); - for (enam = method->usr_data; enam->lname; enam++) { - if (strval == enam->bitnum) - return strdup(enam->lname); - } - return i2s_ASN1_ENUMERATED(method, e); -} -LCRYPTO_ALIAS(i2s_ASN1_ENUMERATED_TABLE); - -char * -i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) -{ - BIGNUM *bntmp; - char *strtmp = NULL; - - if (a == NULL) - return NULL; - if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL || - (strtmp = bn_to_string(bntmp)) == NULL) - X509V3error(ERR_R_MALLOC_FAILURE); - BN_free(bntmp); - return strtmp; -} -LCRYPTO_ALIAS(i2s_ASN1_INTEGER); - -ASN1_INTEGER * -s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) -{ - BIGNUM *bn = NULL; - ASN1_INTEGER *aint; - int isneg = 0, ishex = 0; - int ret; - - if (!value) { - X509V3error(X509V3_R_INVALID_NULL_VALUE); - return NULL; - } - if ((bn = BN_new()) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - return NULL; - } - if (value[0] == '-') { - value++; - isneg = 1; - } - - if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { - value += 2; - ishex = 1; - } - - if (ishex) - ret = BN_hex2bn(&bn, value); - else - ret = BN_dec2bn(&bn, value); - - if (!ret || value[ret]) { - BN_free(bn); - X509V3error(X509V3_R_BN_DEC2BN_ERROR); - return NULL; - } - - if (BN_is_zero(bn)) - isneg = 0; - - aint = BN_to_ASN1_INTEGER(bn, NULL); - BN_free(bn); - if (!aint) { - X509V3error(X509V3_R_BN_TO_ASN1_INTEGER_ERROR); - return NULL; - } - if (isneg) - aint->type |= V_ASN1_NEG; - return aint; -} -LCRYPTO_ALIAS(s2i_ASN1_INTEGER); - -int -X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist) -{ - char *strtmp; - int ret; - - if (!aint) - return 1; - if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) - return 0; - ret = X509V3_add_value(name, strtmp, extlist); - free(strtmp); - return ret; -} - -int -X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool) -{ - char *btmp; - - if (!(btmp = value->value)) - goto err; - if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") || - !strcmp(btmp, "Y") || !strcmp(btmp, "y") || - !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { - *asn1_bool = 0xff; - return 1; - } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") || - !strcmp(btmp, "N") || !strcmp(btmp, "n") || - !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { - *asn1_bool = 0; - return 1; - } - - err: - X509V3error(X509V3_R_INVALID_BOOLEAN_STRING); - X509V3_conf_err(value); - return 0; -} - -int -X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) -{ - ASN1_INTEGER *itmp; - - if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { - X509V3_conf_err(value); - return 0; - } - *aint = itmp; - return 1; -} - -#define HDR_NAME 1 -#define HDR_VALUE 2 - -/*#define DEBUG*/ - -STACK_OF(CONF_VALUE) * -X509V3_parse_list(const char *line) -{ - char *p, *q, c; - char *ntmp, *vtmp; - STACK_OF(CONF_VALUE) *values = NULL; - char *linebuf; - int state; - - /* We are going to modify the line so copy it first */ - if ((linebuf = strdup(line)) == NULL) { - X509V3error(ERR_R_MALLOC_FAILURE); - goto err; - } - state = HDR_NAME; - ntmp = NULL; - - /* Go through all characters */ - for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && - (c != '\n'); p++) { - - switch (state) { - case HDR_NAME: - if (c == ':') { - state = HDR_VALUE; - *p = 0; - ntmp = strip_spaces(q); - if (!ntmp) { - X509V3error(X509V3_R_INVALID_NULL_NAME); - goto err; - } - q = p + 1; - } else if (c == ',') { - *p = 0; - ntmp = strip_spaces(q); - q = p + 1; - if (!ntmp) { - X509V3error(X509V3_R_INVALID_NULL_NAME); - goto err; - } - if (!X509V3_add_value(ntmp, NULL, &values)) - goto err; - } - break; - - case HDR_VALUE: - if (c == ',') { - state = HDR_NAME; - *p = 0; - vtmp = strip_spaces(q); - if (!vtmp) { - X509V3error(X509V3_R_INVALID_NULL_VALUE); - goto err; - } - if (!X509V3_add_value(ntmp, vtmp, &values)) - goto err; - ntmp = NULL; - q = p + 1; - } - - } - } - - if (state == HDR_VALUE) { - vtmp = strip_spaces(q); - if (!vtmp) { - X509V3error(X509V3_R_INVALID_NULL_VALUE); - goto err; - } - if (!X509V3_add_value(ntmp, vtmp, &values)) - goto err; - } else { - ntmp = strip_spaces(q); - if (!ntmp) { - X509V3error(X509V3_R_INVALID_NULL_NAME); - goto err; - } - if (!X509V3_add_value(ntmp, NULL, &values)) - goto err; - } - free(linebuf); - return values; - - err: - free(linebuf); - sk_CONF_VALUE_pop_free(values, X509V3_conf_free); - return NULL; -} -LCRYPTO_ALIAS(X509V3_parse_list); - -/* Delete leading and trailing spaces from a string */ -static char * -strip_spaces(char *name) -{ - char *p, *q; - - /* Skip over leading spaces */ - p = name; - while (*p && isspace((unsigned char)*p)) - p++; - if (!*p) - return NULL; - q = p + strlen(p) - 1; - while ((q != p) && isspace((unsigned char)*q)) - q--; - if (p != q) - q[1] = 0; - if (!*p) - return NULL; - return p; -} - -static const char hex_digits[] = "0123456789ABCDEF"; - -char * -hex_to_string(const unsigned char *buffer, long len) -{ - CBB cbb; - CBS cbs; - uint8_t *out = NULL; - uint8_t c; - size_t out_len; - - if (!CBB_init(&cbb, 0)) - goto err; - - if (len < 0) - goto err; - - CBS_init(&cbs, buffer, len); - while (CBS_len(&cbs) > 0) { - if (!CBS_get_u8(&cbs, &c)) - goto err; - if (!CBB_add_u8(&cbb, hex_digits[c >> 4])) - goto err; - if (!CBB_add_u8(&cbb, hex_digits[c & 0xf])) - goto err; - if (CBS_len(&cbs) > 0) { - if (!CBB_add_u8(&cbb, ':')) - goto err; - } - } - - if (!CBB_add_u8(&cbb, '\0')) - goto err; - - if (!CBB_finish(&cbb, &out, &out_len)) - goto err; - - err: - CBB_cleanup(&cbb); - - return out; -} -LCRYPTO_ALIAS(hex_to_string); - -static int -x509_skip_colons_cbs(CBS *cbs) -{ - uint8_t c; - - while (CBS_len(cbs) > 0) { - if (!CBS_peek_u8(cbs, &c)) - return 0; - if (c != ':') - return 1; - if (!CBS_get_u8(cbs, &c)) - return 0; - } - - return 1; -} - -static int -x509_get_xdigit_nibble_cbs(CBS *cbs, uint8_t *out_nibble) -{ - uint8_t c; - - if (!CBS_get_u8(cbs, &c)) - return 0; - - if (c >= '0' && c <= '9') { - *out_nibble = c - '0'; - return 1; - } - if (c >= 'a' && c <= 'f') { - *out_nibble = c - 'a' + 10; - return 1; - } - if (c >= 'A' && c <= 'F') { - *out_nibble = c - 'A' + 10; - return 1; - } - - X509V3error(X509V3_R_ILLEGAL_HEX_DIGIT); - return 0; -} - -unsigned char * -string_to_hex(const char *str, long *len) -{ - CBB cbb; - CBS cbs; - uint8_t *out = NULL; - size_t out_len; - uint8_t hi, lo; - - *len = 0; - - if (!CBB_init(&cbb, 0)) - goto err; - - if (str == NULL) { - X509V3error(X509V3_R_INVALID_NULL_ARGUMENT); - goto err; - } - - CBS_init(&cbs, str, strlen(str)); - while (CBS_len(&cbs) > 0) { - /* - * Skipping only a single colon between two pairs of digits - * would make more sense - history... - */ - if (!x509_skip_colons_cbs(&cbs)) - goto err; - /* Another historic idiocy. */ - if (CBS_len(&cbs) == 0) - break; - if (!x509_get_xdigit_nibble_cbs(&cbs, &hi)) - goto err; - if (CBS_len(&cbs) == 0) { - X509V3error(X509V3_R_ODD_NUMBER_OF_DIGITS); - goto err; - } - if (!x509_get_xdigit_nibble_cbs(&cbs, &lo)) - goto err; - if (!CBB_add_u8(&cbb, hi << 4 | lo)) - goto err; - } - - if (!CBB_finish(&cbb, &out, &out_len)) - goto err; - if (out_len > LONG_MAX) { - freezero(out, out_len); - out = NULL; - goto err; - } - - *len = out_len; - - err: - CBB_cleanup(&cbb); - - return out; -} -LCRYPTO_ALIAS(string_to_hex); - -/* V2I name comparison function: returns zero if 'name' matches - * cmp or cmp.* - */ - -int -name_cmp(const char *name, const char *cmp) -{ - int len, ret; - char c; - - len = strlen(cmp); - if ((ret = strncmp(name, cmp, len))) - return ret; - c = name[len]; - if (!c || (c=='.')) - return 0; - return 1; -} - -static int -sk_strcmp(const char * const *a, const char * const *b) -{ - return strcmp(*a, *b); -} - -STACK_OF(OPENSSL_STRING) * -X509_get1_email(X509 *x) -{ - GENERAL_NAMES *gens; - STACK_OF(OPENSSL_STRING) *ret; - - gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - ret = get_email(X509_get_subject_name(x), gens); - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return ret; -} -LCRYPTO_ALIAS(X509_get1_email); - -STACK_OF(OPENSSL_STRING) * -X509_get1_ocsp(X509 *x) -{ - AUTHORITY_INFO_ACCESS *info; - STACK_OF(OPENSSL_STRING) *ret = NULL; - int i; - - info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); - if (!info) - return NULL; - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { - ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); - if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { - if (ad->location->type == GEN_URI) { - if (!append_ia5(&ret, - ad->location->d.uniformResourceIdentifier)) - break; - } - } - } - AUTHORITY_INFO_ACCESS_free(info); - return ret; -} -LCRYPTO_ALIAS(X509_get1_ocsp); - -STACK_OF(OPENSSL_STRING) * -X509_REQ_get1_email(X509_REQ *x) -{ - GENERAL_NAMES *gens; - STACK_OF(X509_EXTENSION) *exts; - STACK_OF(OPENSSL_STRING) *ret; - - exts = X509_REQ_get_extensions(x); - gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); - ret = get_email(X509_REQ_get_subject_name(x), gens); - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - return ret; -} -LCRYPTO_ALIAS(X509_REQ_get1_email); - - -static STACK_OF(OPENSSL_STRING) * -get_email(X509_NAME *name, GENERAL_NAMES *gens) -{ - STACK_OF(OPENSSL_STRING) *ret = NULL; - X509_NAME_ENTRY *ne; - ASN1_IA5STRING *email; - GENERAL_NAME *gen; - int i; - - /* Now add any email address(es) to STACK */ - i = -1; - - /* First supplied X509_NAME */ - while ((i = X509_NAME_get_index_by_NID(name, - NID_pkcs9_emailAddress, i)) >= 0) { - ne = X509_NAME_get_entry(name, i); - email = X509_NAME_ENTRY_get_data(ne); - if (!append_ia5(&ret, email)) - return NULL; - } - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != GEN_EMAIL) - continue; - if (!append_ia5(&ret, gen->d.ia5)) - return NULL; - } - return ret; -} - -static void -str_free(OPENSSL_STRING str) -{ - free(str); -} - -static int -append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) -{ - char *emtmp; - - /* First some sanity checks */ - if (email->type != V_ASN1_IA5STRING) - return 1; - if (!email->data || !email->length) - return 1; - if (!*sk) - *sk = sk_OPENSSL_STRING_new(sk_strcmp); - if (!*sk) - return 0; - /* Don't add duplicates */ - if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) - return 1; - emtmp = strdup((char *)email->data); - if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { - X509_email_free(*sk); - *sk = NULL; - return 0; - } - return 1; -} - -void -X509_email_free(STACK_OF(OPENSSL_STRING) *sk) -{ - sk_OPENSSL_STRING_pop_free(sk, str_free); -} -LCRYPTO_ALIAS(X509_email_free); - -typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, unsigned int flags); - -/* Skip pattern prefix to match "wildcard" subject */ -static void -skip_prefix(const unsigned char **p, size_t *plen, const unsigned char *subject, - size_t subject_len, unsigned int flags) -{ - const unsigned char *pattern = *p; - size_t pattern_len = *plen; - - /* - * If subject starts with a leading '.' followed by more octets, and - * pattern is longer, compare just an equal-length suffix with the - * full subject (starting at the '.'), provided the prefix contains - * no NULs. - */ - if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0) - return; - - while (pattern_len > subject_len && *pattern) { - if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) && - *pattern == '.') - break; - ++pattern; - --pattern_len; - } - - /* Skip if entire prefix acceptable */ - if (pattern_len == subject_len) { - *p = pattern; - *plen = pattern_len; - } -} - -/* - * Open/BoringSSL uses memcmp for "equal_case" while their - * "equal_nocase" function is a hand-rolled strncasecmp that does not - * allow \0 in the pattern. Since an embedded \0 is likely a sign of - * problems, we simply don't allow it in either case, and then we use - * standard libc functions. - */ - -/* Compare using strncasecmp */ -static int -equal_nocase(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, unsigned int flags) -{ - if (memchr(pattern, '\0', pattern_len) != NULL) - return 0; - if (memchr(subject, '\0', subject_len) != NULL) - return 0; - skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); - if (pattern_len != subject_len) - return 0; - return (strncasecmp(pattern, subject, pattern_len) == 0); -} - -/* Compare using strncmp. */ -static int -equal_case(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, unsigned int flags) -{ - if (memchr(pattern, 0, pattern_len) != NULL) - return 0; - if (memchr(subject, 0, subject_len) != NULL) - return 0; - skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); - if (pattern_len != subject_len) - return 0; - return (strncmp(pattern, subject, pattern_len) == 0); -} - -/* - * RFC 5280, section 7.5, requires that only the domain is compared in a - * case-insensitive manner. - */ -static int -equal_email(const unsigned char *a, size_t a_len, const unsigned char *b, - size_t b_len, unsigned int unused_flags) -{ - size_t pos = a_len; - if (a_len != b_len) - return 0; - /* - * We search backwards for the '@' character, so that we do not have to - * deal with quoted local-parts. The domain part is compared in a - * case-insensitive manner. - */ - while (pos > 0) { - pos--; - if (a[pos] == '@' || b[pos] == '@') { - if (!equal_nocase(a + pos, a_len - pos, b + pos, - a_len - pos, 0)) - return 0; - break; - } - } - if (pos == 0) - pos = a_len; - return equal_case(a, pos, b, pos, 0); -} - -/* - * Compare the prefix and suffix with the subject, and check that the - * characters in-between are valid. - */ -static int -wildcard_match(const unsigned char *prefix, size_t prefix_len, - const unsigned char *suffix, size_t suffix_len, - const unsigned char *subject, size_t subject_len, unsigned int flags) -{ - const unsigned char *wildcard_start; - const unsigned char *wildcard_end; - const unsigned char *p; - int allow_multi = 0; - int allow_idna = 0; - - if (subject_len < prefix_len + suffix_len) - return 0; - if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) - return 0; - wildcard_start = subject + prefix_len; - wildcard_end = subject + (subject_len - suffix_len); - if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) - return 0; - /* - * If the wildcard makes up the entire first label, it must match at - * least one character. - */ - if (prefix_len == 0 && *suffix == '.') { - if (wildcard_start == wildcard_end) - return 0; - allow_idna = 1; - if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS) - allow_multi = 1; - } - /* IDNA labels cannot match partial wildcards */ - if (!allow_idna && - subject_len >= 4 - && strncasecmp((char *)subject, "xn--", 4) == 0) - return 0; - /* The wildcard may match a literal '*' */ - if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') - return 1; - /* - * Check that the part matched by the wildcard contains only - * permitted characters and only matches a single label unless - * allow_multi is set. - */ - for (p = wildcard_start; p != wildcard_end; ++p) - if (!(('0' <= *p && *p <= '9') || ('A' <= *p && *p <= 'Z') || - ('a' <= *p && *p <= 'z') || *p == '-' || - (allow_multi && *p == '.'))) - return 0; - return 1; -} - -#define LABEL_START (1 << 0) -#define LABEL_END (1 << 1) -#define LABEL_HYPHEN (1 << 2) -#define LABEL_IDNA (1 << 3) - -static const unsigned char * -valid_star(const unsigned char *p, size_t len, unsigned int flags) -{ - const unsigned char *star = 0; - size_t i; - int state = LABEL_START; - int dots = 0; - for (i = 0; i < len; ++i) { - /* - * Locate first and only legal wildcard, either at the start - * or end of a non-IDNA first and not final label. - */ - if (p[i] == '*') { - int atstart = (state & LABEL_START); - int atend = (i == len - 1 || p[i + 1] == '.'); - /* - * At most one wildcard per pattern. - * No wildcards in IDNA labels. - * No wildcards after the first label. - */ - if (star != NULL || (state & LABEL_IDNA) != 0 || dots) - return NULL; - /* Only full-label '*.example.com' wildcards? */ - if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS) - && (!atstart || !atend)) - return NULL; - /* No 'foo*bar' wildcards */ - if (!atstart && !atend) - return NULL; - star = &p[i]; - state &= ~LABEL_START; - } else if ((state & LABEL_START) != 0) { - /* - * At the start of a label, skip any "xn--" and - * remain in the LABEL_START state, but set the - * IDNA label state - */ - if ((state & LABEL_IDNA) == 0 && len - i >= 4 - && strncasecmp((char *)&p[i], "xn--", 4) == 0) { - i += 3; - state |= LABEL_IDNA; - continue; - } - /* Labels must start with a letter or digit */ - state &= ~LABEL_START; - if (('a' <= p[i] && p[i] <= 'z') - || ('A' <= p[i] && p[i] <= 'Z') - || ('0' <= p[i] && p[i] <= '9')) - continue; - return NULL; - } else if (('a' <= p[i] && p[i] <= 'z') - || ('A' <= p[i] && p[i] <= 'Z') - || ('0' <= p[i] && p[i] <= '9')) { - state &= LABEL_IDNA; - continue; - } else if (p[i] == '.') { - if (state & (LABEL_HYPHEN | LABEL_START)) - return NULL; - state = LABEL_START; - ++dots; - } else if (p[i] == '-') { - /* no domain/subdomain starts with '-' */ - if ((state & LABEL_START) != 0) - return NULL; - state |= LABEL_HYPHEN; - } else - return NULL; - } - - /* - * The final label must not end in a hyphen or ".", and - * there must be at least two dots after the star. - */ - if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) - return NULL; - return star; -} - -/* Compare using wildcards. */ -static int -equal_wildcard(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, unsigned int flags) -{ - const unsigned char *star = NULL; - - /* - * Subject names starting with '.' can only match a wildcard pattern - * via a subject sub-domain pattern suffix match. - */ - if (!(subject_len > 1 && subject[0] == '.')) - star = valid_star(pattern, pattern_len, flags); - if (star == NULL) - return equal_nocase(pattern, pattern_len, - subject, subject_len, flags); - return wildcard_match(pattern, star - pattern, - star + 1, (pattern + pattern_len) - star - 1, - subject, subject_len, flags); -} - -/* - * Compare an ASN1_STRING to a supplied string. If they match return 1. If - * cmp_type > 0 only compare if string matches the type, otherwise convert it - * to UTF8. - */ - -static int -do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, - unsigned int flags, const char *b, size_t blen, char **peername) -{ - int rv = 0; - - if (!a->data || !a->length) - return 0; - if (cmp_type > 0) { - if (cmp_type != a->type) - return 0; - if (cmp_type == V_ASN1_IA5STRING) - rv = equal(a->data, a->length, (unsigned char *)b, - blen, flags); - else if (a->length == (int)blen && !memcmp(a->data, b, blen)) - rv = 1; - if (rv > 0 && peername && - (*peername = strndup((char *)a->data, a->length)) == NULL) - rv = -1; - } else { - int astrlen; - unsigned char *astr = NULL; - astrlen = ASN1_STRING_to_UTF8(&astr, a); - if (astrlen < 0) - return -1; - rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); - if (rv > 0 && peername && - (*peername = strndup((char *)astr, astrlen)) == NULL) - rv = -1; - free(astr); - } - return rv; -} - -static int -do_x509_check(X509 *x, const char *chk, size_t chklen, unsigned int flags, - int check_type, char **peername) -{ - GENERAL_NAMES *gens = NULL; - X509_NAME *name = NULL; - size_t i; - int j; - int cnid = NID_undef; - int alt_type; - int san_present = 0; - int rv = 0; - equal_fn equal; - - /* See below, this flag is internal-only */ - flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS; - if (check_type == GEN_EMAIL) { - cnid = NID_pkcs9_emailAddress; - alt_type = V_ASN1_IA5STRING; - equal = equal_email; - } else if (check_type == GEN_DNS) { - if (!(flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) - cnid = NID_commonName; - /* Implicit client-side DNS sub-domain pattern */ - if (chklen > 1 && chk[0] == '.') - flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS; - alt_type = V_ASN1_IA5STRING; - if (flags & X509_CHECK_FLAG_NO_WILDCARDS) - equal = equal_nocase; - else - equal = equal_wildcard; - } else { - alt_type = V_ASN1_OCTET_STRING; - equal = equal_case; - } - - gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - if (gens != NULL) { - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - GENERAL_NAME *gen; - ASN1_STRING *cstr; - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != check_type) - continue; - san_present = 1; - if (check_type == GEN_EMAIL) - cstr = gen->d.rfc822Name; - else if (check_type == GEN_DNS) - cstr = gen->d.dNSName; - else - cstr = gen->d.iPAddress; - /* Positive on success, negative on error! */ - if ((rv = do_check_string(cstr, alt_type, equal, flags, - chk, chklen, peername)) != 0) - break; - } - GENERAL_NAMES_free(gens); - if (rv != 0) - return rv; - if (cnid == NID_undef || - (san_present && - !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))) - return 0; - } - - /* We're done if CN-ID is not pertinent */ - if (cnid == NID_undef) - return 0; - - j = -1; - name = X509_get_subject_name(x); - while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { - X509_NAME_ENTRY *ne; - ASN1_STRING *str; - if ((ne = X509_NAME_get_entry(name, j)) == NULL) - return -1; - if ((str = X509_NAME_ENTRY_get_data(ne)) == NULL) - return -1; - /* Positive on success, negative on error! */ - if ((rv = do_check_string(str, -1, equal, flags, - chk, chklen, peername)) != 0) - return rv; - } - return 0; -} - -int -X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags, - char **peername) -{ - if (chk == NULL) - return -2; - if (chklen == 0) - chklen = strlen(chk); - else if (memchr(chk, '\0', chklen)) - return -2; - return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); -} -LCRYPTO_ALIAS(X509_check_host); - -int -X509_check_email(X509 *x, const char *chk, size_t chklen, unsigned int flags) -{ - if (chk == NULL) - return -2; - if (chklen == 0) - chklen = strlen(chk); - else if (memchr(chk, '\0', chklen)) - return -2; - return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); -} -LCRYPTO_ALIAS(X509_check_email); - -int -X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags) -{ - if (chk == NULL) - return -2; - return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); -} -LCRYPTO_ALIAS(X509_check_ip); - -int -X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) -{ - unsigned char ipout[16]; - size_t iplen; - - if (ipasc == NULL) - return -2; - iplen = (size_t)a2i_ipadd(ipout, ipasc); - if (iplen == 0) - return -2; - return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); -} -LCRYPTO_ALIAS(X509_check_ip_asc); - -/* Convert IP addresses both IPv4 and IPv6 into an - * OCTET STRING compatible with RFC3280. - */ - -ASN1_OCTET_STRING * -a2i_IPADDRESS(const char *ipasc) -{ - unsigned char ipout[16]; - ASN1_OCTET_STRING *ret; - int iplen; - - /* If string contains a ':' assume IPv6 */ - - iplen = a2i_ipadd(ipout, ipasc); - - if (!iplen) - return NULL; - - ret = ASN1_OCTET_STRING_new(); - if (!ret) - return NULL; - if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { - ASN1_OCTET_STRING_free(ret); - return NULL; - } - return ret; -} -LCRYPTO_ALIAS(a2i_IPADDRESS); - -ASN1_OCTET_STRING * -a2i_IPADDRESS_NC(const char *ipasc) -{ - ASN1_OCTET_STRING *ret = NULL; - unsigned char ipout[32]; - char *iptmp = NULL, *p; - int iplen1, iplen2; - - p = strchr(ipasc, '/'); - if (!p) - return NULL; - iptmp = strdup(ipasc); - if (!iptmp) - return NULL; - p = iptmp + (p - ipasc); - *p++ = 0; - - iplen1 = a2i_ipadd(ipout, iptmp); - - if (!iplen1) - goto err; - - iplen2 = a2i_ipadd(ipout + iplen1, p); - - free(iptmp); - iptmp = NULL; - - if (!iplen2 || (iplen1 != iplen2)) - goto err; - - ret = ASN1_OCTET_STRING_new(); - if (!ret) - goto err; - if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) - goto err; - - return ret; - - err: - free(iptmp); - if (ret) - ASN1_OCTET_STRING_free(ret); - return NULL; -} -LCRYPTO_ALIAS(a2i_IPADDRESS_NC); - - -int -a2i_ipadd(unsigned char *ipout, const char *ipasc) -{ - /* If string contains a ':' assume IPv6 */ - - if (strchr(ipasc, ':')) { - if (!ipv6_from_asc(ipout, ipasc)) - return 0; - return 16; - } else { - if (!ipv4_from_asc(ipout, ipasc)) - return 0; - return 4; - } -} -LCRYPTO_ALIAS(a2i_ipadd); - -static int -ipv4_from_asc(unsigned char *v4, const char *in) -{ - int a0, a1, a2, a3; - if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) - return 0; - if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) || - (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) - return 0; - v4[0] = a0; - v4[1] = a1; - v4[2] = a2; - v4[3] = a3; - return 1; -} - -typedef struct { - /* Temporary store for IPV6 output */ - unsigned char tmp[16]; - /* Total number of bytes in tmp */ - int total; - /* The position of a zero (corresponding to '::') */ - int zero_pos; - /* Number of zeroes */ - int zero_cnt; -} IPV6_STAT; - - -static int -ipv6_from_asc(unsigned char *v6, const char *in) -{ - IPV6_STAT v6stat; - - v6stat.total = 0; - v6stat.zero_pos = -1; - v6stat.zero_cnt = 0; - - /* - * Treat the IPv6 representation as a list of values separated by ':'. - * The presence of a '::' will parse as one (e.g., "2001:db8::1"), - * two (e.g., "2001:db8::") or three (e.g., "::") zero length elements. - */ - if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) - return 0; - - /* Now for some sanity checks */ - - if (v6stat.zero_pos == -1) { - /* If no '::' must have exactly 16 bytes */ - if (v6stat.total != 16) - return 0; - } else { - /* If '::' must have less than 16 bytes */ - if (v6stat.total == 16) - return 0; - /* More than three zeroes is an error */ - if (v6stat.zero_cnt > 3) - return 0; - /* Can only have three zeroes if nothing else present */ - else if (v6stat.zero_cnt == 3) { - if (v6stat.total > 0) - return 0; - } - /* Can only have two zeroes if at start or end */ - else if (v6stat.zero_cnt == 2) { - if ((v6stat.zero_pos != 0) && - (v6stat.zero_pos != v6stat.total)) - return 0; - } else - /* Can only have one zero if *not* start or end */ - { - if ((v6stat.zero_pos == 0) || - (v6stat.zero_pos == v6stat.total)) - return 0; - } - } - - /* Format result */ - - if (v6stat.zero_pos >= 0) { - /* Copy initial part */ - memcpy(v6, v6stat.tmp, v6stat.zero_pos); - /* Zero middle */ - memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); - /* Copy final part */ - if (v6stat.total != v6stat.zero_pos) - memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, - v6stat.tmp + v6stat.zero_pos, - v6stat.total - v6stat.zero_pos); - } else - memcpy(v6, v6stat.tmp, 16); - - return 1; -} - -static int -ipv6_cb(const char *elem, int len, void *usr) -{ - IPV6_STAT *s = usr; - - /* Error if 16 bytes written */ - if (s->total == 16) - return 0; - if (len == 0) { - /* Zero length element, corresponds to '::' */ - if (s->zero_pos == -1) - s->zero_pos = s->total; - /* If we've already got a :: its an error */ - else if (s->zero_pos != s->total) - return 0; - s->zero_cnt++; - } else { - /* If more than 4 characters could be final a.b.c.d form */ - if (len > 4) { - /* Need at least 4 bytes left */ - if (s->total > 12) - return 0; - /* Must be end of string */ - if (elem[len]) - return 0; - if (!ipv4_from_asc(s->tmp + s->total, elem)) - return 0; - s->total += 4; - } else { - if (!ipv6_hex(s->tmp + s->total, elem, len)) - return 0; - s->total += 2; - } - } - return 1; -} - -/* Convert a string of up to 4 hex digits into the corresponding - * IPv6 form. - */ - -static int -ipv6_hex(unsigned char *out, const char *in, int inlen) -{ - unsigned char c; - unsigned int num = 0; - - if (inlen > 4) - return 0; - while (inlen--) { - c = *in++; - num <<= 4; - if ((c >= '0') && (c <= '9')) - num |= c - '0'; - else if ((c >= 'A') && (c <= 'F')) - num |= c - 'A' + 10; - else if ((c >= 'a') && (c <= 'f')) - num |= c - 'a' + 10; - else - return 0; - } - out[0] = num >> 8; - out[1] = num & 0xff; - return 1; -} - -int -X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, - unsigned long chtype) -{ - CONF_VALUE *v; - int i, mval; - char *p, *type; - - if (!nm) - return 0; - - for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { - v = sk_CONF_VALUE_value(dn_sk, i); - type = v->name; - /* Skip past any leading X. X: X, etc to allow for - * multiple instances - */ - for (p = type; *p; p++) - if ((*p == ':') || (*p == ',') || (*p == '.')) { - p++; - if (*p) - type = p; - break; - } - if (*type == '+') { - mval = -1; - type++; - } else - mval = 0; - if (!X509_NAME_add_entry_by_txt(nm, type, chtype, - (unsigned char *) v->value, -1, -1, mval)) - return 0; - } - return 1; -} -LCRYPTO_ALIAS(X509V3_NAME_from_section); diff --git a/src/lib/libcrypto/x509/x509_v3.c b/src/lib/libcrypto/x509/x509_v3.c deleted file mode 100644 index 688aed15a2..0000000000 --- a/src/lib/libcrypto/x509/x509_v3.c +++ /dev/null @@ -1,295 +0,0 @@ -/* $OpenBSD: x509_v3.c,v 1.43 2024/07/12 09:57:04 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include "x509_local.h" - -int -X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *exts) -{ - if (exts == NULL) - return 0; - - return sk_X509_EXTENSION_num(exts); -} -LCRYPTO_ALIAS(X509v3_get_ext_count); - -int -X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *exts, int nid, int lastpos) -{ - const ASN1_OBJECT *obj; - - if ((obj = OBJ_nid2obj(nid)) == NULL) - return -2; - - return X509v3_get_ext_by_OBJ(exts, obj, lastpos); -} -LCRYPTO_ALIAS(X509v3_get_ext_by_NID); - -int -X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *exts, - const ASN1_OBJECT *obj, int lastpos) -{ - if (++lastpos < 0) - lastpos = 0; - - for (; lastpos < X509v3_get_ext_count(exts); lastpos++) { - const X509_EXTENSION *ext = X509v3_get_ext(exts, lastpos); - - if (OBJ_cmp(ext->object, obj) == 0) - return lastpos; - } - - return -1; -} -LCRYPTO_ALIAS(X509v3_get_ext_by_OBJ); - -int -X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *exts, int critical, - int lastpos) -{ - critical = (critical != 0); - - if (++lastpos < 0) - lastpos = 0; - - for (; lastpos < X509v3_get_ext_count(exts); lastpos++) { - const X509_EXTENSION *ext = X509v3_get_ext(exts, lastpos); - - if (X509_EXTENSION_get_critical(ext) == critical) - return lastpos; - } - - return -1; -} -LCRYPTO_ALIAS(X509v3_get_ext_by_critical); - -X509_EXTENSION * -X509v3_get_ext(const STACK_OF(X509_EXTENSION) *exts, int loc) -{ - return sk_X509_EXTENSION_value(exts, loc); -} -LCRYPTO_ALIAS(X509v3_get_ext); - -X509_EXTENSION * -X509v3_delete_ext(STACK_OF(X509_EXTENSION) *exts, int loc) -{ - return sk_X509_EXTENSION_delete(exts, loc); -} -LCRYPTO_ALIAS(X509v3_delete_ext); - -STACK_OF(X509_EXTENSION) * -X509v3_add_ext(STACK_OF(X509_EXTENSION) **out_exts, X509_EXTENSION *ext, int loc) -{ - STACK_OF(X509_EXTENSION) *exts = NULL; - X509_EXTENSION *new_ext = NULL; - - /* - * XXX - Nonsense from the poorly reviewed OpenSSL c755c5fd8ba (2005). - * This check should have been joined with the next check, i.e., if no - * stack was passed in, a new one should be created and returned. - */ - if (out_exts == NULL) { - X509error(ERR_R_PASSED_NULL_PARAMETER); - goto err; - } - - if ((exts = *out_exts) == NULL) - exts = sk_X509_EXTENSION_new_null(); - if (exts == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((new_ext = X509_EXTENSION_dup(ext)) == NULL) - goto err; - if (!sk_X509_EXTENSION_insert(exts, new_ext, loc)) - goto err; - new_ext = NULL; - - *out_exts = exts; - - return exts; - - err: - X509_EXTENSION_free(new_ext); - if (out_exts != NULL && exts != *out_exts) - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - - return NULL; -} -LCRYPTO_ALIAS(X509v3_add_ext); - -X509_EXTENSION * -X509_EXTENSION_create_by_NID(X509_EXTENSION **out_ext, int nid, int critical, - ASN1_OCTET_STRING *data) -{ - const ASN1_OBJECT *obj; - - if ((obj = OBJ_nid2obj(nid)) == NULL) { - X509error(X509_R_UNKNOWN_NID); - return NULL; - } - - return X509_EXTENSION_create_by_OBJ(out_ext, obj, critical, data); -} -LCRYPTO_ALIAS(X509_EXTENSION_create_by_NID); - -X509_EXTENSION * -X509_EXTENSION_create_by_OBJ(X509_EXTENSION **out_ext, const ASN1_OBJECT *obj, - int critical, ASN1_OCTET_STRING *data) -{ - X509_EXTENSION *ext; - - if (out_ext == NULL || (ext = *out_ext) == NULL) - ext = X509_EXTENSION_new(); - if (ext == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!X509_EXTENSION_set_object(ext, obj)) - goto err; - if (!X509_EXTENSION_set_critical(ext, critical)) - goto err; - if (!X509_EXTENSION_set_data(ext, data)) - goto err; - - if (out_ext != NULL) - *out_ext = ext; - - return ext; - - err: - if (out_ext == NULL || ext != *out_ext) - X509_EXTENSION_free(ext); - - return NULL; -} -LCRYPTO_ALIAS(X509_EXTENSION_create_by_OBJ); - -int -X509_EXTENSION_set_object(X509_EXTENSION *ext, const ASN1_OBJECT *obj) -{ - if (ext == NULL || obj == NULL) - return 0; - - ASN1_OBJECT_free(ext->object); - return (ext->object = OBJ_dup(obj)) != NULL; -} -LCRYPTO_ALIAS(X509_EXTENSION_set_object); - -int -X509_EXTENSION_set_critical(X509_EXTENSION *ext, int critical) -{ - if (ext == NULL) - return 0; - - ext->critical = critical ? 0xFF : -1; - - return 1; -} -LCRYPTO_ALIAS(X509_EXTENSION_set_critical); - -int -X509_EXTENSION_set_data(X509_EXTENSION *ext, ASN1_OCTET_STRING *data) -{ - if (ext == NULL) - return 0; - - return ASN1_STRING_set(ext->value, data->data, data->length); -} -LCRYPTO_ALIAS(X509_EXTENSION_set_data); - -ASN1_OBJECT * -X509_EXTENSION_get_object(X509_EXTENSION *ext) -{ - if (ext == NULL) - return NULL; - - return ext->object; -} -LCRYPTO_ALIAS(X509_EXTENSION_get_object); - -ASN1_OCTET_STRING * -X509_EXTENSION_get_data(X509_EXTENSION *ext) -{ - if (ext == NULL) - return NULL; - - return ext->value; -} -LCRYPTO_ALIAS(X509_EXTENSION_get_data); - -int -X509_EXTENSION_get_critical(const X509_EXTENSION *ext) -{ - if (ext == NULL) - return 0; - - return ext->critical > 0; -} -LCRYPTO_ALIAS(X509_EXTENSION_get_critical); diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c deleted file mode 100644 index f25e2b3f15..0000000000 --- a/src/lib/libcrypto/x509/x509_verify.c +++ /dev/null @@ -1,1288 +0,0 @@ -/* $OpenBSD: x509_verify.c,v 1.73 2025/02/08 10:12:00 tb Exp $ */ -/* - * Copyright (c) 2020-2021 Bob Beck - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* x509_verify - inspired by golang's crypto/x509.Verify */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "asn1_local.h" -#include "x509_internal.h" -#include "x509_issuer_cache.h" - -static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, - struct x509_verify_chain *current_chain); -static int x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, - char *name); -static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, - struct x509_verify_chain *current_chain, int full_chain, char *name); -static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, - size_t depth, int error, int ok); -static void x509_verify_chain_free(struct x509_verify_chain *chain); - -/* - * Parse an asn1 to a representable time_t as per RFC 5280 rules. - * Returns -1 if that can't be done for any reason. - */ -int -x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter, - time_t *out) -{ - struct tm tm = { 0 }; - int type; - - if (atime == NULL) - return 0; - - type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type); - if (type == -1) - return 0; - - /* RFC 5280 section 4.1.2.5 */ - if (tm.tm_year < 150 && type != V_ASN1_UTCTIME) - return 0; - if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) - return 0; - - if (notAfter) { - /* - * If we are a completely broken operating system with a - * 32 bit time_t, and we have been told this is a notAfter - * date, limit the date to a 32 bit representable value. - */ - if (!ASN1_time_tm_clamp_notafter(&tm)) - return 0; - } - - /* - * Defensively fail if the time string is not representable as - * a time_t. A time_t must be sane if you care about times after - * Jan 19 2038. - */ - return asn1_time_tm_to_time_t(&tm, out); -} - -struct x509_verify_chain * -x509_verify_chain_new(void) -{ - struct x509_verify_chain *chain; - - if ((chain = calloc(1, sizeof(*chain))) == NULL) - goto err; - if ((chain->certs = sk_X509_new_null()) == NULL) - goto err; - if ((chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS, - sizeof(int))) == NULL) - goto err; - if ((chain->names = - x509_constraints_names_new(X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) - goto err; - - return chain; - err: - x509_verify_chain_free(chain); - return NULL; -} - -static void -x509_verify_chain_clear(struct x509_verify_chain *chain) -{ - sk_X509_pop_free(chain->certs, X509_free); - chain->certs = NULL; - free(chain->cert_errors); - chain->cert_errors = NULL; - x509_constraints_names_free(chain->names); - chain->names = NULL; -} - -static void -x509_verify_chain_free(struct x509_verify_chain *chain) -{ - if (chain == NULL) - return; - x509_verify_chain_clear(chain); - free(chain); -} - -static struct x509_verify_chain * -x509_verify_chain_dup(struct x509_verify_chain *chain) -{ - struct x509_verify_chain *new_chain; - - if ((new_chain = calloc(1, sizeof(*chain))) == NULL) - goto err; - if ((new_chain->certs = X509_chain_up_ref(chain->certs)) == NULL) - goto err; - if ((new_chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS, - sizeof(int))) == NULL) - goto err; - memcpy(new_chain->cert_errors, chain->cert_errors, - X509_VERIFY_MAX_CHAIN_CERTS * sizeof(int)); - if ((new_chain->names = - x509_constraints_names_dup(chain->names)) == NULL) - goto err; - return(new_chain); - err: - x509_verify_chain_free(new_chain); - return NULL; -} - -static int -x509_verify_chain_append(struct x509_verify_chain *chain, X509 *cert, - int *error) -{ - int verify_err = X509_V_ERR_UNSPECIFIED; - size_t idx; - - if (!x509_constraints_extract_names(chain->names, cert, - sk_X509_num(chain->certs) == 0, &verify_err)) { - *error = verify_err; - return 0; - } - - X509_up_ref(cert); - if (!sk_X509_push(chain->certs, cert)) { - X509_free(cert); - *error = X509_V_ERR_OUT_OF_MEM; - return 0; - } - - idx = sk_X509_num(chain->certs) - 1; - chain->cert_errors[idx] = *error; - - /* - * We've just added the issuer for the previous certificate, - * clear its error if appropriate. - */ - if (idx > 1 && chain->cert_errors[idx - 1] == - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) - chain->cert_errors[idx - 1] = X509_V_OK; - - return 1; -} - -static X509 * -x509_verify_chain_last(struct x509_verify_chain *chain) -{ - int last; - - if (chain->certs == NULL) - return NULL; - if ((last = sk_X509_num(chain->certs) - 1) < 0) - return NULL; - return sk_X509_value(chain->certs, last); -} - -X509 * -x509_verify_chain_leaf(struct x509_verify_chain *chain) -{ - if (chain->certs == NULL) - return NULL; - return sk_X509_value(chain->certs, 0); -} - -static void -x509_verify_ctx_reset(struct x509_verify_ctx *ctx) -{ - size_t i; - - for (i = 0; i < ctx->chains_count; i++) - x509_verify_chain_free(ctx->chains[i]); - sk_X509_pop_free(ctx->saved_error_chain, X509_free); - ctx->saved_error = 0; - ctx->saved_error_depth = 0; - ctx->error = 0; - ctx->error_depth = 0; - ctx->chains_count = 0; - ctx->sig_checks = 0; - ctx->check_time = NULL; -} - -static void -x509_verify_ctx_clear(struct x509_verify_ctx *ctx) -{ - x509_verify_ctx_reset(ctx); - sk_X509_pop_free(ctx->intermediates, X509_free); - free(ctx->chains); - -} - -static int -x509_verify_cert_cache_extensions(X509 *cert) -{ - return x509v3_cache_extensions(cert); -} - -static int -x509_verify_cert_self_signed(X509 *cert) -{ - return (cert->ex_flags & EXFLAG_SS) ? 1 : 0; -} - -/* XXX beck - clean up this mess of is_root */ -static int -x509_verify_check_chain_end(X509 *cert, int full_chain) -{ - if (full_chain) - return x509_verify_cert_self_signed(cert); - return 1; -} - -static int -x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert, - int full_chain) -{ - X509 *match = NULL; - int i; - - if (!x509_verify_cert_cache_extensions(cert)) - return 0; - - /* Check by lookup if we have a legacy xsc */ - if (ctx->xsc != NULL) { - /* - * "alternative" lookup method, using the "trusted" stack in the - * xsc as the source for roots. - */ - if (ctx->xsc->trusted != NULL) { - for (i = 0; i < sk_X509_num(ctx->xsc->trusted); i++) { - if (X509_cmp(sk_X509_value(ctx->xsc->trusted, - i), cert) == 0) - return x509_verify_check_chain_end(cert, - full_chain); - } - } - if ((match = x509_vfy_lookup_cert_match(ctx->xsc, - cert)) != NULL) { - X509_free(match); - return x509_verify_check_chain_end(cert, full_chain); - } - } else { - /* Check the provided roots */ - for (i = 0; i < sk_X509_num(ctx->roots); i++) { - if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0) - return x509_verify_check_chain_end(cert, - full_chain); - } - } - - return 0; -} - -static int -x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx, - struct x509_verify_chain *chain, int set_error, int is_trusted) -{ - size_t num_untrusted; - int i; - - if (ctx->xsc == NULL) - return 1; - - /* - * XXX num_untrusted is the number of untrusted certs at the - * bottom of the chain. This works now since we stop at the first - * trusted cert. This will need fixing once we allow more than one - * trusted certificate. - */ - num_untrusted = sk_X509_num(chain->certs); - if (is_trusted && num_untrusted > 0) - num_untrusted--; - ctx->xsc->num_untrusted = num_untrusted; - - sk_X509_pop_free(ctx->xsc->chain, X509_free); - ctx->xsc->chain = X509_chain_up_ref(chain->certs); - if (ctx->xsc->chain == NULL) - return x509_verify_cert_error(ctx, NULL, 0, - X509_V_ERR_OUT_OF_MEM, 0); - - if (set_error) { - ctx->xsc->error = X509_V_OK; - ctx->xsc->error_depth = 0; - for (i = 0; i < sk_X509_num(chain->certs); i++) { - if (chain->cert_errors[i] != X509_V_OK) { - ctx->xsc->error = chain->cert_errors[i]; - ctx->xsc->error_depth = i; - break; - } - } - } - - return 1; -} - - -/* - * Save the error state and unvalidated chain off of the xsc for - * later. - */ -static int -x509_verify_ctx_save_xsc_error(struct x509_verify_ctx *ctx) -{ - if (ctx->xsc != NULL && ctx->xsc->chain != NULL) { - sk_X509_pop_free(ctx->saved_error_chain, X509_free); - ctx->saved_error_chain = X509_chain_up_ref(ctx->xsc->chain); - if (ctx->saved_error_chain == NULL) - return x509_verify_cert_error(ctx, NULL, 0, - X509_V_ERR_OUT_OF_MEM, 0); - ctx->saved_error = ctx->xsc->error; - ctx->saved_error_depth = ctx->xsc->error_depth; - } - return 1; -} - -/* - * Restore the saved error state and unvalidated chain to the xsc - * if we do not have a validated chain. - */ -static int -x509_verify_ctx_restore_xsc_error(struct x509_verify_ctx *ctx) -{ - if (ctx->xsc != NULL && ctx->chains_count == 0 && - ctx->saved_error_chain != NULL) { - sk_X509_pop_free(ctx->xsc->chain, X509_free); - ctx->xsc->chain = X509_chain_up_ref(ctx->saved_error_chain); - if (ctx->xsc->chain == NULL) - return x509_verify_cert_error(ctx, NULL, 0, - X509_V_ERR_OUT_OF_MEM, 0); - ctx->xsc->error = ctx->saved_error; - ctx->xsc->error_depth = ctx->saved_error_depth; - } - return 1; -} - -/* Perform legacy style validation of a chain */ -static int -x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx, - struct x509_verify_chain *chain, size_t depth) -{ - int ret = 0, trust; - - if (ctx->xsc == NULL) - return 1; - - /* - * If we have a legacy xsc, choose a validated chain, and - * apply the extensions, revocation, and policy checks just - * like the legacy code did. We do this here instead of as - * building the chains to more easily support the callback and - * the bewildering array of VERIFY_PARAM knobs that are there - * for the fiddling. - */ - - /* These may be set in one of the following calls. */ - ctx->xsc->error = X509_V_OK; - ctx->xsc->error_depth = 0; - - if (!x509_verify_ctx_set_xsc_chain(ctx, chain, 0, 1)) - goto err; - - /* - * Call the legacy code to walk the chain and check trust - * in the legacy way to handle partial chains and get the - * callback fired correctly. - */ - trust = x509_vfy_check_trust(ctx->xsc); - if (trust == X509_TRUST_REJECTED) - goto err; /* callback was called in x509_vfy_check_trust */ - if (trust != X509_TRUST_TRUSTED) { - /* NOTREACHED */ - goto err; /* should not happen if we get in here - abort? */ - } - - /* - * XXX currently this duplicates some work done in chain - * build, but we keep it here until we have feature parity - */ - if (!x509_vfy_check_chain_extensions(ctx->xsc)) - goto err; - -#ifndef OPENSSL_NO_RFC3779 - if (!X509v3_asid_validate_path(ctx->xsc)) - goto err; - - if (!X509v3_addr_validate_path(ctx->xsc)) - goto err; -#endif - - if (!x509_vfy_check_security_level(ctx->xsc)) - goto err; - - if (!x509_constraints_chain(ctx->xsc->chain, - &ctx->xsc->error, &ctx->xsc->error_depth)) { - X509 *cert = sk_X509_value(ctx->xsc->chain, depth); - if (!x509_verify_cert_error(ctx, cert, - ctx->xsc->error_depth, ctx->xsc->error, 0)) - goto err; - } - - if (!x509_vfy_check_revocation(ctx->xsc)) - goto err; - - if (!x509_vfy_check_policy(ctx->xsc)) - goto err; - - ret = 1; - - err: - /* - * The above checks may have set ctx->xsc->error and - * ctx->xsc->error_depth - save these for later on. - */ - if (ctx->xsc->error != X509_V_OK) { - if (ctx->xsc->error_depth < 0 || - ctx->xsc->error_depth >= X509_VERIFY_MAX_CHAIN_CERTS) - return 0; - chain->cert_errors[ctx->xsc->error_depth] = - ctx->xsc->error; - ctx->error_depth = ctx->xsc->error_depth; - } - - return ret; -} - -/* Add a validated chain to our list of valid chains */ -static int -x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, - struct x509_verify_chain *chain, char *name) -{ - size_t depth; - X509 *last = x509_verify_chain_last(chain); - X509 *leaf = x509_verify_chain_leaf(chain); - - depth = sk_X509_num(chain->certs); - if (depth > 0) - depth--; - - if (ctx->chains_count >= ctx->max_chains) - return x509_verify_cert_error(ctx, last, depth, - X509_V_ERR_CERT_CHAIN_TOO_LONG, 0); - - /* Clear a get issuer failure for a root certificate. */ - if (chain->cert_errors[depth] == - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) - chain->cert_errors[depth] = X509_V_OK; - - if (!x509_verify_ctx_validate_legacy_chain(ctx, chain, depth)) - return 0; - - /* Verify the leaf certificate and store any resulting error. */ - if (!x509_verify_cert_valid(ctx, leaf, NULL)) - return 0; - if (!x509_verify_cert_hostname(ctx, leaf, name)) - return 0; - if (ctx->error_depth == 0 && - ctx->error != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) - chain->cert_errors[0] = ctx->error; - - /* - * In the non-legacy code, extensions and purpose are dealt - * with as the chain is built. - * - * The non-legacy api returns multiple chains but does not do - * any revocation checking (it must be done by the caller on - * any chain they wish to use) - */ - - if ((ctx->chains[ctx->chains_count] = x509_verify_chain_dup(chain)) == - NULL) { - return x509_verify_cert_error(ctx, last, depth, - X509_V_ERR_OUT_OF_MEM, 0); - } - ctx->chains_count++; - - ctx->error = X509_V_OK; - ctx->error_depth = depth; - - return 1; -} - -static int -x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent, - X509 *child) -{ - if (!x509_verify_cert_cache_extensions(parent)) - return 0; - if (ctx->xsc != NULL) - return (ctx->xsc->check_issued(ctx->xsc, child, parent)); - - /* XXX key usage */ - return X509_check_issued(parent, child) == X509_V_OK; -} - -/* Matches x509_crl_verify_parent_signature() */ -static int -x509_verify_parent_signature(X509 *parent, X509 *child, int *error) -{ - EVP_PKEY *pkey; - int cached; - int ret = 0; - - /* Use cached value if we have it */ - if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0) { - if (cached == 0) - *error = X509_V_ERR_CERT_SIGNATURE_FAILURE; - return cached; - } - - /* Check signature. Did parent sign child? */ - if ((pkey = X509_get0_pubkey(parent)) == NULL) { - *error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - return 0; - } - if (X509_verify(child, pkey) <= 0) - *error = X509_V_ERR_CERT_SIGNATURE_FAILURE; - else - ret = 1; - - /* Add result to cache */ - x509_issuer_cache_add(parent->hash, child->hash, ret); - - return ret; -} - -static int -x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, - int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain, - int full_chain, char *name) -{ - int depth = sk_X509_num(current_chain->certs); - struct x509_verify_chain *new_chain; - int i; - - /* Fail if the certificate is already in the chain */ - for (i = 0; i < sk_X509_num(current_chain->certs); i++) { - if (X509_cmp(sk_X509_value(current_chain->certs, i), - candidate) == 0) - return 0; - } - - if (ctx->sig_checks++ > X509_VERIFY_MAX_SIGCHECKS) { - /* don't allow callback to override safety check */ - (void) x509_verify_cert_error(ctx, candidate, depth, - X509_V_ERR_CERT_CHAIN_TOO_LONG, 0); - return 0; - } - - if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) { - if (!x509_verify_cert_error(ctx, candidate, depth, - ctx->error, 0)) - return 0; - } - - if (!x509_verify_cert_valid(ctx, candidate, current_chain)) - return 0; - - /* candidate is good, add it to a copy of the current chain */ - if ((new_chain = x509_verify_chain_dup(current_chain)) == NULL) { - x509_verify_cert_error(ctx, candidate, depth, - X509_V_ERR_OUT_OF_MEM, 0); - return 0; - } - if (!x509_verify_chain_append(new_chain, candidate, &ctx->error)) { - x509_verify_cert_error(ctx, candidate, depth, ctx->error, 0); - x509_verify_chain_free(new_chain); - return 0; - } - - /* - * If candidate is a trusted root, we have a validated chain, - * so we save it. Otherwise, recurse until we find a root or - * give up. - */ - if (is_root_cert) { - if (!x509_verify_ctx_set_xsc_chain(ctx, new_chain, 0, 1)) { - x509_verify_chain_free(new_chain); - return 0; - } - if (!x509_verify_ctx_add_chain(ctx, new_chain, name)) { - x509_verify_chain_free(new_chain); - return 0; - } - goto done; - } - - x509_verify_build_chains(ctx, candidate, new_chain, full_chain, name); - - done: - x509_verify_chain_free(new_chain); - return 1; -} - -static int -x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth, - int error, int ok) -{ - ctx->error = error; - ctx->error_depth = depth; - if (ctx->xsc != NULL) { - ctx->xsc->error = error; - ctx->xsc->error_depth = depth; - ctx->xsc->current_cert = cert; - return ctx->xsc->verify_cb(ok, ctx->xsc); - } - return ok; -} - -static void -x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, - struct x509_verify_chain *current_chain, int full_chain, char *name) -{ - X509 *candidate; - int i, depth, count, ret, is_root; - - /* - * If we are finding chains with an xsc, just stop after we have - * one chain, there's no point in finding more, it just exercises - * the potentially buggy callback processing in the calling software. - */ - if (ctx->xsc != NULL && ctx->chains_count > 0) - return; - - depth = sk_X509_num(current_chain->certs); - if (depth > 0) - depth--; - - if (depth >= ctx->max_depth && - !x509_verify_cert_error(ctx, cert, depth, - X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) - return; - - count = ctx->chains_count; - - ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; - ctx->error_depth = depth; - - if (ctx->saved_error != 0) - ctx->error = ctx->saved_error; - if (ctx->saved_error_depth != 0) - ctx->error_depth = ctx->saved_error_depth; - - if (ctx->xsc != NULL) { - /* - * Long ago experiments at Muppet labs resulted in a - * situation where software not only sees these errors - * but forced developers to expect them in certain cases. - * so we must mimic this awfulness for the legacy case. - */ - if (cert->ex_flags & EXFLAG_SS) - ctx->error = (depth == 0) ? - X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; - } - - /* Check for legacy mode roots */ - if (ctx->xsc != NULL) { - if ((ret = ctx->xsc->get_issuer(&candidate, ctx->xsc, cert)) < 0) { - x509_verify_cert_error(ctx, cert, depth, - X509_V_ERR_STORE_LOOKUP, 0); - return; - } - if (ret > 0) { - if (x509_verify_potential_parent(ctx, candidate, cert)) { - is_root = x509_verify_check_chain_end(candidate, - full_chain); - x509_verify_consider_candidate(ctx, cert, - is_root, candidate, current_chain, - full_chain, name); - } - X509_free(candidate); - } - } else { - /* Check to see if we have a trusted root issuer. */ - for (i = 0; i < sk_X509_num(ctx->roots); i++) { - candidate = sk_X509_value(ctx->roots, i); - if (x509_verify_potential_parent(ctx, candidate, cert)) { - is_root = x509_verify_check_chain_end(candidate, - full_chain); - x509_verify_consider_candidate(ctx, cert, - is_root, candidate, current_chain, - full_chain, name); - } - } - } - - /* Check intermediates after checking roots */ - if (ctx->intermediates != NULL) { - for (i = 0; i < sk_X509_num(ctx->intermediates); i++) { - candidate = sk_X509_value(ctx->intermediates, i); - if (x509_verify_potential_parent(ctx, candidate, cert)) { - x509_verify_consider_candidate(ctx, cert, - 0, candidate, current_chain, - full_chain, name); - } - } - } - - if (ctx->chains_count > count) { - if (ctx->xsc != NULL) { - ctx->xsc->error = X509_V_OK; - ctx->xsc->error_depth = depth; - ctx->xsc->current_cert = cert; - } - } else if (ctx->error_depth == depth) { - if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0)) - return; - } -} - -static int -x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, char *name) -{ - char *candidate; - size_t len; - - if (name == NULL) { - if (ctx->xsc != NULL) { - int ret; - - if ((ret = x509_vfy_check_id(ctx->xsc)) == 0) - ctx->error = ctx->xsc->error; - return ret; - } - return 1; - } - if ((candidate = strdup(name)) == NULL) { - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if ((len = strlen(candidate)) < 1) { - ctx->error = X509_V_ERR_UNSPECIFIED; /* XXX */ - goto err; - } - - /* IP addresses may be written in [ ]. */ - if (candidate[0] == '[' && candidate[len - 1] == ']') { - candidate[len - 1] = '\0'; - if (X509_check_ip_asc(cert, candidate + 1, 0) <= 0) { - ctx->error = X509_V_ERR_IP_ADDRESS_MISMATCH; - goto err; - } - } else { - int flags = 0; - - if (ctx->xsc == NULL) - flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; - - if (X509_check_host(cert, candidate, len, flags, NULL) <= 0) { - ctx->error = X509_V_ERR_HOSTNAME_MISMATCH; - goto err; - } - } - free(candidate); - return 1; - err: - free(candidate); - return x509_verify_cert_error(ctx, cert, 0, ctx->error, 0); -} - -static int -x509_verify_set_check_time(struct x509_verify_ctx *ctx) -{ - if (ctx->xsc != NULL) { - if (ctx->xsc->param->flags & X509_V_FLAG_USE_CHECK_TIME) { - ctx->check_time = &ctx->xsc->param->check_time; - return 1; - } - if (ctx->xsc->param->flags & X509_V_FLAG_NO_CHECK_TIME) - return 0; - } - - ctx->check_time = NULL; - return 1; -} - -static int -x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error) -{ - time_t when, not_before, not_after; - - if (cmp_time == NULL) - when = time(NULL); - else - when = *cmp_time; - - if (!x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0, - ¬_before)) { - *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; - return 0; - } - if (when < not_before) { - *error = X509_V_ERR_CERT_NOT_YET_VALID; - return 0; - } - if (!x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1, - ¬_after)) { - *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; - return 0; - } - if (when > not_after) { - *error = X509_V_ERR_CERT_HAS_EXPIRED; - return 0; - } - - return 1; -} - -static int -x509_verify_validate_constraints(X509 *cert, - struct x509_verify_chain *current_chain, int *error) -{ - struct x509_constraints_names *excluded = NULL; - struct x509_constraints_names *permitted = NULL; - int err = X509_V_ERR_UNSPECIFIED; - - if (current_chain == NULL) - return 1; - - if (cert->nc != NULL) { - if ((permitted = x509_constraints_names_new( - X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { - err = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if ((excluded = x509_constraints_names_new( - X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { - err = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!x509_constraints_extract_constraints(cert, - permitted, excluded, &err)) - goto err; - if (!x509_constraints_check(current_chain->names, - permitted, excluded, &err)) - goto err; - x509_constraints_names_free(excluded); - x509_constraints_names_free(permitted); - } - - return 1; - err: - *error = err; - x509_constraints_names_free(excluded); - x509_constraints_names_free(permitted); - return 0; -} - -static int -x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca) -{ - if (!x509_verify_cert_cache_extensions(cert)) { - ctx->error = X509_V_ERR_UNSPECIFIED; - return 0; - } - - if (ctx->xsc != NULL) - return 1; /* legacy is checked after chain is built */ - - if (cert->ex_flags & EXFLAG_CRITICAL) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; - return 0; - } - /* No we don't care about v1, netscape, and other ancient silliness */ - if (need_ca && (!(cert->ex_flags & EXFLAG_BCONS) && - (cert->ex_flags & EXFLAG_CA))) { - ctx->error = X509_V_ERR_INVALID_CA; - return 0; - } - if (ctx->purpose > 0 && X509_check_purpose(cert, ctx->purpose, need_ca)) { - ctx->error = X509_V_ERR_INVALID_PURPOSE; - return 0; - } - - return 1; -} - -/* Validate that cert is a possible candidate to append to current_chain */ -static int -x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, - struct x509_verify_chain *current_chain) -{ - X509 *issuer_candidate; - int should_be_ca = current_chain != NULL; - size_t depth = 0; - - if (current_chain != NULL) - depth = sk_X509_num(current_chain->certs); - - if (!x509_verify_cert_extensions(ctx, cert, should_be_ca)) - return 0; - - if (should_be_ca) { - issuer_candidate = x509_verify_chain_last(current_chain); - if (issuer_candidate != NULL && - !X509_check_issued(issuer_candidate, cert)) - if (!x509_verify_cert_error(ctx, cert, depth, - X509_V_ERR_SUBJECT_ISSUER_MISMATCH, 0)) - return 0; - } - - if (x509_verify_set_check_time(ctx)) { - if (!x509_verify_cert_times(cert, ctx->check_time, - &ctx->error)) { - if (!x509_verify_cert_error(ctx, cert, depth, - ctx->error, 0)) - return 0; - } - } - - if (!x509_verify_validate_constraints(cert, current_chain, - &ctx->error) && !x509_verify_cert_error(ctx, cert, depth, - ctx->error, 0)) - return 0; - - return 1; -} - -struct x509_verify_ctx * -x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc) -{ - struct x509_verify_ctx *ctx; - size_t max_depth; - - if (xsc == NULL) - return NULL; - - if ((ctx = x509_verify_ctx_new(NULL)) == NULL) - return NULL; - - ctx->xsc = xsc; - - if (xsc->untrusted && - (ctx->intermediates = X509_chain_up_ref(xsc->untrusted)) == NULL) - goto err; - - max_depth = X509_VERIFY_MAX_CHAIN_CERTS; - if (xsc->param->depth > 0 && xsc->param->depth < X509_VERIFY_MAX_CHAIN_CERTS) - max_depth = xsc->param->depth; - if (!x509_verify_ctx_set_max_depth(ctx, max_depth)) - goto err; - - return ctx; - err: - x509_verify_ctx_free(ctx); - return NULL; -} - -/* Public API */ - -struct x509_verify_ctx * -x509_verify_ctx_new(STACK_OF(X509) *roots) -{ - struct x509_verify_ctx *ctx; - - if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL) - return NULL; - - if (roots != NULL) { - if ((ctx->roots = X509_chain_up_ref(roots)) == NULL) - goto err; - } else { - if ((ctx->roots = sk_X509_new_null()) == NULL) - goto err; - } - - ctx->max_depth = X509_VERIFY_MAX_CHAIN_CERTS; - ctx->max_chains = X509_VERIFY_MAX_CHAINS; - ctx->max_sigs = X509_VERIFY_MAX_SIGCHECKS; - - if ((ctx->chains = calloc(X509_VERIFY_MAX_CHAINS, - sizeof(*ctx->chains))) == NULL) - goto err; - - return ctx; - err: - x509_verify_ctx_free(ctx); - return NULL; -} - -void -x509_verify_ctx_free(struct x509_verify_ctx *ctx) -{ - if (ctx == NULL) - return; - sk_X509_pop_free(ctx->roots, X509_free); - x509_verify_ctx_clear(ctx); - free(ctx); -} - -int -x509_verify_ctx_set_max_depth(struct x509_verify_ctx *ctx, size_t max) -{ - if (max < 1 || max > X509_VERIFY_MAX_CHAIN_CERTS) - return 0; - ctx->max_depth = max; - return 1; -} - -int -x509_verify_ctx_set_max_chains(struct x509_verify_ctx *ctx, size_t max) -{ - if (max < 1 || max > X509_VERIFY_MAX_CHAINS) - return 0; - ctx->max_chains = max; - return 1; -} - -int -x509_verify_ctx_set_max_signatures(struct x509_verify_ctx *ctx, size_t max) -{ - if (max < 1 || max > 100000) - return 0; - ctx->max_sigs = max; - return 1; -} - -int -x509_verify_ctx_set_purpose(struct x509_verify_ctx *ctx, int purpose) -{ - if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) - return 0; - ctx->purpose = purpose; - return 1; -} - -int -x509_verify_ctx_set_intermediates(struct x509_verify_ctx *ctx, - STACK_OF(X509) *intermediates) -{ - if ((ctx->intermediates = X509_chain_up_ref(intermediates)) == NULL) - return 0; - return 1; -} - -const char * -x509_verify_ctx_error_string(struct x509_verify_ctx *ctx) -{ - return X509_verify_cert_error_string(ctx->error); -} - -size_t -x509_verify_ctx_error_depth(struct x509_verify_ctx *ctx) -{ - return ctx->error_depth; -} - -STACK_OF(X509) * -x509_verify_ctx_chain(struct x509_verify_ctx *ctx, size_t i) -{ - if (i >= ctx->chains_count) - return NULL; - return ctx->chains[i]->certs; -} - -size_t -x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name) -{ - struct x509_verify_chain *current_chain; - int retry_chain_build, full_chain = 0; - - if (ctx->roots == NULL || ctx->max_depth == 0) { - ctx->error = X509_V_ERR_INVALID_CALL; - goto err; - } - - if (ctx->xsc != NULL) { - if (leaf != NULL || name != NULL) { - ctx->error = X509_V_ERR_INVALID_CALL; - goto err; - } - leaf = ctx->xsc->cert; - - /* XXX */ - full_chain = 1; - if (ctx->xsc->param->flags & X509_V_FLAG_PARTIAL_CHAIN) - full_chain = 0; - /* - * XXX - * The legacy code expects the top level cert to be - * there, even if we didn't find a chain. So put it - * there, we will clobber it later if we find a valid - * chain. - */ - if ((ctx->xsc->chain = sk_X509_new_null()) == NULL) { - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!X509_up_ref(leaf)) { - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - if (!sk_X509_push(ctx->xsc->chain, leaf)) { - X509_free(leaf); - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - ctx->xsc->error_depth = 0; - ctx->xsc->current_cert = leaf; - } - - if ((current_chain = x509_verify_chain_new()) == NULL) { - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto err; - } - - /* - * Add the leaf to the chain and try to build chains from it. - * Note that unlike Go's verifier, we have not yet checked - * anything about the leaf, This is intentional, so that we - * report failures in chain building before we report problems - * with the leaf. - */ - if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) { - x509_verify_chain_free(current_chain); - goto err; - } - do { - retry_chain_build = 0; - if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) { - if (!x509_verify_ctx_add_chain(ctx, current_chain, - name)) { - x509_verify_chain_free(current_chain); - goto err; - } - } else { - x509_verify_build_chains(ctx, leaf, current_chain, - full_chain, name); - if (full_chain && ctx->chains_count == 0) { - /* - * Save the error state from the xsc - * at this point to put back on the - * xsc in case we do not find a chain - * that is trusted but not a full - * chain to a self signed root. This - * is because the unvalidated chain is - * used by the autochain batshittery - * on failure and will be needed for - * that. - */ - ctx->xsc->error_depth = ctx->error_depth; - if (!x509_verify_ctx_save_xsc_error(ctx)) { - x509_verify_chain_free(current_chain); - goto err; - } - full_chain = 0; - retry_chain_build = 1; - } - } - } while (retry_chain_build); - - x509_verify_chain_free(current_chain); - - /* - * Do the new verifier style return, where we don't have an xsc - * that allows a crazy callback to turn invalid things into valid. - */ - if (ctx->xsc == NULL) { - /* - * Safety net: - * We could not find a validated chain, and for some reason do not - * have an error set. - */ - if (ctx->chains_count == 0 && ctx->error == X509_V_OK) - ctx->error = X509_V_ERR_UNSPECIFIED; - - /* - * If we are not using an xsc, and have no possibility for the - * crazy OpenSSL callback API changing the results of - * validation steps (because the callback can make validation - * proceed in the presence of invalid certs), any chains we - * have here are correctly built and verified. - */ - if (ctx->chains_count > 0) - ctx->error = X509_V_OK; - - return ctx->chains_count; - } - - /* - * Otherwise we are doing compatibility with an xsc, which means that we - * will have one chain, which might actually be a bogus chain because - * the callback told us to ignore errors and proceed to build an invalid - * chain. Possible return values from this include returning 1 with an - * invalid chain and a value of xsc->error != X509_V_OK (It's tradition - * that makes it ok). - */ - - if (ctx->chains_count > 0) { - /* - * The chain we have using an xsc might not be a verified chain - * if the callback perverted things while we built it to ignore - * failures and proceed with chain building. We put this chain - * and the error associated with it on the xsc. - */ - if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1, 1)) - goto err; - - /* - * Call the callback for completion up our built - * chain. The callback could still tell us to - * fail. Since this chain might exist as the result of - * callback doing perversions, we could still return - * "success" with something other than X509_V_OK set - * as the error. - */ - if (!x509_vfy_callback_indicate_completion(ctx->xsc)) - goto err; - } else { - /* - * We did not find a chain. Bring back the failure - * case we wanted to the xsc if we saved one. If we - * did not we should have just the leaf on the xsc. - */ - if (!x509_verify_ctx_restore_xsc_error(ctx)) - goto err; - - /* - * Safety net, ensure we have an error set in the - * failing case. - */ - if (ctx->xsc->error == X509_V_OK) { - if (ctx->error == X509_V_OK) - ctx->error = X509_V_ERR_UNSPECIFIED; - ctx->xsc->error = ctx->error; - } - - /* - * Let the callback override the return value - * at depth 0 if it chooses to - */ - return ctx->xsc->verify_cb(0, ctx->xsc); - } - - /* We only ever find one chain in compat mode with an xsc. */ - return 1; - - err: - if (ctx->error == X509_V_OK) - ctx->error = X509_V_ERR_UNSPECIFIED; - - if (ctx->xsc != NULL) { - if (ctx->xsc->error == X509_V_OK) - ctx->xsc->error = X509_V_ERR_UNSPECIFIED; - ctx->error = ctx->xsc->error; - } - - return 0; -} diff --git a/src/lib/libcrypto/x509/x509_verify.h b/src/lib/libcrypto/x509/x509_verify.h deleted file mode 100644 index d8d2cb0b5f..0000000000 --- a/src/lib/libcrypto/x509/x509_verify.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $OpenBSD: x509_verify.h,v 1.2 2021/11/04 23:52:34 beck Exp $ */ -/* - * Copyright (c) 2020 Bob Beck - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef HEADER_X509_VERIFY_H -#define HEADER_X509_VERIFY_H - -#ifdef LIBRESSL_INTERNAL -struct x509_verify_ctx; -struct x509_verify_cert_info; -typedef struct x509_verify_ctx X509_VERIFY_CTX; - -X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); -void x509_verify_ctx_free(struct x509_verify_ctx *ctx); - -int x509_verify_ctx_set_max_depth(X509_VERIFY_CTX *ctx, size_t max); -int x509_verify_ctx_set_max_chains(X509_VERIFY_CTX *ctx, size_t max); -int x509_verify_ctx_set_max_signatures(X509_VERIFY_CTX *ctx, size_t max); -int x509_verify_ctx_set_purpose(X509_VERIFY_CTX *ctx, int purpose_id); -int x509_verify_ctx_set_intermediates(X509_VERIFY_CTX *ctx, - STACK_OF(X509) *intermediates); - -const char *x509_verify_ctx_error_string(X509_VERIFY_CTX *ctx); -size_t x509_verify_ctx_error_depth(X509_VERIFY_CTX *ctx); - -STACK_OF(X509) *x509_verify_ctx_chain(X509_VERIFY_CTX *ctx, size_t chain); - -size_t x509_verify(X509_VERIFY_CTX *ctx, X509 *leaf, char *name); -#endif - -#endif diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c deleted file mode 100644 index c93ae81bd8..0000000000 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ /dev/null @@ -1,2602 +0,0 @@ -/* $OpenBSD: x509_vfy.c,v 1.147 2025/03/04 08:43:25 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "asn1_local.h" -#include "x509_internal.h" -#include "x509_issuer_cache.h" -#include "x509_local.h" - -/* CRL score values */ - -/* No unhandled critical extensions */ - -#define CRL_SCORE_NOCRITICAL 0x100 - -/* certificate is within CRL scope */ - -#define CRL_SCORE_SCOPE 0x080 - -/* CRL times valid */ - -#define CRL_SCORE_TIME 0x040 - -/* Issuer name matches certificate */ - -#define CRL_SCORE_ISSUER_NAME 0x020 - -/* If this score or above CRL is probably valid */ - -#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) - -/* CRL issuer is certificate issuer */ - -#define CRL_SCORE_ISSUER_CERT 0x018 - -/* CRL issuer is on certificate path */ - -#define CRL_SCORE_SAME_PATH 0x008 - -/* CRL issuer matches CRL AKID */ - -#define CRL_SCORE_AKID 0x004 - -/* Have a delta CRL with valid times */ - -#define CRL_SCORE_TIME_DELTA 0x002 - -static int x509_vfy_check_crl(X509_STORE_CTX *ctx, X509_CRL *crl); -static int x509_vfy_cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); - -static int null_callback(int ok, X509_STORE_CTX *e); -static int check_issued(X509_STORE_CTX *ctx, X509 *subject, X509 *issuer); -static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x, - int allow_expired); -static int check_name_constraints(X509_STORE_CTX *ctx); -static int check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth); - -static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, - unsigned int *preasons, X509_CRL *crl, X509 *x); -static int get_crl_delta(X509_STORE_CTX *ctx, - X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); -static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, - X509_CRL *base, STACK_OF(X509_CRL) *crls); -static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, - int *pcrl_score); -static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, - unsigned int *preasons); -static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); -static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, - STACK_OF(X509) *crl_path); -static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, - int clamp_notafter); - -static int internal_verify(X509_STORE_CTX *ctx); -static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); -static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err); - -static int -null_callback(int ok, X509_STORE_CTX *e) -{ - return ok; -} - -/* Return 1 if a certificate is self signed */ -static int -cert_self_signed(X509 *x) -{ - X509_check_purpose(x, -1, 0); - if (x->ex_flags & EXFLAG_SS) - return 1; - else - return 0; -} - -static int -check_id_error(X509_STORE_CTX *ctx, int errcode) -{ - ctx->error = errcode; - ctx->current_cert = ctx->cert; - ctx->error_depth = 0; - return ctx->verify_cb(0, ctx); -} - -static int -x509_vfy_check_hosts(X509 *x, X509_VERIFY_PARAM *vpm) -{ - int i, n; - char *name; - - n = sk_OPENSSL_STRING_num(vpm->hosts); - free(vpm->peername); - vpm->peername = NULL; - - for (i = 0; i < n; ++i) { - name = sk_OPENSSL_STRING_value(vpm->hosts, i); - if (X509_check_host(x, name, strlen(name), vpm->hostflags, - &vpm->peername) > 0) - return 1; - } - return n == 0; -} - -int -x509_vfy_check_id(X509_STORE_CTX *ctx) -{ - X509_VERIFY_PARAM *vpm = ctx->param; - X509 *x = ctx->cert; - - if (vpm->hosts && x509_vfy_check_hosts(x, vpm) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) - return 0; - } - if (vpm->email != NULL && X509_check_email(x, vpm->email, vpm->emaillen, 0) - <= 0) { - if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) - return 0; - } - if (vpm->ip != NULL && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) - return 0; - } - return 1; -} - -/* - * This is the effectively broken legacy OpenSSL chain builder. It - * might find an unvalidated chain and leave it sitting in - * ctx->chain. It does not correctly handle many cases where multiple - * chains could exist. - * - * Oh no.. I know a dirty word... - * Oooooooh.. - */ -static int -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 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; - - cb = ctx->verify_cb; - - /* - * First we make sure the chain we are going to build is - * present and that the first entry is in place. - */ - ctx->chain = sk_X509_new_null(); - if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { - X509error(ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto end; - } - X509_up_ref(ctx->cert); - ctx->num_untrusted = 1; - - /* We use a temporary STACK so we can chop and hack at it */ - if (ctx->untrusted != NULL && - (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { - X509error(ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - goto end; - } - - num = sk_X509_num(ctx->chain); - x = sk_X509_value(ctx->chain, num - 1); - depth = param->depth; - - for (;;) { - /* If we have enough, we break */ - /* FIXME: If this happens, we should take - * note of it and, if appropriate, use the - * X509_V_ERR_CERT_CHAIN_TOO_LONG error code - * later. - */ - if (depth < num) - break; - /* If we are self signed, we break */ - if (cert_self_signed(x)) - break; - /* - * If asked see if we can find issuer in trusted store first - */ - if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { - ok = ctx->get_issuer(&xtmp, ctx, x); - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto end; - } - /* - * If successful for now free up cert so it - * will be picked up again later. - */ - if (ok > 0) { - X509_free(xtmp); - break; - } - } - /* If we were passed a cert chain, use it first */ - if (ctx->untrusted != NULL) { - /* - * If we do not find a non-expired untrusted cert, peek - * ahead and see if we can satisfy this from the trusted - * store. If not, see if we have an expired untrusted cert. - */ - xtmp = find_issuer(ctx, sktmp, x, 0); - if (xtmp == NULL && - !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)) { - ok = ctx->get_issuer(&xtmp, ctx, x); - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto end; - } - if (ok > 0) { - X509_free(xtmp); - break; - } - xtmp = find_issuer(ctx, sktmp, x, 1); - } - if (xtmp != NULL) { - if (!sk_X509_push(ctx->chain, xtmp)) { - X509error(ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = 0; - goto end; - } - X509_up_ref(xtmp); - (void)sk_X509_delete_ptr(sktmp, xtmp); - ctx->num_untrusted++; - x = xtmp; - num++; - /* - * reparse the full chain for the next one - */ - continue; - } - } - break; - } - /* Remember how many untrusted certs we have */ - j = num; - - /* - * At this point, chain should contain a list of untrusted - * certificates. We now need to add at least one trusted one, - * if possible, otherwise we complain. - */ - - do { - /* - * Examine last certificate in chain and see if it is - * self signed. - */ - i = sk_X509_num(ctx->chain); - x = sk_X509_value(ctx->chain, i - 1); - if (cert_self_signed(x)) { - /* we have a self signed certificate */ - if (i == 1) { - /* - * We have a single self signed - * certificate: see if we can find it - * in the store. We must have an exact - * match to avoid possible - * impersonation. - */ - ok = ctx->get_issuer(&xtmp, ctx, x); - if ((ok <= 0) || X509_cmp(x, xtmp)) { - ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; - ctx->current_cert = x; - ctx->error_depth = i - 1; - if (ok == 1) - X509_free(xtmp); - bad_chain = 1; - ok = cb(0, ctx); - if (!ok) - goto end; - } else { - /* - * We have a match: replace - * certificate with store - * version so we get any trust - * settings. - */ - X509_free(x); - x = xtmp; - (void)sk_X509_set(ctx->chain, i - 1, x); - ctx->num_untrusted = 0; - } - } else { - /* - * extract and save self signed - * certificate for later use - */ - chain_ss = sk_X509_pop(ctx->chain); - ctx->num_untrusted--; - num--; - j--; - x = sk_X509_value(ctx->chain, num - 1); - } - } - /* We now lookup certs from the certificate store */ - for (;;) { - /* If we have enough, we break */ - if (depth < num) - break; - /* If we are self signed, we break */ - if (cert_self_signed(x)) - break; - ok = ctx->get_issuer(&xtmp, ctx, x); - - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto end; - } - if (ok == 0) - break; - x = xtmp; - if (!sk_X509_push(ctx->chain, x)) { - X509_free(xtmp); - X509error(ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = 0; - goto end; - } - num++; - } - - /* we now have our chain, lets check it... */ - trust = x509_vfy_check_trust(ctx); - - /* If explicitly rejected error */ - if (trust == X509_TRUST_REJECTED) { - ok = 0; - goto end; - } - /* - * If it's not explicitly trusted then check if there - * is an alternative chain that could be used. We only - * do this if we haven't already checked via - * TRUSTED_FIRST and the user hasn't switched off - * alternate chain checking - */ - retry = 0; - if (trust != X509_TRUST_TRUSTED && - !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) && - !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { - while (j-- > 1) { - xtmp2 = sk_X509_value(ctx->chain, j - 1); - ok = ctx->get_issuer(&xtmp, ctx, xtmp2); - if (ok < 0) - goto end; - /* Check if we found an alternate chain */ - if (ok > 0) { - /* - * Free up the found cert - * we'll add it again later - */ - X509_free(xtmp); - /* - * Dump all the certs above - * this point - we've found an - * alternate chain - */ - while (num > j) { - xtmp = sk_X509_pop(ctx->chain); - X509_free(xtmp); - num--; - } - ctx->num_untrusted = sk_X509_num(ctx->chain); - retry = 1; - break; - } - } - } - } while (retry); - - /* - * If not explicitly trusted then indicate error unless it's a single - * self signed certificate in which case we've indicated an error already - * and set bad_chain == 1 - */ - if (trust != X509_TRUST_TRUSTED && !bad_chain) { - if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { - 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; - ctx->current_cert = x; - } else { - if (!sk_X509_push(ctx->chain, chain_ss)) { - X509error(ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = 0; - goto end; - } - num++; - ctx->num_untrusted = num; - ctx->current_cert = chain_ss; - ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; - chain_ss = NULL; - } - - ctx->error_depth = num - 1; - bad_chain = 1; - ok = cb(0, ctx); - if (!ok) - goto end; - } - - ret = 1; - end: - sk_X509_free(sktmp); - X509_free(chain_ss); - *bad = bad_chain; - *out_ok = ok; - - return ret; -} - -static int -X509_verify_cert_legacy(X509_STORE_CTX *ctx) -{ - int ok = 0, bad_chain; - - ctx->error = X509_V_OK; /* Initialize to 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 */ - ok = x509_vfy_check_chain_extensions(ctx); - if (!ok) - goto end; - - /* Check that the chain satisfies the security level. */ - ok = x509_vfy_check_security_level(ctx); - if (!ok) - goto end; - - /* Check name constraints */ - ok = check_name_constraints(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 = x509_vfy_check_id(ctx); - if (!ok) - goto end; - - /* - * Check revocation status: we do this after copying parameters because - * they may be needed for CRL signature verification. - */ - ok = x509_vfy_check_revocation(ctx); - if (!ok) - goto end; - - /* At this point, we have a chain and need to verify it */ - if (ctx->verify != NULL) - ok = ctx->verify(ctx); - else - ok = internal_verify(ctx); - if (!ok) - goto end; - - /* If we get this far evaluate policies */ - if (!bad_chain) - ok = x509_vfy_check_policy(ctx); - - end: - /* Safety net, error returns must set ctx->error */ - if (ok <= 0 && ctx->error == X509_V_OK) - ctx->error = X509_V_ERR_UNSPECIFIED; - - return ok; -} - -int -X509_verify_cert(X509_STORE_CTX *ctx) -{ - struct x509_verify_ctx *vctx = NULL; - int chain_count = 0; - - if (ctx->cert == NULL) { - X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - if (ctx->chain != NULL) { - /* - * This X509_STORE_CTX has already been used to verify - * a cert. We cannot do another one. - */ - X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - if (ctx->param->poisoned) { - /* - * This X509_STORE_CTX had failures setting - * up verify parameters. We can not use it. - */ - X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - if (ctx->error != X509_V_ERR_INVALID_CALL) { - /* - * This X509_STORE_CTX has not been properly initialized. - */ - X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - - /* - * If the certificate's public key is too weak, don't bother - * continuing. - */ - if (!check_key_level(ctx, ctx->cert) && - !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL)) - return 0; - - /* - * If flags request legacy, use the legacy verifier. If we - * requested "no alt chains" from the age of hammer pants, use - * the legacy verifier because the multi chain verifier really - * does find all the "alt chains". - * - * XXX deprecate the NO_ALT_CHAINS flag? - */ - if ((ctx->param->flags & X509_V_FLAG_LEGACY_VERIFY) || - (ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) - return X509_verify_cert_legacy(ctx); - - /* Use the modern multi-chain verifier from x509_verify_cert */ - - 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); - - /* if we succeed we have a chain in ctx->chain */ - return chain_count > 0 && ctx->chain != NULL; -} -LCRYPTO_ALIAS(X509_verify_cert); - -/* Given a STACK_OF(X509) find the issuer of cert (if any) - */ - -static X509 * -find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x, - int allow_expired) -{ - int i; - X509 *issuer, *rv = NULL; - - for (i = 0; i < sk_X509_num(sk); i++) { - issuer = sk_X509_value(sk, i); - if (ctx->check_issued(ctx, x, issuer)) { - if (x509_check_cert_time(ctx, issuer, -1)) - return issuer; - if (allow_expired) - rv = issuer; - } - } - return rv; -} - -/* Given a possible certificate and issuer check them */ - -static int -check_issued(X509_STORE_CTX *ctx, X509 *subject, X509 *issuer) -{ - /* - * Yes, the arguments of X509_STORE_CTX_check_issued_fn were exposed in - * reverse order compared to the already public X509_check_issued()... - */ - return X509_check_issued(issuer, subject) == X509_V_OK; -} - -/* Alternative lookup method: look from a STACK stored in ctx->trusted */ - -static int -x509_vfy_get_trusted_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -{ - *issuer = find_issuer(ctx, ctx->trusted, x, 1); - if (*issuer) { - CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); - return 1; - } else - return 0; -} - -/* Check a certificate chains extensions for consistency - * with the supplied purpose - */ - -int -x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx) -{ - int i, ok = 0, must_be_ca, plen = 0; - X509 *x; - int (*cb)(int xok, X509_STORE_CTX *xctx); - int proxy_path_length = 0; - int purpose; - - cb = ctx->verify_cb; - - /* must_be_ca can have 1 of 3 values: - -1: we accept both CA and non-CA certificates, to allow direct - use of self-signed certificates (which are marked as CA). - 0: we only accept non-CA certificates. This is currently not - used, but the possibility is present for future extensions. - 1: we only accept CA certificates. This is currently used for - all certificates in the chain except the leaf certificate. - */ - must_be_ca = -1; - - /* CRL path validation */ - if (ctx->parent) - purpose = X509_PURPOSE_CRL_SIGN; - else - purpose = ctx->param->purpose; - - /* Check all untrusted certificates */ - 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) && - (x->ex_flags & EXFLAG_CRITICAL)) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - ret = X509_check_ca(x); - if (must_be_ca == -1) { - if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && - (ret != 1) && (ret != 0)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; - } else { - if ((ret == 0) || - ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && - (ret != 1))) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; - } - if (ret == 0) { - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - if (ctx->param->purpose > 0) { - ret = X509_check_purpose(x, purpose, must_be_ca > 0); - if ((ret == 0) || - ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && - (ret != 1))) { - ctx->error = X509_V_ERR_INVALID_PURPOSE; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - } - /* Check pathlen if not self issued */ - if ((i > 1) && !(x->ex_flags & EXFLAG_SI) && - (x->ex_pathlen != -1) && - (plen > (x->ex_pathlen + proxy_path_length + 1))) { - ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - /* Increment path length if not self issued */ - if (!(x->ex_flags & EXFLAG_SI)) - plen++; - must_be_ca = 1; - } - - ok = 1; - - end: - return ok; -} - -static int -check_name_constraints(X509_STORE_CTX *ctx) -{ - if (!x509_constraints_chain(ctx->chain, &ctx->error, - &ctx->error_depth)) { - ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); - if (!ctx->verify_cb(0, ctx)) - return 0; - } - return 1; -} - -/* Given a certificate try and find an exact match in the store */ - -static X509 * -lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) -{ - STACK_OF(X509) *certs; - X509 *xtmp = NULL; - size_t i; - - /* Lookup all certs with matching subject name */ - certs = X509_STORE_CTX_get1_certs(ctx, X509_get_subject_name(x)); - if (certs == NULL) - return NULL; - - /* Look for exact match */ - for (i = 0; i < sk_X509_num(certs); i++) { - xtmp = sk_X509_value(certs, i); - if (!X509_cmp(xtmp, x)) - break; - } - - if (i < sk_X509_num(certs)) - X509_up_ref(xtmp); - else - xtmp = NULL; - - sk_X509_pop_free(certs, X509_free); - return xtmp; -} - -X509 * -x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) -{ - if (ctx->store == NULL || ctx->store->objs == NULL) - return NULL; - return lookup_cert_match(ctx, x); -} - -int -x509_vfy_check_trust(X509_STORE_CTX *ctx) -{ - size_t i; - int ok; - X509 *x = NULL; - int (*cb) (int xok, X509_STORE_CTX *xctx); - - cb = ctx->verify_cb; - /* Check all trusted certificates in chain */ - 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); - - /* If explicitly trusted return trusted */ - if (ok == X509_TRUST_TRUSTED) - return X509_TRUST_TRUSTED; - /* - * If explicitly rejected notify callback and reject if not - * overridden. - */ - if (ok == X509_TRUST_REJECTED) { - ctx->error_depth = i; - ctx->current_cert = x; - ctx->error = X509_V_ERR_CERT_REJECTED; - ok = cb(0, ctx); - if (!ok) - return X509_TRUST_REJECTED; - } - } - /* - * If we accept partial chains and have at least one trusted certificate - * return success. - */ - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - X509 *mx; - 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->num_untrusted = 0; - return X509_TRUST_TRUSTED; - } - } - - /* - * If no trusted certs in chain at all return untrusted and allow - * standard (no issuer cert) etc errors to be indicated. - */ - return X509_TRUST_UNTRUSTED; -} - -int -x509_vfy_check_revocation(X509_STORE_CTX *ctx) -{ - int i, last, ok; - - if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) - return 1; - if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) - last = sk_X509_num(ctx->chain) - 1; - else { - /* If checking CRL paths this isn't the EE certificate */ - if (ctx->parent) - return 1; - last = 0; - } - for (i = 0; i <= last; i++) { - ok = check_cert(ctx, ctx->chain, i); - if (!ok) - return ok; - } - return 1; -} - -static int -check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth) -{ - X509_CRL *crl = NULL, *dcrl = NULL; - X509 *x; - int ok = 0, cnum; - unsigned int last_reasons; - - cnum = ctx->error_depth = depth; - x = sk_X509_value(chain, cnum); - ctx->current_cert = x; - ctx->current_issuer = NULL; - ctx->current_crl_score = 0; - ctx->current_reasons = 0; - while (ctx->current_reasons != CRLDP_ALL_REASONS) { - last_reasons = ctx->current_reasons; - /* Try to retrieve relevant CRL */ - ok = get_crl_delta(ctx, &crl, &dcrl, x); - if (!ok) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; - } - ctx->current_crl = crl; - ok = x509_vfy_check_crl(ctx, crl); - if (!ok) - goto err; - - if (dcrl) { - ok = x509_vfy_check_crl(ctx, dcrl); - if (!ok) - goto err; - ok = x509_vfy_cert_crl(ctx, dcrl, x); - if (!ok) - goto err; - } else - ok = 1; - - /* Don't look in full CRL if delta reason is removefromCRL */ - if (ok != 2) { - ok = x509_vfy_cert_crl(ctx, crl, x); - if (!ok) - goto err; - } - - ctx->current_crl = NULL; - X509_CRL_free(crl); - X509_CRL_free(dcrl); - crl = NULL; - dcrl = NULL; - /* If reasons not updated we wont get anywhere by - * another iteration, so exit loop. - */ - if (last_reasons == ctx->current_reasons) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; - } - } - -err: - ctx->current_crl = NULL; - X509_CRL_free(crl); - X509_CRL_free(dcrl); - return ok; -} - -/* Check CRL times against values in X509_STORE_CTX */ - -static int -check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) -{ - time_t *ptime; - int i; - - 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) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i > 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (X509_CRL_get_nextUpdate(crl)) { - i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); - - if (i == 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - /* Ignore expiry of base CRL is delta is valid */ - if ((i < 0) && - !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - } - - if (notify) - ctx->current_crl = NULL; - - return 1; -} - -static int -get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, - X509 **pissuer, int *pscore, unsigned int *preasons, - STACK_OF(X509_CRL) *crls) -{ - int i, crl_score, best_score = *pscore; - unsigned int reasons, best_reasons = 0; - X509 *x = ctx->current_cert; - X509_CRL *crl, *best_crl = NULL; - X509 *crl_issuer = NULL, *best_crl_issuer = NULL; - - for (i = 0; i < sk_X509_CRL_num(crls); i++) { - crl = sk_X509_CRL_value(crls, i); - reasons = *preasons; - crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); - - if (crl_score > best_score) { - best_crl = crl; - best_crl_issuer = crl_issuer; - best_score = crl_score; - best_reasons = reasons; - } - } - - if (best_crl) { - if (*pcrl) - X509_CRL_free(*pcrl); - *pcrl = best_crl; - *pissuer = best_crl_issuer; - *pscore = best_score; - *preasons = best_reasons; - CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); - if (*pdcrl) { - X509_CRL_free(*pdcrl); - *pdcrl = NULL; - } - get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); - } - - if (best_score >= CRL_SCORE_VALID) - return 1; - - return 0; -} - -/* Compare two CRL extensions for delta checking purposes. They should be - * both present or both absent. If both present all fields must be identical. - */ - -static int -crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) -{ - ASN1_OCTET_STRING *exta, *extb; - int i; - - i = X509_CRL_get_ext_by_NID(a, nid, -1); - if (i >= 0) { - /* Can't have multiple occurrences */ - if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) - return 0; - exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); - } else - exta = NULL; - - i = X509_CRL_get_ext_by_NID(b, nid, -1); - - if (i >= 0) { - if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) - return 0; - extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); - } else - extb = NULL; - - if (!exta && !extb) - return 1; - - if (!exta || !extb) - return 0; - - if (ASN1_OCTET_STRING_cmp(exta, extb)) - return 0; - - return 1; -} - -/* See if a base and delta are compatible */ - -static int -check_delta_base(X509_CRL *delta, X509_CRL *base) -{ - /* Delta CRL must be a delta */ - if (!delta->base_crl_number) - return 0; - /* Base must have a CRL number */ - if (!base->crl_number) - return 0; - /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), - X509_CRL_get_issuer(delta))) - return 0; - /* AKID and IDP must match */ - if (!crl_extension_match(delta, base, NID_authority_key_identifier)) - return 0; - if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) - return 0; - /* Delta CRL base number must not exceed Full CRL number. */ - if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) - return 0; - /* Delta CRL number must exceed full CRL number */ - if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) - return 1; - return 0; -} - -/* For a given base CRL find a delta... maybe extend to delta scoring - * or retrieve a chain of deltas... - */ - -static void -get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base, - STACK_OF(X509_CRL) *crls) -{ - X509_CRL *delta; - int i; - - if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) - return; - if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) - return; - for (i = 0; i < sk_X509_CRL_num(crls); i++) { - delta = sk_X509_CRL_value(crls, i); - if (check_delta_base(delta, base)) { - if (check_crl_time(ctx, delta, 0)) - *pscore |= CRL_SCORE_TIME_DELTA; - CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); - *dcrl = delta; - return; - } - } - *dcrl = NULL; -} - -/* For a given CRL return how suitable it is for the supplied certificate 'x'. - * The return value is a mask of several criteria. - * If the issuer is not the certificate issuer this is returned in *pissuer. - * The reasons mask is also used to determine if the CRL is suitable: if - * no new reasons the CRL is rejected, otherwise reasons is updated. - */ - -static int -get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, - X509_CRL *crl, X509 *x) -{ - int crl_score = 0; - unsigned int tmp_reasons = *preasons, crl_reasons; - - /* First see if we can reject CRL straight away */ - - /* Invalid IDP cannot be processed */ - if (crl->idp_flags & IDP_INVALID) - return 0; - /* Reason codes or indirect CRLs need extended CRL support */ - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { - if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) - return 0; - } else if (crl->idp_flags & IDP_REASONS) { - /* If no new reasons reject */ - if (!(crl->idp_reasons & ~tmp_reasons)) - return 0; - } - /* Don't process deltas at this stage */ - else if (crl->base_crl_number) - return 0; - /* If issuer name doesn't match certificate need indirect CRL */ - if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { - if (!(crl->idp_flags & IDP_INDIRECT)) - return 0; - } else - crl_score |= CRL_SCORE_ISSUER_NAME; - - if (!(crl->flags & EXFLAG_CRITICAL)) - crl_score |= CRL_SCORE_NOCRITICAL; - - /* Check expiry */ - if (check_crl_time(ctx, crl, 0)) - crl_score |= CRL_SCORE_TIME; - - /* Check authority key ID and locate certificate issuer */ - crl_akid_check(ctx, crl, pissuer, &crl_score); - - /* If we can't locate certificate issuer at this point forget it */ - - if (!(crl_score & CRL_SCORE_AKID)) - return 0; - - /* Check cert for matching CRL distribution points */ - - if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { - /* If no new reasons reject */ - if (!(crl_reasons & ~tmp_reasons)) - return 0; - tmp_reasons |= crl_reasons; - crl_score |= CRL_SCORE_SCOPE; - } - - *preasons = tmp_reasons; - - return crl_score; -} - -static void -crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, - int *pcrl_score) -{ - X509 *crl_issuer = NULL; - X509_NAME *cnm = X509_CRL_get_issuer(crl); - int cidx = ctx->error_depth; - int i; - - if (cidx != sk_X509_num(ctx->chain) - 1) - cidx++; - - crl_issuer = sk_X509_value(ctx->chain, cidx); - - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { - *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT; - *pissuer = crl_issuer; - return; - } - } - - for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { - crl_issuer = sk_X509_value(ctx->chain, cidx); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH; - *pissuer = crl_issuer; - return; - } - } - - /* Anything else needs extended CRL support */ - - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) - return; - - /* Otherwise the CRL issuer is not on the path. Look for it in the - * set of untrusted certificates. - */ - for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { - crl_issuer = sk_X509_value(ctx->untrusted, i); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - *pissuer = crl_issuer; - *pcrl_score |= CRL_SCORE_AKID; - return; - } - } -} - -/* Check the path of a CRL issuer certificate. This creates a new - * X509_STORE_CTX and populates it with most of the parameters from the - * parent. This could be optimised somewhat since a lot of path checking - * will be duplicated by the parent, but this will rarely be used in - * practice. - */ - -static int -check_crl_path(X509_STORE_CTX *ctx, X509 *x) -{ - X509_STORE_CTX crl_ctx; - int ret; - - /* Don't allow recursive CRL path validation */ - if (ctx->parent) - return 0; - if (!X509_STORE_CTX_init(&crl_ctx, ctx->store, x, ctx->untrusted)) { - ret = -1; - goto err; - } - - crl_ctx.crls = ctx->crls; - /* Copy verify params across */ - X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); - - crl_ctx.parent = ctx; - crl_ctx.verify_cb = ctx->verify_cb; - - /* Verify CRL issuer */ - ret = X509_verify_cert(&crl_ctx); - - if (ret <= 0) - goto err; - - /* Check chain is acceptable */ - ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); - -err: - X509_STORE_CTX_cleanup(&crl_ctx); - return ret; -} - -/* RFC3280 says nothing about the relationship between CRL path - * and certificate path, which could lead to situations where a - * certificate could be revoked or validated by a CA not authorised - * to do so. RFC5280 is more strict and states that the two paths must - * end in the same trust anchor, though some discussions remain... - * until this is resolved we use the RFC5280 version - */ - -static int -check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, - STACK_OF(X509) *crl_path) -{ - X509 *cert_ta, *crl_ta; - - cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); - crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); - if (!X509_cmp(cert_ta, crl_ta)) - return 1; - return 0; -} - -/* Check for match between two dist point names: three separate cases. - * 1. Both are relative names and compare X509_NAME types. - * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. - * 3. Both are full names and compare two GENERAL_NAMES. - * 4. One is NULL: automatic match. - */ - -static int -idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) -{ - X509_NAME *nm = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gena, *genb; - int i, j; - - if (!a || !b) - return 1; - if (a->type == 1) { - if (!a->dpname) - return 0; - /* Case 1: two X509_NAME */ - if (b->type == 1) { - if (!b->dpname) - return 0; - if (!X509_NAME_cmp(a->dpname, b->dpname)) - return 1; - else - return 0; - } - /* Case 2: set name and GENERAL_NAMES appropriately */ - nm = a->dpname; - gens = b->name.fullname; - } else if (b->type == 1) { - if (!b->dpname) - return 0; - /* Case 2: set name and GENERAL_NAMES appropriately */ - gens = a->name.fullname; - nm = b->dpname; - } - - /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ - if (nm) { - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gena = sk_GENERAL_NAME_value(gens, i); - if (gena->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(nm, gena->d.directoryName)) - return 1; - } - return 0; - } - - /* Else case 3: two GENERAL_NAMES */ - - for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { - gena = sk_GENERAL_NAME_value(a->name.fullname, i); - for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { - genb = sk_GENERAL_NAME_value(b->name.fullname, j); - if (!GENERAL_NAME_cmp(gena, genb)) - return 1; - } - } - - return 0; -} - -static int -crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) -{ - int i; - X509_NAME *nm = X509_CRL_get_issuer(crl); - - /* If no CRLissuer return is successful iff don't need a match */ - if (!dp->CRLissuer) - return !!(crl_score & CRL_SCORE_ISSUER_NAME); - for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); - if (gen->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(gen->d.directoryName, nm)) - return 1; - } - return 0; -} - -/* Check CRLDP and IDP */ - -static int -crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons) -{ - int i; - - if (crl->idp_flags & IDP_ONLYATTR) - return 0; - if (x->ex_flags & EXFLAG_CA) { - if (crl->idp_flags & IDP_ONLYUSER) - return 0; - } else { - if (crl->idp_flags & IDP_ONLYCA) - return 0; - } - *preasons = crl->idp_reasons; - for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { - DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); - if (crldp_check_crlissuer(dp, crl, crl_score)) { - if (!crl->idp || - idp_check_dp(dp->distpoint, crl->idp->distpoint)) { - *preasons &= dp->dp_reasons; - return 1; - } - } - } - if ((!crl->idp || !crl->idp->distpoint) && - (crl_score & CRL_SCORE_ISSUER_NAME)) - return 1; - return 0; -} - -/* Retrieve CRL corresponding to current certificate. - * If deltas enabled try to find a delta CRL too - */ - -static int -get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) -{ - int ok; - X509 *issuer = NULL; - int crl_score = 0; - unsigned int reasons; - X509_CRL *crl = NULL, *dcrl = NULL; - STACK_OF(X509_CRL) *skcrl; - X509_NAME *nm = X509_get_issuer_name(x); - - reasons = ctx->current_reasons; - ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, - ctx->crls); - if (ok) - goto done; - - /* Lookup CRLs from store */ - skcrl = X509_STORE_CTX_get1_crls(ctx, nm); - - /* If no CRLs found and a near match from get_crl_sk use that */ - if (!skcrl && crl) - goto done; - - get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); - - sk_X509_CRL_pop_free(skcrl, X509_CRL_free); - -done: - - /* If we got any kind of CRL use it and return success */ - if (crl) { - ctx->current_issuer = issuer; - ctx->current_crl_score = crl_score; - ctx->current_reasons = reasons; - *pcrl = crl; - *pdcrl = dcrl; - return 1; - } - - return 0; -} - -/* Matches x509_verify_parent_signature() */ -static int -x509_crl_verify_parent_signature(X509 *parent, X509_CRL *crl, int *error) -{ - EVP_PKEY *pkey; - int cached; - int ret = 0; - - /* Use cached value if we have it */ - if ((cached = x509_issuer_cache_find(parent->hash, crl->hash)) >= 0) { - if (cached == 0) - *error = X509_V_ERR_CRL_SIGNATURE_FAILURE; - return cached; - } - - /* Check signature. Did parent sign crl? */ - if ((pkey = X509_get0_pubkey(parent)) == NULL) { - *error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - return 0; - } - if (X509_CRL_verify(crl, pkey) <= 0) - *error = X509_V_ERR_CRL_SIGNATURE_FAILURE; - else - ret = 1; - - /* Add result to cache */ - x509_issuer_cache_add(parent->hash, crl->hash, ret); - - return ret; -} - -/* Check CRL validity */ -static int -x509_vfy_check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) -{ - X509 *issuer = NULL; - int ok = 0, chnum, cnum; - - cnum = ctx->error_depth; - chnum = sk_X509_num(ctx->chain) - 1; - /* if we have an alternative CRL issuer cert use that */ - if (ctx->current_issuer) { - issuer = ctx->current_issuer; - } else if (cnum < chnum) { - /* - * Else find CRL issuer: if not last certificate then issuer - * is next certificate in chain. - */ - issuer = sk_X509_value(ctx->chain, cnum + 1); - } else { - issuer = sk_X509_value(ctx->chain, chnum); - /* If not self signed, can't check signature */ - if (!ctx->check_issued(ctx, issuer, issuer)) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - if (issuer) { - /* Skip most tests for deltas because they have already - * been done - */ - if (!crl->base_crl_number) { - /* Check for cRLSign bit if keyUsage present */ - if ((issuer->ex_flags & EXFLAG_KUSAGE) && - !(issuer->ex_kusage & KU_CRL_SIGN)) { - ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { - ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { - if (check_crl_path(ctx, - ctx->current_issuer) <= 0) { - ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - if (crl->idp_flags & IDP_INVALID) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - - } - - if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { - ok = check_crl_time(ctx, crl, 1); - if (!ok) - goto err; - } - - if (!x509_crl_verify_parent_signature(issuer, crl, &ctx->error)) { - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - ok = 1; - - err: - return ok; -} - -/* Check certificate against CRL */ -static int -x509_vfy_cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) -{ - int ok; - X509_REVOKED *rev; - - /* The rules changed for this... previously if a CRL contained - * unhandled critical extensions it could still be used to indicate - * a certificate was revoked. This has since been changed since - * critical extension can change the meaning of CRL entries. - */ - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && - (crl->flags & EXFLAG_CRITICAL)) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; - ok = ctx->verify_cb(0, ctx); - if (!ok) - return 0; - } - /* Look for serial number of certificate in CRL - * If found make sure reason is not removeFromCRL. - */ - if (X509_CRL_get0_by_cert(crl, &rev, x)) { - if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) - return 2; - ctx->error = X509_V_ERR_CERT_REVOKED; - ok = ctx->verify_cb(0, ctx); - if (!ok) - return 0; - } - - return 1; -} - -int -x509_vfy_check_policy(X509_STORE_CTX *ctx) -{ - X509 *current_cert = NULL; - int ret; - - if (ctx->parent != NULL) - return 1; - - ret = X509_policy_check(ctx->chain, ctx->param->policies, - ctx->param->flags, ¤t_cert); - if (ret != X509_V_OK) { - ctx->current_cert = current_cert; - ctx->error = ret; - if (ret == X509_V_ERR_OUT_OF_MEM) - return 0; - return ctx->verify_cb(0, ctx); - } - - if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { - ctx->current_cert = NULL; - /* - * Verification errors need to be "sticky", a callback may have - * allowed an SSL handshake to continue despite an error, and - * we must then remain in an error state. Therefore, we MUST - * NOT clear earlier verification errors by setting the error - * to X509_V_OK. - */ - if (!ctx->verify_cb(2, ctx)) - return 0; - } - - return 1; -} - -/* - * Inform the verify callback of an error. - * - * If x is not NULL it is the error cert, otherwise use the chain cert - * at depth. - * - * If err is not X509_V_OK, that's the error value, otherwise leave - * unchanged (presumably set by the caller). - * - * Returns 0 to abort verification with an error, non-zero to continue. - */ -static int -verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) -{ - ctx->error_depth = depth; - ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth); - if (err != X509_V_OK) - ctx->error = err; - return ctx->verify_cb(0, ctx); -} - -/* - * Check certificate validity times. - * - * If depth >= 0, invoke verification callbacks on error, otherwise just return - * the validation status. - * - * Return 1 on success, 0 otherwise. - */ -int -x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) -{ - time_t ptime; - int i; - - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = ctx->param->check_time; - else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) - return 1; - else - ptime = time(NULL); - - 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, - X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD)) - return 0; - if (i > 0 && !verify_cb_cert(ctx, x, depth, - X509_V_ERR_CERT_NOT_YET_VALID)) - return 0; - - 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, - X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)) - return 0; - if (i < 0 && !verify_cb_cert(ctx, x, depth, - X509_V_ERR_CERT_HAS_EXPIRED)) - return 0; - - return 1; -} - -static int -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); - X509 *xs; - - if (ctx->check_issued(ctx, xi, xi)) - xs = xi; - else { - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - xs = xi; - goto check_cert; - } - if (n <= 0) - return verify_cb_cert(ctx, xi, 0, - X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); - n--; - ctx->error_depth = n; - xs = sk_X509_value(ctx->chain, n); - } - - /* - * Do not clear ctx->error=0, it must be "sticky", only the - * user's callback is allowed to reset errors (at its own - * peril). - */ - while (n >= 0) { - - /* - * Skip signature check for self signed certificates - * unless explicitly asked for. It doesn't add any - * security and just wastes time. If the issuer's - * public key is unusable, report the issuer - * certificate and its depth (rather than the depth of - * the subject). - */ - 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, - X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)) - return 0; - } else if (X509_verify(xs, pkey) <= 0) { - if (!verify_cb_cert(ctx, xs, n, - X509_V_ERR_CERT_SIGNATURE_FAILURE)) { - EVP_PKEY_free(pkey); - return 0; - } - } - EVP_PKEY_free(pkey); - } -check_cert: - /* Calls verify callback as needed */ - if (!chain_verified && !x509_check_cert_time(ctx, xs, n)) - return 0; - - /* - * Signal success at this depth. However, the - * previous error (if any) is retained. - */ - ctx->current_issuer = xi; - ctx->current_cert = xs; - ctx->error_depth = n; - if (!ctx->verify_cb(1, ctx)) - return 0; - - if (--n >= 0) { - xi = xs; - xs = sk_X509_value(ctx->chain, n); - } - } - 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) -{ - return X509_cmp_time(ctm, NULL); -} -LCRYPTO_ALIAS(X509_cmp_current_time); - -/* - * Compare a possibly unvalidated ASN1_TIME string against a time_t - * using RFC 5280 rules for the time string. If *cmp_time is NULL - * the current system time is used. - * - * XXX NOTE that unlike what you expect a "cmp" function to do in C, - * XXX this one is "special", and returns 0 for error. - * - * Returns: - * -1 if the ASN1_time is earlier than OR the same as *cmp_time. - * 1 if the ASN1_time is later than *cmp_time. - * 0 on error. - */ -static int -X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int is_notafter) -{ - time_t compare, cert_time; - - if (cmp_time == NULL) - compare = time(NULL); - else - compare = *cmp_time; - - if (!x509_verify_asn1_time_to_time_t(ctm, is_notafter, &cert_time)) - return 0; /* invalid time */ - - if (cert_time <= compare) - return -1; /* 0 is used for error, so map same to less than */ - - return 1; -} - -int -X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) -{ - return X509_cmp_time_internal(ctm, cmp_time, 0); -} -LCRYPTO_ALIAS(X509_cmp_time); - - -ASN1_TIME * -X509_gmtime_adj(ASN1_TIME *s, long adj) -{ - return X509_time_adj(s, adj, NULL); -} -LCRYPTO_ALIAS(X509_gmtime_adj); - -ASN1_TIME * -X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_time) -{ - return X509_time_adj_ex(s, 0, offset_sec, in_time); -} -LCRYPTO_ALIAS(X509_time_adj); - -ASN1_TIME * -X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *in_time) -{ - time_t t; - if (in_time == NULL) - t = time(NULL); - else - t = *in_time; - - return ASN1_TIME_adj(s, t, offset_day, offset_sec); -} -LCRYPTO_ALIAS(X509_time_adj_ex); - -int -X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) -{ - EVP_PKEY *ktmp = NULL, *ktmp2; - int i, j; - - if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) - return 1; - - for (i = 0; i < sk_X509_num(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 - ktmp = NULL; - } - if (ktmp == NULL) { - X509error(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); - return 0; - } - - /* first, populate the other certs */ - for (j = i - 1; j >= 0; j--) { - 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) - if (!EVP_PKEY_copy_parameters(pkey, ktmp)) - return 0; - return 1; -} -LCRYPTO_ALIAS(X509_get_pubkey_parameters); - -int -X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - /* This function is (usually) called only once, by - * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, - argl, argp, new_func, dup_func, free_func); -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_ex_new_index); - -int -X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) -{ - return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_ex_data); - -void * -X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) -{ - return CRYPTO_get_ex_data(&ctx->ex_data, idx); -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_ex_data); - -int -X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) -{ - return ctx->error; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_error); - -void -X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) -{ - ctx->error = err; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_error); - -int -X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) -{ - return ctx->error_depth; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_error_depth); - -void -X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth) -{ - ctx->error_depth = depth; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_error_depth); - -X509 * -X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) -{ - return ctx->current_cert; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_current_cert); - -void -X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x) -{ - ctx->current_cert = x; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_current_cert); - -STACK_OF(X509) * -X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) -{ - return ctx->chain; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_chain); - -STACK_OF(X509) * -X509_STORE_CTX_get0_chain(X509_STORE_CTX *xs) -{ - return xs->chain; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_chain); - -STACK_OF(X509) * -X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) -{ - int i; - X509 *x; - STACK_OF(X509) *chain; - - if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) - return NULL; - for (i = 0; i < sk_X509_num(chain); i++) { - x = sk_X509_value(chain, i); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - } - return chain; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get1_chain); - -X509 * -X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) -{ - return ctx->current_issuer; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_current_issuer); - -X509_CRL * -X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) -{ - return ctx->current_crl; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_current_crl); - -X509_STORE_CTX * -X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) -{ - return ctx->parent; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_parent_ctx); - -X509_STORE * -X509_STORE_CTX_get0_store(X509_STORE_CTX *xs) -{ - return xs->store; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_store); - -void -X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) -{ - ctx->cert = x; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_cert); - -void -X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->untrusted = sk; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_chain); - -void -X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) -{ - ctx->crls = sk; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set0_crls); - -/* - * This function is used to set the X509_STORE_CTX purpose and trust - * values. This is intended to be used when another structure has its - * own trust and purpose values which (if set) will be inherited by - * the ctx. If they aren't set then we will usually have a default - * purpose in mind which should then be used to set the trust value. - * An example of this is SSL use: an SSL structure will have its own - * purpose and trust settings which the application can set: if they - * aren't set then we use the default of SSL client/server. - */ -int -X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose_id) -{ - const X509_PURPOSE *purpose; - int idx; - - /* XXX - Match wacky/documented behavior. Do we need to keep this? */ - if (purpose_id == 0) - return 1; - - if (purpose_id < X509_PURPOSE_MIN || purpose_id > X509_PURPOSE_MAX) { - X509error(X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - idx = purpose_id - X509_PURPOSE_MIN; - if ((purpose = X509_PURPOSE_get0(idx)) == NULL) { - X509error(X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - - /* XXX - Succeeding while ignoring purpose_id and trust is awful. */ - if (ctx->param->purpose == 0) - ctx->param->purpose = purpose_id; - if (ctx->param->trust == 0) - ctx->param->trust = X509_PURPOSE_get_trust(purpose); - - return 1; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_purpose); - -int -X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust_id) -{ - /* XXX - Match wacky/documented behavior. Do we need to keep this? */ - if (trust_id == 0) - return 1; - - if (trust_id < X509_TRUST_MIN || trust_id > X509_TRUST_MAX) { - X509error(X509_R_UNKNOWN_TRUST_ID); - return 0; - } - - /* XXX - Succeeding while ignoring the trust_id is awful. */ - if (ctx->param->trust == 0) - ctx->param->trust = trust_id; - - return 1; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_trust); - -X509_STORE_CTX * -X509_STORE_CTX_new(void) -{ - X509_STORE_CTX *ctx; - - ctx = calloc(1, sizeof(X509_STORE_CTX)); - if (!ctx) { - X509error(ERR_R_MALLOC_FAILURE); - return NULL; - } - return ctx; -} -LCRYPTO_ALIAS(X509_STORE_CTX_new); - -void -X509_STORE_CTX_free(X509_STORE_CTX *ctx) -{ - if (ctx == NULL) - return; - - X509_STORE_CTX_cleanup(ctx); - free(ctx); -} -LCRYPTO_ALIAS(X509_STORE_CTX_free); - -int -X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *leaf, - STACK_OF(X509) *untrusted) -{ - int param_ret = 1; - - /* - * Make sure everything is initialized properly even in case of an - * early return due to an error. - * - * While this 'ctx' can be reused, X509_STORE_CTX_cleanup() will have - * freed everything and memset ex_data anyway. This also allows us - * to safely use X509_STORE_CTX variables from the stack which will - * have uninitialized data. - */ - memset(ctx, 0, sizeof(*ctx)); - - /* - * Start with this set to not valid - it will be set to valid - * in X509_verify_cert. - */ - ctx->error = X509_V_ERR_INVALID_CALL; - - /* - * Set values other than 0. Keep this in the same order as - * X509_STORE_CTX except for values that may fail. All fields that - * may fail should go last to make sure 'ctx' is as consistent as - * possible even on early exits. - */ - ctx->store = store; - ctx->cert = leaf; - ctx->untrusted = untrusted; - - if (store && store->verify) - ctx->verify = store->verify; - else - ctx->verify = internal_verify; - - if (store && store->verify_cb) - ctx->verify_cb = store->verify_cb; - else - ctx->verify_cb = null_callback; - - ctx->get_issuer = X509_STORE_CTX_get1_issuer; - ctx->check_issued = check_issued; - - ctx->param = X509_VERIFY_PARAM_new(); - if (!ctx->param) { - X509error(ERR_R_MALLOC_FAILURE); - return 0; - } - - /* Inherit callbacks and flags from X509_STORE if not set - * use defaults. - */ - if (store) - param_ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); - else - ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE; - - if (param_ret) - param_ret = X509_VERIFY_PARAM_inherit(ctx->param, - X509_VERIFY_PARAM_lookup("default")); - - if (param_ret == 0) { - X509error(ERR_R_MALLOC_FAILURE); - return 0; - } - - if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, - &ctx->ex_data) == 0) { - X509error(ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; -} -LCRYPTO_ALIAS(X509_STORE_CTX_init); - -/* Set alternative lookup method: just a STACK of trusted certificates. - * This avoids X509_STORE nastiness where it isn't needed. - */ - -void -X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *trusted) -{ - X509_STORE_CTX_set0_trusted_stack(ctx, trusted); -} -LCRYPTO_ALIAS(X509_STORE_CTX_trusted_stack); - -void -X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *trusted) -{ - ctx->trusted = trusted; - ctx->get_issuer = x509_vfy_get_trusted_issuer; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set0_trusted_stack); - -void -X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) -{ - if (ctx->param != NULL) { - if (ctx->parent == NULL) - X509_VERIFY_PARAM_free(ctx->param); - ctx->param = NULL; - } - if (ctx->chain != NULL) { - sk_X509_pop_free(ctx->chain, X509_free); - ctx->chain = NULL; - } - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &ctx->ex_data); - memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); -} -LCRYPTO_ALIAS(X509_STORE_CTX_cleanup); - -void -X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_depth); - -void -X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) -{ - X509_VERIFY_PARAM_set_flags(ctx->param, flags); -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_flags); - -void -X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t) -{ - X509_VERIFY_PARAM_set_time(ctx->param, t); -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_time); - -int -(*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *) -{ - return ctx->verify_cb; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_verify_cb); - -void -X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb)(int, X509_STORE_CTX *)) -{ - ctx->verify_cb = verify_cb; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_verify_cb); - -int -(*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *) -{ - return ctx->verify; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_verify); - -void -X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, int (*verify)(X509_STORE_CTX *)) -{ - ctx->verify = verify; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_verify); - -X509_STORE_CTX_check_issued_fn -X509_STORE_get_check_issued(X509_STORE *store) -{ - return store->check_issued; -} -LCRYPTO_ALIAS(X509_STORE_get_check_issued); - -void -X509_STORE_set_check_issued(X509_STORE *store, - X509_STORE_CTX_check_issued_fn check_issued) -{ - store->check_issued = check_issued; -} -LCRYPTO_ALIAS(X509_STORE_set_check_issued); - -X509_STORE_CTX_check_issued_fn -X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx) -{ - return ctx->check_issued; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_check_issued); - -X509 * -X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) -{ - return ctx->cert; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_cert); - -STACK_OF(X509) * -X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) -{ - return ctx->untrusted; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_untrusted); - -void -X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->untrusted = sk; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set0_untrusted); - -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; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set0_verified_chain); - -int -X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx) -{ - return ctx->num_untrusted; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get_num_untrusted); - -int -X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) -{ - const X509_VERIFY_PARAM *param; - param = X509_VERIFY_PARAM_lookup(name); - if (!param) - return 0; - return X509_VERIFY_PARAM_inherit(ctx->param, param); -} -LCRYPTO_ALIAS(X509_STORE_CTX_set_default); - -X509_VERIFY_PARAM * -X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) -{ - return ctx->param; -} -LCRYPTO_ALIAS(X509_STORE_CTX_get0_param); - -void -X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) -{ - if (ctx->param) - X509_VERIFY_PARAM_free(ctx->param); - ctx->param = param; -} -LCRYPTO_ALIAS(X509_STORE_CTX_set0_param); - -/* - * Check if |bits| are adequate for |security level|. - * Returns 1 if ok, 0 otherwise. - */ -static int -enough_bits_for_security_level(int bits, int level) -{ - /* - * Sigh. OpenSSL does this silly squashing, so we will - * too. Derp for Derp compatibility being important. - */ - if (level < 0) - level = 0; - if (level > 5) - level = 5; - - switch (level) { - case 0: - return 1; - case 1: - return bits >= 80; - case 2: - return bits >= 112; - case 3: - return bits >= 128; - case 4: - return bits >= 192; - case 5: - return bits >= 256; - default: - return 0; - } -} - -/* - * Check whether the public key of |cert| meets the security level of |ctx|. - * - * Returns 1 on success, 0 otherwise. - */ -static int -check_key_level(X509_STORE_CTX *ctx, X509 *cert) -{ - EVP_PKEY *pkey; - int bits; - - /* Unsupported or malformed keys are not secure */ - if ((pkey = X509_get0_pubkey(cert)) == NULL) - return 0; - - if ((bits = EVP_PKEY_security_bits(pkey)) <= 0) - return 0; - - return enough_bits_for_security_level(bits, ctx->param->security_level); -} - -/* - * Check whether the signature digest algorithm of |cert| meets the security - * level of |ctx|. Do not check trust anchors (self-signed or not). - * - * Returns 1 on success, 0 otherwise. - */ -static int -check_sig_level(X509_STORE_CTX *ctx, X509 *cert) -{ - int bits; - - if (!X509_get_signature_info(cert, NULL, NULL, &bits, NULL)) - return 0; - - return enough_bits_for_security_level(bits, ctx->param->security_level); -} - -int -x509_vfy_check_security_level(X509_STORE_CTX *ctx) -{ - int num = sk_X509_num(ctx->chain); - int i; - - if (ctx->param->security_level <= 0) - return 1; - - for (i = 0; i < num; i++) { - X509 *cert = sk_X509_value(ctx->chain, i); - - /* - * We've already checked the security of the leaf key, so here - * we only check the security of issuer keys. - */ - if (i > 0) { - if (!check_key_level(ctx, cert) && - !verify_cb_cert(ctx, cert, i, - X509_V_ERR_CA_KEY_TOO_SMALL)) - return 0; - } - - /* - * We also check the signature algorithm security of all certs - * except those of the trust anchor at index num - 1. - */ - if (i == num - 1) - break; - - if (!check_sig_level(ctx, cert) && - !verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK)) - return 0; - } - return 1; -} diff --git a/src/lib/libcrypto/x509/x509_vfy.h b/src/lib/libcrypto/x509/x509_vfy.h deleted file mode 100644 index 7058bbc5b0..0000000000 --- a/src/lib/libcrypto/x509/x509_vfy.h +++ /dev/null @@ -1,463 +0,0 @@ -/* $OpenBSD: x509_vfy.h,v 1.70 2025/03/09 15:20:20 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_X509_H -#include -/* openssl/x509.h ends up #include-ing this file at about the only - * appropriate moment. */ -#endif - -#ifndef HEADER_X509_VFY_H -#define HEADER_X509_VFY_H - -#include - -#ifndef OPENSSL_NO_LHASH -#include -#endif -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * SSL_CTX -> X509_STORE - * -> X509_LOOKUP - * ->X509_LOOKUP_METHOD - * -> X509_LOOKUP - * ->X509_LOOKUP_METHOD - * - * SSL -> X509_STORE_CTX - * ->X509_STORE - * - * The X509_STORE holds the tables etc for verification stuff. - * A X509_STORE_CTX is used while validating a single certificate. - * The X509_STORE has X509_LOOKUPs for looking up certs. - * The X509_STORE then calls a function to actually verify the - * certificate chain. - */ - -typedef enum { - X509_LU_NONE, - X509_LU_X509, - X509_LU_CRL, -} X509_LOOKUP_TYPE; - - -DECLARE_STACK_OF(X509_LOOKUP) -DECLARE_STACK_OF(X509_OBJECT) -DECLARE_STACK_OF(X509_VERIFY_PARAM) - -/* XXX - unused in OpenSSL. Can we remove this? */ -typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID; - - -int X509_STORE_set_depth(X509_STORE *store, int depth); - -void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); - -#define X509_STORE_CTX_set_app_data(ctx,data) \ - X509_STORE_CTX_set_ex_data(ctx,0,data) -#define X509_STORE_CTX_get_app_data(ctx) \ - X509_STORE_CTX_get_ex_data(ctx,0) - -#define X509_L_FILE_LOAD 1 -#define X509_L_ADD_DIR 2 -#define X509_L_MEM 3 - -#define X509_LOOKUP_load_file(x,name,type) \ - X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) - -#define X509_LOOKUP_add_dir(x,name,type) \ - X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) - -#define X509_LOOKUP_add_mem(x,iov,type) \ - X509_LOOKUP_ctrl((x),X509_L_MEM,(const char *)(iov),\ - (long)(type),NULL) - -#define X509_V_OK 0 -#define X509_V_ERR_UNSPECIFIED 1 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 -#define X509_V_ERR_UNABLE_TO_GET_CRL 3 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 -#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 -#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 -#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 -#define X509_V_ERR_CERT_NOT_YET_VALID 9 -#define X509_V_ERR_CERT_HAS_EXPIRED 10 -#define X509_V_ERR_CRL_NOT_YET_VALID 11 -#define X509_V_ERR_CRL_HAS_EXPIRED 12 -#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 -#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 -#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 -#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 -#define X509_V_ERR_OUT_OF_MEM 17 -#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 -#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 -#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 -#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 -#define X509_V_ERR_CERT_REVOKED 23 -#define X509_V_ERR_INVALID_CA 24 -#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 -#define X509_V_ERR_INVALID_PURPOSE 26 -#define X509_V_ERR_CERT_UNTRUSTED 27 -#define X509_V_ERR_CERT_REJECTED 28 -/* These are 'informational' when looking for issuer cert */ -#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 -#define X509_V_ERR_AKID_SKID_MISMATCH 30 -#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 -#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 - -#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 -#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 -#define X509_V_ERR_INVALID_NON_CA 37 -#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 -#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 -#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 - -#define X509_V_ERR_INVALID_EXTENSION 41 -#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 -#define X509_V_ERR_NO_EXPLICIT_POLICY 43 -#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 -#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 - -#define X509_V_ERR_UNNESTED_RESOURCE 46 - -#define X509_V_ERR_PERMITTED_VIOLATION 47 -#define X509_V_ERR_EXCLUDED_VIOLATION 48 -#define X509_V_ERR_SUBTREE_MINMAX 49 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 -#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 -#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 - -/* The application is not happy */ -#define X509_V_ERR_APPLICATION_VERIFICATION 50 - -/* Host, email and IP check errors */ -#define X509_V_ERR_HOSTNAME_MISMATCH 62 -#define X509_V_ERR_EMAIL_MISMATCH 63 -#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 - -/* Caller error */ -#define X509_V_ERR_INVALID_CALL 65 -/* Issuer lookup error */ -#define X509_V_ERR_STORE_LOOKUP 66 - -/* Security level errors */ -#define X509_V_ERR_EE_KEY_TOO_SMALL 67 -#define X509_V_ERR_CA_KEY_TOO_SMALL 68 -#define X509_V_ERR_CA_MD_TOO_WEAK 69 - -/* Certificate verify flags */ - -/* Deprecated in 1.1.0, has no effect. Various FFI bindings still expose it. */ -#define X509_V_FLAG_CB_ISSUER_CHECK 0x0 -/* Use check time instead of current time */ -#define X509_V_FLAG_USE_CHECK_TIME 0x2 -/* Lookup CRLs */ -#define X509_V_FLAG_CRL_CHECK 0x4 -/* Lookup CRLs for whole chain */ -#define X509_V_FLAG_CRL_CHECK_ALL 0x8 -/* Ignore unhandled critical extensions */ -#define X509_V_FLAG_IGNORE_CRITICAL 0x10 -/* Disable workarounds for broken certificates */ -#define X509_V_FLAG_X509_STRICT 0x20 -/* Enable proxy certificate validation */ -#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 -/* Does nothing as its functionality has been enabled by default */ -#define X509_V_FLAG_POLICY_CHECK 0x80 -/* Policy variable require-explicit-policy */ -#define X509_V_FLAG_EXPLICIT_POLICY 0x100 -/* Policy variable inhibit-any-policy */ -#define X509_V_FLAG_INHIBIT_ANY 0x200 -/* Policy variable inhibit-policy-mapping */ -#define X509_V_FLAG_INHIBIT_MAP 0x400 -/* Notify callback that policy is OK */ -#define X509_V_FLAG_NOTIFY_POLICY 0x800 -/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ -#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 -/* Delta CRL support */ -#define X509_V_FLAG_USE_DELTAS 0x2000 -/* Check selfsigned CA signature */ -#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 -/* Use trusted store first */ -#define X509_V_FLAG_TRUSTED_FIRST 0x8000 -/* Allow partial chains if at least one certificate is in trusted store */ -#define X509_V_FLAG_PARTIAL_CHAIN 0x80000 - -/* If the initial chain is not trusted, do not attempt to build an alternative - * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag - * will force the behaviour to match that of previous versions. */ -#define X509_V_FLAG_NO_ALT_CHAINS 0x100000 - -/* Do not check certificate or CRL validity against current time. */ -#define X509_V_FLAG_NO_CHECK_TIME 0x200000 - -/* Force the use of the legacy certificate verification */ -#define X509_V_FLAG_LEGACY_VERIFY 0x400000 - -#define X509_VP_FLAG_DEFAULT 0x1 -#define X509_VP_FLAG_OVERWRITE 0x2 -#define X509_VP_FLAG_RESET_FLAGS 0x4 -#define X509_VP_FLAG_LOCKED 0x8 -#define X509_VP_FLAG_ONCE 0x10 - -/* - * Obsolete internal use: mask of policy related options. - * This should really go away. - */ -#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ - | X509_V_FLAG_EXPLICIT_POLICY \ - | X509_V_FLAG_INHIBIT_ANY \ - | X509_V_FLAG_INHIBIT_MAP) - -X509_OBJECT *X509_OBJECT_new(void); -void X509_OBJECT_free(X509_OBJECT *a); -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, - X509_NAME *name); -X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, - X509_LOOKUP_TYPE type, X509_NAME *name); -X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); -X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a); -X509 *X509_OBJECT_get0_X509(const X509_OBJECT *xo); -X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo); - -X509_STORE *X509_STORE_new(void); -void X509_STORE_free(X509_STORE *v); -int X509_STORE_up_ref(X509_STORE *x); -#define X509_STORE_get1_certs X509_STORE_CTX_get1_certs -#define X509_STORE_get1_crls X509_STORE_CTX_get1_crls -STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); -STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); -STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *xs); -STACK_OF(X509_OBJECT) *X509_STORE_get1_objects(X509_STORE *xs); -void *X509_STORE_get_ex_data(X509_STORE *xs, int idx); -int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data); - -#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ - CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \ - (newf), (dupf), (freef)) - -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); -int X509_STORE_set_trust(X509_STORE *ctx, int trust); -int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); -X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); - -typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); - -X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *); - -void X509_STORE_set_verify_cb(X509_STORE *ctx, - int (*verify_cb)(int, X509_STORE_CTX *)); -#define X509_STORE_set_verify_cb_func(ctx, func) \ - X509_STORE_set_verify_cb((ctx), (func)) - -typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, - X509 *subject, X509 *issuer); - -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *store); -void X509_STORE_set_check_issued(X509_STORE *store, - X509_STORE_CTX_check_issued_fn check_issued); -X509_STORE_CTX_check_issued_fn - X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx); - -X509_STORE_CTX *X509_STORE_CTX_new(void); - -int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); - -void X509_STORE_CTX_free(X509_STORE_CTX *ctx); -int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, - X509 *x509, STACK_OF(X509) *chain); -X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); -STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *xs); -X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *xs); -STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); -void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); -void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); - -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, const X509_LOOKUP_METHOD *m); - -const X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); -const X509_LOOKUP_METHOD *X509_LOOKUP_file(void); -const X509_LOOKUP_METHOD *X509_LOOKUP_mem(void); - -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); - -int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret); -#define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject -X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, - X509_LOOKUP_TYPE type, X509_NAME *name); - -int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret); - -int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); -int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); -int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); - -void X509_LOOKUP_free(X509_LOOKUP *ctx); - -int X509_STORE_load_locations(X509_STORE *ctx, - const char *file, const char *dir); -int X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len); -int X509_STORE_set_default_paths(X509_STORE *ctx); - -int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); -void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth); -X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x); -X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); -X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); -X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); -STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); -STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); -void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); -void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); -int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); -int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); -void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); -void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, - time_t t); -void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); -int (*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *); -void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, - int (*verify)(X509_STORE_CTX *)); -int (*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *); -void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb)(int, X509_STORE_CTX *)); - -typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); - -void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); -X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); -#define X509_STORE_set_verify_func(ctx, func) \ - X509_STORE_set_verify((ctx), (func)) - -int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); - -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); -int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); - -/* X509_VERIFY_PARAM functions */ - -X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); -void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from); -int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from); -int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); -int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); -int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, - unsigned long flags); -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); -int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); -void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); -void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level); -time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param); -void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); -int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, - ASN1_OBJECT *policy); -int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, - STACK_OF(ASN1_OBJECT) *policies); -int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, - size_t namelen); -int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, const char *name, - size_t namelen); -void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned int flags); -char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, - size_t emaillen); -int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, - size_t iplen); -int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc); -const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); -int X509_VERIFY_PARAM_get_count(void); - -int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); -void X509_VERIFY_PARAM_table_cleanup(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c deleted file mode 100644 index 9efe473fc3..0000000000 --- a/src/lib/libcrypto/x509/x509_vpm.c +++ /dev/null @@ -1,743 +0,0 @@ -/* $OpenBSD: x509_vpm.c,v 1.55 2025/03/19 17:11:21 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "x509_local.h" - -/* X509_VERIFY_PARAM functions */ - -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, - size_t emaillen); -int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, - size_t iplen); - -#define SET_HOST 0 -#define ADD_HOST 1 - -static void -str_free(char *s) -{ - free(s); -} - -static STACK_OF(OPENSSL_STRING) * -sk_OPENSSL_STRING_deep_copy(const STACK_OF(OPENSSL_STRING) *sk) -{ - STACK_OF(OPENSSL_STRING) *new; - char *copy = NULL; - int i; - - if ((new = sk_OPENSSL_STRING_new_null()) == NULL) - goto err; - - for (i = 0; i < sk_OPENSSL_STRING_num(sk); i++) { - if ((copy = strdup(sk_OPENSSL_STRING_value(sk, i))) == NULL) - goto err; - if (sk_OPENSSL_STRING_push(new, copy) <= 0) - goto err; - copy = NULL; - } - - return new; - - err: - sk_OPENSSL_STRING_pop_free(new, str_free); - free(copy); - - return NULL; -} - -static int -x509_param_set_hosts_internal(X509_VERIFY_PARAM *param, int mode, - const char *name, size_t namelen) -{ - char *copy; - - if (name != NULL && namelen == 0) - namelen = strlen(name); - /* - * Refuse names with embedded NUL bytes. - */ - if (name && memchr(name, '\0', namelen)) - return 0; - - if (mode == SET_HOST && param->hosts) { - sk_OPENSSL_STRING_pop_free(param->hosts, str_free); - param->hosts = NULL; - } - if (name == NULL || namelen == 0) - return 1; - copy = strndup(name, namelen); - if (copy == NULL) - return 0; - - if (param->hosts == NULL && - (param->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { - free(copy); - return 0; - } - - if (!sk_OPENSSL_STRING_push(param->hosts, copy)) { - free(copy); - if (sk_OPENSSL_STRING_num(param->hosts) == 0) { - sk_OPENSSL_STRING_free(param->hosts); - param->hosts = NULL; - } - return 0; - } - - return 1; -} - -static void -x509_verify_param_zero(X509_VERIFY_PARAM *param) -{ - if (!param) - return; - - free(param->name); - param->name = NULL; - param->purpose = 0; - param->trust = 0; - /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ - param->inh_flags = 0; - param->flags = 0; - param->depth = -1; - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - param->policies = NULL; - sk_OPENSSL_STRING_pop_free(param->hosts, str_free); - param->hosts = NULL; - free(param->peername); - param->peername = NULL; - free(param->email); - param->email = NULL; - param->emaillen = 0; - free(param->ip); - param->ip = NULL; - param->iplen = 0; - param->poisoned = 0; -} - -X509_VERIFY_PARAM * -X509_VERIFY_PARAM_new(void) -{ - X509_VERIFY_PARAM *param; - - param = calloc(1, sizeof(X509_VERIFY_PARAM)); - if (param == NULL) - return NULL; - x509_verify_param_zero(param); - return param; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_new); - -void -X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) -{ - if (param == NULL) - return; - x509_verify_param_zero(param); - free(param); -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_free); - -/* - * This function determines how parameters are "inherited" from one structure - * to another. There are several different ways this can happen. - * - * 1. If a child structure needs to have its values initialized from a parent - * they are simply copied across. For example SSL_CTX copied to SSL. - * 2. If the structure should take on values only if they are currently unset. - * For example the values in an SSL structure will take appropriate value - * for SSL servers or clients but only if the application has not set new - * ones. - * - * The "inh_flags" field determines how this function behaves. - * - * Normally any values which are set in the default are not copied from the - * destination and verify flags are ORed together. - * - * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied - * to the destination. Effectively the values in "to" become default values - * which will be used only if nothing new is set in "from". - * - * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether - * they are set or not. Flags is still Ored though. - * - * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead - * of ORed. - * - * If X509_VP_FLAG_LOCKED is set then no values are copied. - * - * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed - * after the next call. - */ - -/* Macro to test if a field should be copied from src to dest */ -#define test_x509_verify_param_copy(field, def) \ - (to_overwrite || \ - ((src->field != def) && (to_default || (dest->field == def)))) - -/* Macro to test and copy a field if necessary */ -#define x509_verify_param_copy(field, def) \ - if (test_x509_verify_param_copy(field, def)) \ - dest->field = src->field - -int -X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) -{ - unsigned long inh_flags; - int to_default, to_overwrite; - - if (!src) - return 1; - inh_flags = dest->inh_flags | src->inh_flags; - - if (inh_flags & X509_VP_FLAG_ONCE) - dest->inh_flags = 0; - - if (inh_flags & X509_VP_FLAG_LOCKED) - return 1; - - if (inh_flags & X509_VP_FLAG_DEFAULT) - to_default = 1; - else - to_default = 0; - - if (inh_flags & X509_VP_FLAG_OVERWRITE) - to_overwrite = 1; - else - to_overwrite = 0; - - x509_verify_param_copy(purpose, 0); - x509_verify_param_copy(trust, 0); - x509_verify_param_copy(depth, -1); - - /* If overwrite or check time not set, copy across */ - - if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { - dest->check_time = src->check_time; - dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; - /* Don't need to copy flag: that is done below */ - } - - if (inh_flags & X509_VP_FLAG_RESET_FLAGS) - dest->flags = 0; - - dest->flags |= src->flags; - - if (test_x509_verify_param_copy(policies, NULL)) { - if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) - return 0; - } - - x509_verify_param_copy(hostflags, 0); - - if (test_x509_verify_param_copy(hosts, NULL)) { - if (dest->hosts) { - sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); - dest->hosts = NULL; - } - if (src->hosts) { - dest->hosts = sk_OPENSSL_STRING_deep_copy(src->hosts); - if (dest->hosts == NULL) - return 0; - } - } - - if (test_x509_verify_param_copy(email, NULL)) { - if (!X509_VERIFY_PARAM_set1_email(dest, src->email, - src->emaillen)) - return 0; - } - - if (test_x509_verify_param_copy(ip, NULL)) { - if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) - return 0; - } - - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit); - -int -X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) -{ - unsigned long save_flags = to->inh_flags; - int ret; - - to->inh_flags |= X509_VP_FLAG_DEFAULT; - ret = X509_VERIFY_PARAM_inherit(to, from); - to->inh_flags = save_flags; - return ret; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1); - -static int -x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src, - size_t srclen, int nonul) -{ - char *tmp; - - if (src == NULL) - return 0; - - if (srclen == 0) { - srclen = strlen(src); - if (srclen == 0) - return 0; - if ((tmp = strdup(src)) == NULL) - return 0; - } else { - if (nonul && memchr(src, '\0', srclen)) - return 0; - if ((tmp = malloc(srclen)) == NULL) - return 0; - memcpy(tmp, src, srclen); - } - - if (*pdest) - free(*pdest); - *pdest = tmp; - if (pdestlen) - *pdestlen = srclen; - return 1; -} - -int -X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) -{ - free(param->name); - param->name = NULL; - if (name == NULL) - return 1; - param->name = strdup(name); - if (param->name) - return 1; - return 0; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name); - -int -X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) -{ - param->flags |= flags; - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags); - -int -X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) -{ - param->flags &= ~flags; - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags); - -unsigned long -X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) -{ - return param->flags; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags); - -int -X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) -{ - if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) { - X509V3error(X509V3_R_INVALID_PURPOSE); - return 0; - } - - param->purpose = purpose; - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose); - -int -X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) -{ - if (trust < X509_TRUST_MIN || trust > X509_TRUST_MAX) { - X509error(X509_R_INVALID_TRUST); - return 0; - } - - param->trust = trust; - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust); - -void -X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) -{ - param->depth = depth; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth); - -void -X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level) -{ - param->security_level = auth_level; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level); - -time_t -X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param) -{ - return param->check_time; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time); - -void -X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) -{ - param->check_time = t; - param->flags |= X509_V_FLAG_USE_CHECK_TIME; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time); - -int -X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) -{ - if (param->policies == NULL) - param->policies = sk_ASN1_OBJECT_new_null(); - if (param->policies == NULL) - return 0; - if (sk_ASN1_OBJECT_push(param->policies, policy) <= 0) - return 0; - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy); - -static STACK_OF(ASN1_OBJECT) * -sk_ASN1_OBJECT_deep_copy(const STACK_OF(ASN1_OBJECT) *sk) -{ - STACK_OF(ASN1_OBJECT) *objs; - ASN1_OBJECT *obj = NULL; - int i; - - if ((objs = sk_ASN1_OBJECT_new_null()) == NULL) - goto err; - - for (i = 0; i < sk_ASN1_OBJECT_num(sk); i++) { - if ((obj = OBJ_dup(sk_ASN1_OBJECT_value(sk, i))) == NULL) - goto err; - if (sk_ASN1_OBJECT_push(objs, obj) <= 0) - goto err; - obj = NULL; - } - - return objs; - - err: - sk_ASN1_OBJECT_pop_free(objs, ASN1_OBJECT_free); - ASN1_OBJECT_free(obj); - - return NULL; -} - -int -X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, - STACK_OF(ASN1_OBJECT) *policies) -{ - if (param == NULL) - return 0; - - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - param->policies = NULL; - - if (policies == NULL) - return 1; - - if ((param->policies = sk_ASN1_OBJECT_deep_copy(policies)) == NULL) - return 0; - - return 1; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies); - -int -X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - if (x509_param_set_hosts_internal(param, SET_HOST, name, namelen)) - return 1; - param->poisoned = 1; - return 0; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host); - -int -X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - if (x509_param_set_hosts_internal(param, ADD_HOST, name, namelen)) - return 1; - param->poisoned = 1; - return 0; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host); - -/* Public API in OpenSSL - nothing seems to use this. */ -unsigned int -X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param) -{ - return param->hostflags; -} - -void -X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags) -{ - param->hostflags = flags; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags); - -char * -X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) -{ - return param->peername; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername); - -int -X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, - size_t emaillen) -{ - if (x509_param_set1_internal(¶m->email, ¶m->emaillen, - email, emaillen, 1)) - return 1; - param->poisoned = 1; - return 0; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email); - -int -X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, - size_t iplen) -{ - if (iplen != 4 && iplen != 16) - goto err; - if (x509_param_set1_internal((char **)¶m->ip, ¶m->iplen, - (char *)ip, iplen, 0)) - return 1; - err: - param->poisoned = 1; - return 0; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip); - -int -X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) -{ - unsigned char ipout[16]; - size_t iplen; - - iplen = (size_t)a2i_ipadd(ipout, ipasc); - return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc); - -int -X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) -{ - return param->depth; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth); - -const char * -X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) -{ - return param->name; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_name); - -/* - * Default verify parameters: these are used for various applications and can - * be overridden by the user specified table. - */ - -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 */ - }, - { - .name = "pkcs7", - .purpose = X509_PURPOSE_SMIME_SIGN, - .trust = X509_TRUST_EMAIL, - .depth = -1, - }, - { - .name = "smime_sign", - .purpose = X509_PURPOSE_SMIME_SIGN, - .trust = X509_TRUST_EMAIL, - .depth = -1, - }, - { - .name = "ssl_client", - .purpose = X509_PURPOSE_SSL_CLIENT, - .trust = X509_TRUST_SSL_CLIENT, - .depth = -1, - }, - { - .name = "ssl_server", - .purpose = X509_PURPOSE_SSL_SERVER, - .trust = X509_TRUST_SSL_SERVER, - .depth = -1, - } -}; - -#define N_DEFAULT_VERIFY_PARAMS (sizeof(default_table) / sizeof(default_table[0])) - -static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; - -static int -param_cmp(const X509_VERIFY_PARAM * const *a, - const X509_VERIFY_PARAM * const *b) -{ - return strcmp((*a)->name, (*b)->name); -} - -int -X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) -{ - X509_VERIFY_PARAM *ptmp; - int idx; - - if (param_table == NULL) - param_table = sk_X509_VERIFY_PARAM_new(param_cmp); - if (param_table == NULL) - return 0; - - if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param)) != -1) { - ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); - X509_VERIFY_PARAM_free(ptmp); - (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); - } - - return sk_X509_VERIFY_PARAM_push(param_table, param) > 0; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table); - -int -X509_VERIFY_PARAM_get_count(void) -{ - int num = N_DEFAULT_VERIFY_PARAMS; - - if (param_table != NULL) - num += sk_X509_VERIFY_PARAM_num(param_table); - - return num; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count); - -const X509_VERIFY_PARAM * -X509_VERIFY_PARAM_get0(int id) -{ - int num = N_DEFAULT_VERIFY_PARAMS; - - if (id < 0) - return NULL; - - if (id < num) - return &default_table[id]; - - return sk_X509_VERIFY_PARAM_value(param_table, id - num); -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0); - -const X509_VERIFY_PARAM * -X509_VERIFY_PARAM_lookup(const char *name) -{ - X509_VERIFY_PARAM param; - size_t i; - int idx; - - memset(¶m, 0, sizeof(param)); - param.name = (char *)name; - if ((idx = sk_X509_VERIFY_PARAM_find(param_table, ¶m)) != -1) - return sk_X509_VERIFY_PARAM_value(param_table, idx); - - for (i = 0; i < N_DEFAULT_VERIFY_PARAMS; i++) { - if (strcmp(default_table[i].name, name) == 0) - return &default_table[i]; - } - - return NULL; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup); - -void -X509_VERIFY_PARAM_table_cleanup(void) -{ - sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); - param_table = NULL; -} -LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup); diff --git a/src/lib/libcrypto/x509/x509cset.c b/src/lib/libcrypto/x509/x509cset.c deleted file mode 100644 index 468831266f..0000000000 --- a/src/lib/libcrypto/x509/x509cset.c +++ /dev/null @@ -1,238 +0,0 @@ -/* $OpenBSD: x509cset.c,v 1.22 2024/03/26 23:41:45 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -int -X509_CRL_up_ref(X509_CRL *x) -{ - return CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL) > 1; -} -LCRYPTO_ALIAS(X509_CRL_up_ref); - -int -X509_CRL_set_version(X509_CRL *x, long version) -{ - if (x == NULL) - return 0; - /* - * RFC 5280, 4.1: versions 1 - 3 are specified as follows. - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - * The only specified versions for CRLs are 1 and 2. - */ - if (version < 0 || version > 1) - return 0; - if (x->crl->version == NULL) { - if ((x->crl->version = ASN1_INTEGER_new()) == NULL) - return 0; - } - return ASN1_INTEGER_set(x->crl->version, version); -} -LCRYPTO_ALIAS(X509_CRL_set_version); - -int -X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) -{ - if (x == NULL || x->crl == NULL) - return 0; - return X509_NAME_set(&x->crl->issuer, name); -} -LCRYPTO_ALIAS(X509_CRL_set_issuer_name); - -int -X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL) - return 0; - in = x->crl->lastUpdate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->crl->lastUpdate); - x->crl->lastUpdate = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_CRL_set_lastUpdate); - -int -X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - return X509_CRL_set_lastUpdate(x, tm); -} -LCRYPTO_ALIAS(X509_CRL_set1_lastUpdate); - -int -X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL) - return 0; - in = x->crl->nextUpdate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->crl->nextUpdate); - x->crl->nextUpdate = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_CRL_set_nextUpdate); - -int -X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - return X509_CRL_set_nextUpdate(x, tm); -} -LCRYPTO_ALIAS(X509_CRL_set1_nextUpdate); - -int -X509_CRL_sort(X509_CRL *c) -{ - X509_REVOKED *r; - int i; - - /* Sort the data so it will be written in serial number order */ - sk_X509_REVOKED_sort(c->crl->revoked); - for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) { - r = sk_X509_REVOKED_value(c->crl->revoked, i); - r->sequence = i; - } - c->crl->enc.modified = 1; - return 1; -} -LCRYPTO_ALIAS(X509_CRL_sort); - -const STACK_OF(X509_EXTENSION) * -X509_REVOKED_get0_extensions(const X509_REVOKED *x) -{ - return x->extensions; -} -LCRYPTO_ALIAS(X509_REVOKED_get0_extensions); - -const ASN1_TIME * -X509_REVOKED_get0_revocationDate(const X509_REVOKED *x) -{ - return x->revocationDate; -} -LCRYPTO_ALIAS(X509_REVOKED_get0_revocationDate); - -const ASN1_INTEGER * -X509_REVOKED_get0_serialNumber(const X509_REVOKED *x) -{ - return x->serialNumber; -} -LCRYPTO_ALIAS(X509_REVOKED_get0_serialNumber); - -int -X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL) - return 0; - in = x->revocationDate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->revocationDate); - x->revocationDate = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_REVOKED_set_revocationDate); - -int -X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in; - - if (x == NULL) - return 0; - in = x->serialNumber; - if (in != serial) { - in = ASN1_INTEGER_dup(serial); - if (in != NULL) { - ASN1_INTEGER_free(x->serialNumber); - x->serialNumber = in; - } - } - return in != NULL; -} -LCRYPTO_ALIAS(X509_REVOKED_set_serialNumber); - -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); -} -LCRYPTO_ALIAS(i2d_re_X509_CRL_tbs); diff --git a/src/lib/libcrypto/x509/x509name.c b/src/lib/libcrypto/x509/x509name.c deleted file mode 100644 index d2df06ccc6..0000000000 --- a/src/lib/libcrypto/x509/x509name.c +++ /dev/null @@ -1,452 +0,0 @@ -/* $OpenBSD: x509name.c,v 1.35 2023/05/29 11:54:50 beck Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "bytestring.h" -#include "x509_local.h" - -int -X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-1); - return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); -} -LCRYPTO_ALIAS(X509_NAME_get_text_by_NID); - -int -X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf, - int len) -{ - unsigned char *text = NULL; - ASN1_STRING *data; - int i, text_len; - int ret = -1; - CBS cbs; - - i = X509_NAME_get_index_by_OBJ(name, obj, -1); - if (i < 0) - goto err; - data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); - /* - * Fail if we cannot encode as UTF-8, or if the UTF-8 encoding of the - * string contains a 0 byte, because mortal callers seldom handle the - * length difference correctly. - */ - if ((text_len = ASN1_STRING_to_UTF8(&text, data)) < 0) - goto err; - CBS_init(&cbs, text, text_len); - if (CBS_contains_zero_byte(&cbs)) - goto err; - /* We still support the "pass NULL to find out how much" API */ - if (buf != NULL) { - if (len <= 0 || !CBS_write_bytes(&cbs, buf, len - 1, NULL)) - goto err; - /* It must be a C string */ - buf[text_len] = '\0'; - } - ret = text_len; - - err: - free(text); - return (ret); -} -LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ); - -int -X509_NAME_entry_count(const X509_NAME *name) -{ - if (name == NULL) - return (0); - return (sk_X509_NAME_ENTRY_num(name->entries)); -} -LCRYPTO_ALIAS(X509_NAME_entry_count); - -int -X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-2); - return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); -} -LCRYPTO_ALIAS(X509_NAME_get_index_by_NID); - -/* NOTE: you should be passing -1, not 0 as lastpos */ -int -X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, - int lastpos) -{ - int n; - X509_NAME_ENTRY *ne; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL) - return (-1); - if (lastpos < 0) - lastpos = -1; - sk = name->entries; - n = sk_X509_NAME_ENTRY_num(sk); - for (lastpos++; lastpos < n; lastpos++) { - ne = sk_X509_NAME_ENTRY_value(sk, lastpos); - if (OBJ_cmp(ne->object, obj) == 0) - return (lastpos); - } - return (-1); -} -LCRYPTO_ALIAS(X509_NAME_get_index_by_OBJ); - -X509_NAME_ENTRY * -X509_NAME_get_entry(const X509_NAME *name, int loc) -{ - if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc || - loc < 0) - return (NULL); - else - return (sk_X509_NAME_ENTRY_value(name->entries, loc)); -} -LCRYPTO_ALIAS(X509_NAME_get_entry); - -X509_NAME_ENTRY * -X509_NAME_delete_entry(X509_NAME *name, int loc) -{ - X509_NAME_ENTRY *ret; - int i, n, set_prev, set_next; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc || - loc < 0) - return (NULL); - sk = name->entries; - ret = sk_X509_NAME_ENTRY_delete(sk, loc); - n = sk_X509_NAME_ENTRY_num(sk); - name->modified = 1; - if (loc == n) - return (ret); - - /* else we need to fixup the set field */ - if (loc != 0) - set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; - else - set_prev = ret->set - 1; - set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; - - /* set_prev is the previous set - * set is the current set - * set_next is the following - * prev 1 1 1 1 1 1 1 1 - * set 1 1 2 2 - * next 1 1 2 2 2 2 3 2 - * so basically only if prev and next differ by 2, then - * re-number down by 1 */ - if (set_prev + 1 < set_next) - for (i = loc; i < n; i++) - sk_X509_NAME_ENTRY_value(sk, i)->set--; - return (ret); -} -LCRYPTO_ALIAS(X509_NAME_delete_entry); - -int -X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len, int loc, int set) -{ - X509_NAME_ENTRY *ne; - int ret; - - ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; -} -LCRYPTO_ALIAS(X509_NAME_add_entry_by_OBJ); - -int -X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, - const unsigned char *bytes, int len, int loc, int set) -{ - X509_NAME_ENTRY *ne; - int ret; - - ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; -} -LCRYPTO_ALIAS(X509_NAME_add_entry_by_NID); - -int -X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, - const unsigned char *bytes, int len, int loc, int set) -{ - X509_NAME_ENTRY *ne; - int ret; - - ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; -} -LCRYPTO_ALIAS(X509_NAME_add_entry_by_txt); - -/* if set is -1, append to previous set, 0 'a new one', and 1, - * prepend to the guy we are about to stomp on. */ -int -X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, - int set) -{ - X509_NAME_ENTRY *new_name = NULL; - int n, i, inc; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL) - return (0); - sk = name->entries; - n = sk_X509_NAME_ENTRY_num(sk); - if (loc > n) - loc = n; - else if (loc < 0) - loc = n; - inc = (set == 0); - name->modified = 1; - - if (set == -1) { - if (loc == 0) { - set = 0; - inc = 1; - } else - set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; - } else /* if (set >= 0) */ { - if (loc >= n) { - if (loc != 0) - set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; - else - set = 0; - } else - set = sk_X509_NAME_ENTRY_value(sk, loc)->set; - } - - /* OpenSSL has ASN1-generated X509_NAME_ENTRY_dup() without const. */ - if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL) - goto err; - new_name->set = set; - if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { - X509error(ERR_R_MALLOC_FAILURE); - goto err; - } - if (inc) { - n = sk_X509_NAME_ENTRY_num(sk); - for (i = loc + 1; i < n; i++) - sk_X509_NAME_ENTRY_value(sk, i)->set += 1; - } - return (1); - -err: - if (new_name != NULL) - X509_NAME_ENTRY_free(new_name); - return (0); -} -LCRYPTO_ALIAS(X509_NAME_add_entry); - -X509_NAME_ENTRY * -X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, - const char *field, int type, const unsigned char *bytes, int len) -{ - ASN1_OBJECT *obj; - X509_NAME_ENTRY *nentry; - - obj = OBJ_txt2obj(field, 0); - if (obj == NULL) { - X509error(X509_R_INVALID_FIELD_NAME); - ERR_asprintf_error_data("name=%s", field); - return (NULL); - } - nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nentry; -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_txt); - -X509_NAME_ENTRY * -X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type, - const unsigned char *bytes, int len) -{ - ASN1_OBJECT *obj; - X509_NAME_ENTRY *nentry; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - X509error(X509_R_UNKNOWN_NID); - return (NULL); - } - nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nentry; -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_NID); - -X509_NAME_ENTRY * -X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, const ASN1_OBJECT *obj, - int type, const unsigned char *bytes, int len) -{ - X509_NAME_ENTRY *ret; - - if ((ne == NULL) || (*ne == NULL)) { - if ((ret = X509_NAME_ENTRY_new()) == NULL) - return (NULL); - } else - ret= *ne; - - if (!X509_NAME_ENTRY_set_object(ret, obj)) - goto err; - if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) - goto err; - - if ((ne != NULL) && (*ne == NULL)) - *ne = ret; - return (ret); - -err: - if ((ne == NULL) || (ret != *ne)) - X509_NAME_ENTRY_free(ret); - return (NULL); -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_OBJ); - -int -X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) -{ - if ((ne == NULL) || (obj == NULL)) { - X509error(ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - ASN1_OBJECT_free(ne->object); - ne->object = OBJ_dup(obj); - return ((ne->object == NULL) ? 0 : 1); -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_set_object); - -int -X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, - const unsigned char *bytes, int len) -{ - int i; - - if ((ne == NULL) || ((bytes == NULL) && (len != 0))) - return (0); - if ((type > 0) && (type & MBSTRING_FLAG)) - return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type, - OBJ_obj2nid(ne->object)) ? 1 : 0; - if (len < 0) - len = strlen((const char *)bytes); - i = ASN1_STRING_set(ne->value, bytes, len); - if (!i) - return (0); - if (type != V_ASN1_UNDEF) { - if (type == V_ASN1_APP_CHOOSE) - ne->value->type = ASN1_PRINTABLE_type(bytes, len); - else - ne->value->type = type; - } - return (1); -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_set_data); - -ASN1_OBJECT * -X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) -{ - if (ne == NULL) - return (NULL); - return (ne->object); -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_get_object); - -ASN1_STRING * -X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) -{ - if (ne == NULL) - return (NULL); - return (ne->value); -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_get_data); - -int -X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) -{ - return (ne->set); -} -LCRYPTO_ALIAS(X509_NAME_ENTRY_set); diff --git a/src/lib/libcrypto/x509/x509rset.c b/src/lib/libcrypto/x509/x509rset.c deleted file mode 100644 index 2e2d4abd08..0000000000 --- a/src/lib/libcrypto/x509/x509rset.c +++ /dev/null @@ -1,113 +0,0 @@ -/* $OpenBSD: x509rset.c,v 1.16 2024/03/26 23:45:05 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include -#include - -#include "x509_local.h" - -int -X509_REQ_set_version(X509_REQ *x, long version) -{ - if (x == NULL) - return 0; - /* RFC 2986 section 4.1 only specifies version 1, encoded as a 0. */ - if (version != 0) - return 0; - x->req_info->enc.modified = 1; - return ASN1_INTEGER_set(x->req_info->version, version); -} -LCRYPTO_ALIAS(X509_REQ_set_version); - -long -X509_REQ_get_version(const X509_REQ *x) -{ - return ASN1_INTEGER_get(x->req_info->version); -} -LCRYPTO_ALIAS(X509_REQ_get_version); - -int -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); -} -LCRYPTO_ALIAS(X509_REQ_set_subject_name); - -X509_NAME * -X509_REQ_get_subject_name(const X509_REQ *x) -{ - return x->req_info->subject; -} -LCRYPTO_ALIAS(X509_REQ_get_subject_name); - -int -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); -} -LCRYPTO_ALIAS(X509_REQ_set_pubkey); diff --git a/src/lib/libcrypto/x509/x509spki.c b/src/lib/libcrypto/x509/x509spki.c deleted file mode 100644 index 04c9a6f01b..0000000000 --- a/src/lib/libcrypto/x509/x509spki.c +++ /dev/null @@ -1,136 +0,0 @@ -/* $OpenBSD: x509spki.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include - -#include -#include - -int -NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->spkac == NULL)) - return (0); - return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); -} -LCRYPTO_ALIAS(NETSCAPE_SPKI_set_pubkey); - -EVP_PKEY * -NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) -{ - if ((x == NULL) || (x->spkac == NULL)) - return (NULL); - return (X509_PUBKEY_get(x->spkac->pubkey)); -} -LCRYPTO_ALIAS(NETSCAPE_SPKI_get_pubkey); - -/* Load a Netscape SPKI from a base64 encoded string */ - -NETSCAPE_SPKI * -NETSCAPE_SPKI_b64_decode(const char *str, int len) -{ - unsigned char *spki_der; - const unsigned char *p; - int spki_len; - NETSCAPE_SPKI *spki; - - if (len <= 0) - len = strlen(str); - if (!(spki_der = malloc(len + 1))) { - X509error(ERR_R_MALLOC_FAILURE); - return NULL; - } - spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); - if (spki_len < 0) { - X509error(X509_R_BASE64_DECODE_ERROR); - free(spki_der); - return NULL; - } - p = spki_der; - spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); - free(spki_der); - return spki; -} -LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_decode); - -/* Generate a base64 encoded string from an SPKI */ - -char * -NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) -{ - unsigned char *der_spki, *p; - char *b64_str; - int der_len; - der_len = i2d_NETSCAPE_SPKI(spki, NULL); - der_spki = malloc(der_len); - b64_str = reallocarray(NULL, der_len, 2); - if (!der_spki || !b64_str) { - X509error(ERR_R_MALLOC_FAILURE); - free(der_spki); - free(b64_str); - return NULL; - } - p = der_spki; - i2d_NETSCAPE_SPKI(spki, &p); - EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); - free(der_spki); - return b64_str; -} -LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_encode); diff --git a/src/lib/libcrypto/x509/x509type.c b/src/lib/libcrypto/x509/x509type.c deleted file mode 100644 index 1698d8a0ab..0000000000 --- a/src/lib/libcrypto/x509/x509type.c +++ /dev/null @@ -1,136 +0,0 @@ -/* $OpenBSD: x509type.c,v 1.24 2023/11/13 16:16:14 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include - -#include "evp_local.h" -#include "x509_local.h" - -int -X509_certificate_type(const X509 *x, const EVP_PKEY *pkey) -{ - const EVP_PKEY *pk = pkey; - int nid; - int ret = 0; - - if (x == NULL) - goto done; - - if (pk == NULL) - pk = X509_get0_pubkey(x); - if (pk == NULL) - goto done; - - switch (pk->type) { - case EVP_PKEY_RSA: - ret = EVP_PK_RSA|EVP_PKT_SIGN|EVP_PKT_ENC; - break; - case EVP_PKEY_RSA_PSS: - ret = EVP_PK_RSA|EVP_PKT_SIGN; - break; - case EVP_PKEY_DSA: - ret = EVP_PK_DSA|EVP_PKT_SIGN; - break; - case EVP_PKEY_EC: - ret = EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH; - break; - case EVP_PKEY_ED25519: - ret = EVP_PKT_SIGN; - break; - case EVP_PKEY_DH: - ret = EVP_PK_DH|EVP_PKT_EXCH; - break; - case NID_id_GostR3410_94: - case NID_id_GostR3410_2001: - ret = EVP_PKT_EXCH|EVP_PKT_SIGN; - break; - default: - break; - } - - if ((nid = X509_get_signature_nid(x)) == NID_undef) - goto done; - - if (!OBJ_find_sigid_algs(nid, NULL, &nid)) - goto done; - - switch (nid) { - case NID_rsaEncryption: - case NID_rsa: - ret |= EVP_PKS_RSA; - break; - case NID_dsa: - case NID_dsa_2: - ret |= EVP_PKS_DSA; - break; - case NID_X9_62_id_ecPublicKey: - ret |= EVP_PKS_EC; - break; - default: - break; - } - - done: - - return ret; -} -LCRYPTO_ALIAS(X509_certificate_type); diff --git a/src/lib/libcrypto/x509/x509v3.h b/src/lib/libcrypto/x509/x509v3.h deleted file mode 100644 index fa31279280..0000000000 --- a/src/lib/libcrypto/x509/x509v3.h +++ /dev/null @@ -1,1041 +0,0 @@ -/* $OpenBSD: x509v3.h,v 1.40 2024/12/23 09:57:23 tb Exp $ */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef HEADER_X509V3_H -#define HEADER_X509V3_H - -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Forward reference */ -struct v3_ext_method; -struct v3_ext_ctx; - -/* Useful typedefs */ - -typedef void * (*X509V3_EXT_NEW)(void); -typedef void (*X509V3_EXT_FREE)(void *); -typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long); -typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); -typedef STACK_OF(CONF_VALUE) * - (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext, - STACK_OF(CONF_VALUE) *extlist); -typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE) *values); -typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext); -typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, const char *str); -typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext, - BIO *out, int indent); -typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, const char *str); - -/* V3 extension structure */ - -struct v3_ext_method { - int ext_nid; - int ext_flags; - /* If this is set the following four fields are ignored */ - ASN1_ITEM_EXP *it; - /* Old style ASN1 calls */ - X509V3_EXT_NEW ext_new; - X509V3_EXT_FREE ext_free; - X509V3_EXT_D2I d2i; - X509V3_EXT_I2D i2d; - - /* The following pair is used for string extensions */ - X509V3_EXT_I2S i2s; - X509V3_EXT_S2I s2i; - - /* The following pair is used for multi-valued extensions */ - X509V3_EXT_I2V i2v; - X509V3_EXT_V2I v2i; - - /* The following are used for raw extensions */ - X509V3_EXT_I2R i2r; - X509V3_EXT_R2I r2i; - - const void *usr_data; /* Any extension specific data */ -}; - -struct v3_ext_ctx { - #define CTX_TEST 0x1 - int flags; - X509 *issuer_cert; - X509 *subject_cert; - X509_REQ *subject_req; - X509_CRL *crl; - void *db; -}; - -typedef struct v3_ext_method X509V3_EXT_METHOD; - -DECLARE_STACK_OF(X509V3_EXT_METHOD) - -/* XXX - can this be made internal? */ -#define X509V3_EXT_MULTILINE 0x4 - -/* XXX - remove it anyway? */ -/* Guess who uses this... Yes, of course, it's xca. */ -typedef BIT_STRING_BITNAME ENUMERATED_NAMES; - -typedef struct BASIC_CONSTRAINTS_st { - int ca; - ASN1_INTEGER *pathlen; -} BASIC_CONSTRAINTS; - - -typedef struct PKEY_USAGE_PERIOD_st { - ASN1_GENERALIZEDTIME *notBefore; - ASN1_GENERALIZEDTIME *notAfter; -} PKEY_USAGE_PERIOD; - -typedef struct otherName_st { - ASN1_OBJECT *type_id; - ASN1_TYPE *value; -} OTHERNAME; - -typedef struct EDIPartyName_st { - ASN1_STRING *nameAssigner; - ASN1_STRING *partyName; -} EDIPARTYNAME; - -typedef struct GENERAL_NAME_st { - - #define GEN_OTHERNAME 0 - #define GEN_EMAIL 1 - #define GEN_DNS 2 - #define GEN_X400 3 - #define GEN_DIRNAME 4 - #define GEN_EDIPARTY 5 - #define GEN_URI 6 - #define GEN_IPADD 7 - #define GEN_RID 8 - - int type; - union { - char *ptr; - OTHERNAME *otherName; /* otherName */ - ASN1_IA5STRING *rfc822Name; - ASN1_IA5STRING *dNSName; - ASN1_STRING *x400Address; - X509_NAME *directoryName; - EDIPARTYNAME *ediPartyName; - ASN1_IA5STRING *uniformResourceIdentifier; - ASN1_OCTET_STRING *iPAddress; - ASN1_OBJECT *registeredID; - - /* Old names */ - ASN1_OCTET_STRING *ip; /* iPAddress */ - X509_NAME *dirn; /* dirn */ - ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, uniformResourceIdentifier */ - ASN1_OBJECT *rid; /* registeredID */ - } d; -} GENERAL_NAME; - -typedef struct ACCESS_DESCRIPTION_st { - ASN1_OBJECT *method; - GENERAL_NAME *location; -} ACCESS_DESCRIPTION; - -typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; - -typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; - -DECLARE_STACK_OF(GENERAL_NAME) - -typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; -DECLARE_STACK_OF(GENERAL_NAMES) - -DECLARE_STACK_OF(ACCESS_DESCRIPTION) - -typedef struct DIST_POINT_NAME_st { - int type; - union { - GENERAL_NAMES *fullname; - STACK_OF(X509_NAME_ENTRY) *relativename; - } name; - /* If relativename then this contains the full distribution point name */ - X509_NAME *dpname; -} DIST_POINT_NAME; -/* All existing reasons */ -#define CRLDP_ALL_REASONS 0x807f - -#define CRL_REASON_NONE -1 -#define CRL_REASON_UNSPECIFIED 0 -#define CRL_REASON_KEY_COMPROMISE 1 -#define CRL_REASON_CA_COMPROMISE 2 -#define CRL_REASON_AFFILIATION_CHANGED 3 -#define CRL_REASON_SUPERSEDED 4 -#define CRL_REASON_CESSATION_OF_OPERATION 5 -#define CRL_REASON_CERTIFICATE_HOLD 6 -#define CRL_REASON_REMOVE_FROM_CRL 8 -#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 -#define CRL_REASON_AA_COMPROMISE 10 - -struct DIST_POINT_st { - DIST_POINT_NAME *distpoint; - ASN1_BIT_STRING *reasons; - GENERAL_NAMES *CRLissuer; - int dp_reasons; -}; - -typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; - -DECLARE_STACK_OF(DIST_POINT) - -struct AUTHORITY_KEYID_st { - ASN1_OCTET_STRING *keyid; - GENERAL_NAMES *issuer; - ASN1_INTEGER *serial; -}; - -typedef struct NOTICEREF_st { - ASN1_STRING *organization; - STACK_OF(ASN1_INTEGER) *noticenos; -} NOTICEREF; - -typedef struct USERNOTICE_st { - NOTICEREF *noticeref; - ASN1_STRING *exptext; -} USERNOTICE; - -typedef struct POLICYQUALINFO_st { - ASN1_OBJECT *pqualid; - union { - ASN1_IA5STRING *cpsuri; - USERNOTICE *usernotice; - ASN1_TYPE *other; - } d; -} POLICYQUALINFO; - -DECLARE_STACK_OF(POLICYQUALINFO) - -typedef struct POLICYINFO_st { - ASN1_OBJECT *policyid; - STACK_OF(POLICYQUALINFO) *qualifiers; -} POLICYINFO; - -typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; - -DECLARE_STACK_OF(POLICYINFO) - -typedef struct POLICY_MAPPING_st { - ASN1_OBJECT *issuerDomainPolicy; - ASN1_OBJECT *subjectDomainPolicy; -} POLICY_MAPPING; - -DECLARE_STACK_OF(POLICY_MAPPING) - -typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; - -typedef struct GENERAL_SUBTREE_st { - GENERAL_NAME *base; - ASN1_INTEGER *minimum; - ASN1_INTEGER *maximum; -} GENERAL_SUBTREE; - -DECLARE_STACK_OF(GENERAL_SUBTREE) - -struct NAME_CONSTRAINTS_st { - STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; - STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; -}; - -typedef struct POLICY_CONSTRAINTS_st { - ASN1_INTEGER *requireExplicitPolicy; - ASN1_INTEGER *inhibitPolicyMapping; -} POLICY_CONSTRAINTS; - -struct ISSUING_DIST_POINT_st { - DIST_POINT_NAME *distpoint; - int onlyuser; - int onlyCA; - ASN1_BIT_STRING *onlysomereasons; - int indirectCRL; - int onlyattr; -}; - -/* Values in idp_flags field */ -/* IDP present */ -#define IDP_PRESENT 0x1 -/* IDP values inconsistent */ -#define IDP_INVALID 0x2 -/* onlyuser true */ -#define IDP_ONLYUSER 0x4 -/* onlyCA true */ -#define IDP_ONLYCA 0x8 -/* onlyattr true */ -#define IDP_ONLYATTR 0x10 -/* indirectCRL true */ -#define IDP_INDIRECT 0x20 -/* onlysomereasons present */ -#define IDP_REASONS 0x40 - -#define X509V3_conf_err(val) ERR_asprintf_error_data( \ - "section:%s,name:%s,value:%s", val->section, \ - val->name, val->value); - -#define X509V3_set_ctx_test(ctx) \ - X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) -#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; - -/* X509_PURPOSE stuff */ - -#define EXFLAG_BCONS 0x0001 -#define EXFLAG_KUSAGE 0x0002 -#define EXFLAG_XKUSAGE 0x0004 -#define EXFLAG_NSCERT 0x0008 - -#define EXFLAG_CA 0x0010 -#define EXFLAG_SI 0x0020 /* Self issued. */ -#define EXFLAG_V1 0x0040 -#define EXFLAG_INVALID 0x0080 -#define EXFLAG_SET 0x0100 -#define EXFLAG_CRITICAL 0x0200 -#if !defined(LIBRESSL_INTERNAL) -#define EXFLAG_PROXY 0x0400 -#endif -#define EXFLAG_INVALID_POLICY 0x0800 -#define EXFLAG_FRESHEST 0x1000 -#define EXFLAG_SS 0x2000 /* Self signed. */ - -#define KU_DIGITAL_SIGNATURE 0x0080 -#define KU_NON_REPUDIATION 0x0040 -#define KU_KEY_ENCIPHERMENT 0x0020 -#define KU_DATA_ENCIPHERMENT 0x0010 -#define KU_KEY_AGREEMENT 0x0008 -#define KU_KEY_CERT_SIGN 0x0004 -#define KU_CRL_SIGN 0x0002 -#define KU_ENCIPHER_ONLY 0x0001 -#define KU_DECIPHER_ONLY 0x8000 - -#define NS_SSL_CLIENT 0x80 -#define NS_SSL_SERVER 0x40 -#define NS_SMIME 0x20 -#define NS_OBJSIGN 0x10 -#define NS_SSL_CA 0x04 -#define NS_SMIME_CA 0x02 -#define NS_OBJSIGN_CA 0x01 -#define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) - -#define XKU_SSL_SERVER 0x1 -#define XKU_SSL_CLIENT 0x2 -#define XKU_SMIME 0x4 -#define XKU_CODE_SIGN 0x8 -#define XKU_SGC 0x10 -#define XKU_OCSP_SIGN 0x20 -#define XKU_TIMESTAMP 0x40 -#define XKU_DVCS 0x80 -#define XKU_ANYEKU 0x100 - -#define X509_PURPOSE_DYNAMIC 0x1 -#define X509_PURPOSE_DYNAMIC_NAME 0x2 - -typedef struct x509_purpose_st X509_PURPOSE; - -#define X509_PURPOSE_SSL_CLIENT 1 -#define X509_PURPOSE_SSL_SERVER 2 -#define X509_PURPOSE_NS_SSL_SERVER 3 -#define X509_PURPOSE_SMIME_SIGN 4 -#define X509_PURPOSE_SMIME_ENCRYPT 5 -#define X509_PURPOSE_CRL_SIGN 6 -#define X509_PURPOSE_ANY 7 -#define X509_PURPOSE_OCSP_HELPER 8 -#define X509_PURPOSE_TIMESTAMP_SIGN 9 - -#define X509_PURPOSE_MIN 1 -#define X509_PURPOSE_MAX 9 - -/* Flags for X509V3_EXT_print() */ - -#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) -/* Return error for unknown extensions */ -#define X509V3_EXT_DEFAULT 0 -/* Print error for unknown extensions */ -#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) -/* ASN1 parse unknown extensions */ -#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) -/* BIO_dump unknown extensions */ -#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) - -/* Flags for X509V3_add1_i2d */ - -#define X509V3_ADD_OP_MASK 0xfL -#define X509V3_ADD_DEFAULT 0L -#define X509V3_ADD_APPEND 1L -#define X509V3_ADD_REPLACE 2L -#define X509V3_ADD_REPLACE_EXISTING 3L -#define X509V3_ADD_KEEP_EXISTING 4L -#define X509V3_ADD_DELETE 5L -#define X509V3_ADD_SILENT 0x10 - -DECLARE_STACK_OF(X509_PURPOSE) - -BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void); -void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a); -BASIC_CONSTRAINTS *d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len); -int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out); -extern const ASN1_ITEM BASIC_CONSTRAINTS_it; - -AUTHORITY_KEYID *AUTHORITY_KEYID_new(void); -void AUTHORITY_KEYID_free(AUTHORITY_KEYID *a); -AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len); -int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out); -extern const ASN1_ITEM AUTHORITY_KEYID_it; - -PKEY_USAGE_PERIOD *PKEY_USAGE_PERIOD_new(void); -void PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a); -PKEY_USAGE_PERIOD *d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len); -int i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out); -extern const ASN1_ITEM PKEY_USAGE_PERIOD_it; - -GENERAL_NAME *GENERAL_NAME_new(void); -void GENERAL_NAME_free(GENERAL_NAME *a); -GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len); -int i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out); -extern const ASN1_ITEM GENERAL_NAME_it; -GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); -int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); - - - -ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - ASN1_BIT_STRING *bits, - STACK_OF(CONF_VALUE) *extlist); - -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); -int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); - -GENERAL_NAMES *GENERAL_NAMES_new(void); -void GENERAL_NAMES_free(GENERAL_NAMES *a); -GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len); -int i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out); -extern const ASN1_ITEM GENERAL_NAMES_it; - -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, - GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); -GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); - -OTHERNAME *OTHERNAME_new(void); -void OTHERNAME_free(OTHERNAME *a); -OTHERNAME *d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len); -int i2d_OTHERNAME(OTHERNAME *a, unsigned char **out); -extern const ASN1_ITEM OTHERNAME_it; -EDIPARTYNAME *EDIPARTYNAME_new(void); -void EDIPARTYNAME_free(EDIPARTYNAME *a); -EDIPARTYNAME *d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len); -int i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out); -extern const ASN1_ITEM EDIPARTYNAME_it; -int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); -void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); -void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); -int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, - ASN1_OBJECT *oid, ASN1_TYPE *value); -int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, - ASN1_OBJECT **poid, ASN1_TYPE **pvalue); - -char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - const ASN1_OCTET_STRING *ia5); -ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str); - -EXTENDED_KEY_USAGE *EXTENDED_KEY_USAGE_new(void); -void EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a); -EXTENDED_KEY_USAGE *d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len); -int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out); -extern const ASN1_ITEM EXTENDED_KEY_USAGE_it; -int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a); - -CERTIFICATEPOLICIES *CERTIFICATEPOLICIES_new(void); -void CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a); -CERTIFICATEPOLICIES *d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len); -int i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out); -extern const ASN1_ITEM CERTIFICATEPOLICIES_it; -POLICYINFO *POLICYINFO_new(void); -void POLICYINFO_free(POLICYINFO *a); -POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len); -int i2d_POLICYINFO(POLICYINFO *a, unsigned char **out); -extern const ASN1_ITEM POLICYINFO_it; -POLICYQUALINFO *POLICYQUALINFO_new(void); -void POLICYQUALINFO_free(POLICYQUALINFO *a); -POLICYQUALINFO *d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len); -int i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out); -extern const ASN1_ITEM POLICYQUALINFO_it; -USERNOTICE *USERNOTICE_new(void); -void USERNOTICE_free(USERNOTICE *a); -USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len); -int i2d_USERNOTICE(USERNOTICE *a, unsigned char **out); -extern const ASN1_ITEM USERNOTICE_it; -NOTICEREF *NOTICEREF_new(void); -void NOTICEREF_free(NOTICEREF *a); -NOTICEREF *d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len); -int i2d_NOTICEREF(NOTICEREF *a, unsigned char **out); -extern const ASN1_ITEM NOTICEREF_it; - -CRL_DIST_POINTS *CRL_DIST_POINTS_new(void); -void CRL_DIST_POINTS_free(CRL_DIST_POINTS *a); -CRL_DIST_POINTS *d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len); -int i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out); -extern const ASN1_ITEM CRL_DIST_POINTS_it; -DIST_POINT *DIST_POINT_new(void); -void DIST_POINT_free(DIST_POINT *a); -DIST_POINT *d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len); -int i2d_DIST_POINT(DIST_POINT *a, unsigned char **out); -extern const ASN1_ITEM DIST_POINT_it; -DIST_POINT_NAME *DIST_POINT_NAME_new(void); -void DIST_POINT_NAME_free(DIST_POINT_NAME *a); -DIST_POINT_NAME *d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len); -int i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out); -extern const ASN1_ITEM DIST_POINT_NAME_it; -ISSUING_DIST_POINT *ISSUING_DIST_POINT_new(void); -void ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a); -ISSUING_DIST_POINT *d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len); -int i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out); -extern const ASN1_ITEM ISSUING_DIST_POINT_it; - -int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); - -int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); - -ACCESS_DESCRIPTION *ACCESS_DESCRIPTION_new(void); -void ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a); -ACCESS_DESCRIPTION *d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len); -int i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out); -extern const ASN1_ITEM ACCESS_DESCRIPTION_it; -AUTHORITY_INFO_ACCESS *AUTHORITY_INFO_ACCESS_new(void); -void AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a); -AUTHORITY_INFO_ACCESS *d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len); -int i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out); -extern const ASN1_ITEM AUTHORITY_INFO_ACCESS_it; - -extern const ASN1_ITEM POLICY_MAPPING_it; -POLICY_MAPPING *POLICY_MAPPING_new(void); -void POLICY_MAPPING_free(POLICY_MAPPING *a); -extern const ASN1_ITEM POLICY_MAPPINGS_it; - -extern const ASN1_ITEM GENERAL_SUBTREE_it; -GENERAL_SUBTREE *GENERAL_SUBTREE_new(void); -void GENERAL_SUBTREE_free(GENERAL_SUBTREE *a); - -extern const ASN1_ITEM NAME_CONSTRAINTS_it; -NAME_CONSTRAINTS *NAME_CONSTRAINTS_new(void); -void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a); - -POLICY_CONSTRAINTS *POLICY_CONSTRAINTS_new(void); -void POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a); -extern const ASN1_ITEM POLICY_CONSTRAINTS_it; - -GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - int gen_type, const char *value, int is_nc); - -#ifdef HEADER_CONF_H -GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf); -GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); -void X509V3_conf_free(CONF_VALUE *val); - -X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, - const char *value); -X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, - const char *value); -int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, - STACK_OF(X509_EXTENSION) **sk); -int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509 *cert); -int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_REQ *req); -int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_CRL *crl); - -X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - int ext_nid, const char *value); -X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - const char *name, const char *value); - -void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); -#endif - -void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, - X509_REQ *req, X509_CRL *crl, int flags); - -char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); -ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value); -char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); -char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, - const ASN1_ENUMERATED *aint); - -const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); -const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); -int X509V3_add_standard_extensions(void); -STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); -void *X509V3_EXT_d2i(X509_EXTENSION *ext); -void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, - int *idx); - -X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); -int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); - -char *hex_to_string(const unsigned char *buffer, long len); -unsigned char *string_to_hex(const char *str, long *len); - -void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, - int ml); -int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent); -int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); - -int X509V3_extensions_print(BIO *out, const char *title, - const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent); - -int X509_check_ca(X509 *x); -int X509_check_purpose(X509 *x, int id, int ca); -int X509_supported_extension(X509_EXTENSION *ex); -int X509_check_issued(X509 *issuer, X509 *subject); -int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); - -int X509_PURPOSE_get_count(void); -const X509_PURPOSE *X509_PURPOSE_get0(int idx); -int X509_PURPOSE_get_by_sname(const char *sname); -const char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); -const char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); -int X509_PURPOSE_get_id(const X509_PURPOSE *); -uint32_t X509_get_extension_flags(X509 *x); -uint32_t X509_get_key_usage(X509 *x); -uint32_t X509_get_extended_key_usage(X509 *x); - -STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); -STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); -void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); -STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); - -/* Flags for X509_check_* functions */ -/* Always check subject name for host match even if subject alt names present */ -#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 -/* Disable wildcard matching for dnsName fields and common name. */ -#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 -/* Wildcards must not match a partial label. */ -#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 -/* Allow (non-partial) wildcards to match multiple labels. */ -#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 -/* Constraint verifier subdomain patterns to match a single labels. */ -#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 -/* Disable checking the CN for a hostname, to support modern validation */ -#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 - -int X509_check_host(X509 *x, const char *chk, size_t chklen, - unsigned int flags, char **peername); -int X509_check_email(X509 *x, const char *chk, size_t chklen, - unsigned int flags); -int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags); -int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); - -ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); -ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); -int a2i_ipadd(unsigned char *ipout, const char *ipasc); -int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, - unsigned long chtype); - -#ifndef OPENSSL_NO_RFC3779 -typedef struct ASRange_st { - ASN1_INTEGER *min; - ASN1_INTEGER *max; -} ASRange; - -#define ASIdOrRange_id 0 -#define ASIdOrRange_range 1 - -typedef struct ASIdOrRange_st { - int type; - union { - ASN1_INTEGER *id; - ASRange *range; - } u; -} ASIdOrRange; - -typedef STACK_OF(ASIdOrRange) ASIdOrRanges; -DECLARE_STACK_OF(ASIdOrRange) - -#define ASIdentifierChoice_inherit 0 -#define ASIdentifierChoice_asIdsOrRanges 1 - -typedef struct ASIdentifierChoice_st { - int type; - union { - ASN1_NULL *inherit; - ASIdOrRanges *asIdsOrRanges; - } u; -} ASIdentifierChoice; - -typedef struct ASIdentifiers_st { - ASIdentifierChoice *asnum; - ASIdentifierChoice *rdi; -} ASIdentifiers; - -ASRange *ASRange_new(void); -void ASRange_free(ASRange *a); -ASRange *d2i_ASRange(ASRange **a, const unsigned char **in, long len); -int i2d_ASRange(ASRange *a, unsigned char **out); -extern const ASN1_ITEM ASRange_it; - -ASIdOrRange *ASIdOrRange_new(void); -void ASIdOrRange_free(ASIdOrRange *a); -ASIdOrRange *d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, - long len); -int i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out); -extern const ASN1_ITEM ASIdOrRange_it; - -ASIdentifierChoice *ASIdentifierChoice_new(void); -void ASIdentifierChoice_free(ASIdentifierChoice *a); -ASIdentifierChoice *d2i_ASIdentifierChoice(ASIdentifierChoice **a, - const unsigned char **in, long len); -int i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out); -extern const ASN1_ITEM ASIdentifierChoice_it; - -ASIdentifiers *ASIdentifiers_new(void); -void ASIdentifiers_free(ASIdentifiers *a); -ASIdentifiers *d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, - long len); -int i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out); -extern const ASN1_ITEM ASIdentifiers_it; - -typedef struct IPAddressRange_st { - ASN1_BIT_STRING *min; - ASN1_BIT_STRING *max; -} IPAddressRange; - -#define IPAddressOrRange_addressPrefix 0 -#define IPAddressOrRange_addressRange 1 - -typedef struct IPAddressOrRange_st { - int type; - union { - ASN1_BIT_STRING *addressPrefix; - IPAddressRange *addressRange; - } u; -} IPAddressOrRange; - -typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; -DECLARE_STACK_OF(IPAddressOrRange) - -#define IPAddressChoice_inherit 0 -#define IPAddressChoice_addressesOrRanges 1 - -typedef struct IPAddressChoice_st { - int type; - union { - ASN1_NULL *inherit; - IPAddressOrRanges *addressesOrRanges; - } u; -} IPAddressChoice; - -typedef struct IPAddressFamily_st { - ASN1_OCTET_STRING *addressFamily; - IPAddressChoice *ipAddressChoice; -} IPAddressFamily; - -typedef STACK_OF(IPAddressFamily) IPAddrBlocks; -DECLARE_STACK_OF(IPAddressFamily) - -IPAddressRange *IPAddressRange_new(void); -void IPAddressRange_free(IPAddressRange *a); -IPAddressRange *d2i_IPAddressRange(IPAddressRange **a, - const unsigned char **in, long len); -int i2d_IPAddressRange(IPAddressRange *a, unsigned char **out); -extern const ASN1_ITEM IPAddressRange_it; - -IPAddressOrRange *IPAddressOrRange_new(void); -void IPAddressOrRange_free(IPAddressOrRange *a); -IPAddressOrRange *d2i_IPAddressOrRange(IPAddressOrRange **a, - const unsigned char **in, long len); -int i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out); -extern const ASN1_ITEM IPAddressOrRange_it; - -IPAddressChoice *IPAddressChoice_new(void); -void IPAddressChoice_free(IPAddressChoice *a); -IPAddressChoice *d2i_IPAddressChoice(IPAddressChoice **a, - const unsigned char **in, long len); -int i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out); -extern const ASN1_ITEM IPAddressChoice_it; - -IPAddressFamily *IPAddressFamily_new(void); -void IPAddressFamily_free(IPAddressFamily *a); -IPAddressFamily *d2i_IPAddressFamily(IPAddressFamily **a, - const unsigned char **in, long len); -int i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out); -extern const ASN1_ITEM IPAddressFamily_it; - -/* - * API tag for elements of the ASIdentifer SEQUENCE. - */ -#define V3_ASID_ASNUM 0 -#define V3_ASID_RDI 1 - -/* - * AFI values, assigned by IANA. It'd be nice to make the AFI - * handling code totally generic, but there are too many little things - * that would need to be defined for other address families for it to - * be worth the trouble. - */ -#define IANA_AFI_IPV4 1 -#define IANA_AFI_IPV6 2 - -/* - * Utilities to construct and extract values from RFC3779 extensions, - * since some of the encodings (particularly for IP address prefixes - * and ranges) are a bit tedious to work with directly. - */ -int X509v3_asid_add_inherit(ASIdentifiers *asid, int which); -int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, - ASN1_INTEGER *min, ASN1_INTEGER *max); -int X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi); -int X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi, unsigned char *a, const int prefixlen); -int X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi, - const unsigned *safi, unsigned char *min, unsigned char *max); -unsigned X509v3_addr_get_afi(const IPAddressFamily *f); -int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, - unsigned char *min, unsigned char *max, const int length); - -/* - * Canonical forms. - */ -int X509v3_asid_is_canonical(ASIdentifiers *asid); -int X509v3_addr_is_canonical(IPAddrBlocks *addr); -int X509v3_asid_canonize(ASIdentifiers *asid); -int X509v3_addr_canonize(IPAddrBlocks *addr); - -/* - * Tests for inheritance and containment. - */ -int X509v3_asid_inherits(ASIdentifiers *asid); -int X509v3_addr_inherits(IPAddrBlocks *addr); -int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); -int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); - -/* - * Check whether RFC 3779 extensions nest properly in chains. - */ -int X509v3_asid_validate_path(X509_STORE_CTX *); -int X509v3_addr_validate_path(X509_STORE_CTX *); -int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, - int allow_inheritance); -int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext, - int allow_inheritance); - -#endif /* !OPENSSL_NO_RFC3779 */ - -void ERR_load_X509V3_strings(void); - -/* Error codes for the X509V3 functions. */ - -/* Function codes. */ -#define X509V3_F_A2I_GENERAL_NAME 164 -#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 -#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 -#define X509V3_F_COPY_EMAIL 122 -#define X509V3_F_COPY_ISSUER 123 -#define X509V3_F_DO_DIRNAME 144 -#define X509V3_F_DO_EXT_CONF 124 -#define X509V3_F_DO_EXT_I2D 135 -#define X509V3_F_DO_EXT_NCONF 151 -#define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 -#define X509V3_F_GNAMES_FROM_SECTNAME 156 -#define X509V3_F_HEX_TO_STRING 111 -#define X509V3_F_I2S_ASN1_ENUMERATED 121 -#define X509V3_F_I2S_ASN1_IA5STRING 149 -#define X509V3_F_I2S_ASN1_INTEGER 120 -#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 -#define X509V3_F_NOTICE_SECTION 132 -#define X509V3_F_NREF_NOS 133 -#define X509V3_F_POLICY_SECTION 131 -#define X509V3_F_PROCESS_PCI_VALUE 150 -#define X509V3_F_R2I_CERTPOL 130 -#define X509V3_F_R2I_PCI 155 -#define X509V3_F_S2I_ASN1_IA5STRING 100 -#define X509V3_F_S2I_ASN1_INTEGER 108 -#define X509V3_F_S2I_ASN1_OCTET_STRING 112 -#define X509V3_F_S2I_ASN1_SKEY_ID 114 -#define X509V3_F_S2I_SKEY_ID 115 -#define X509V3_F_SET_DIST_POINT_NAME 158 -#define X509V3_F_STRING_TO_HEX 113 -#define X509V3_F_SXNET_ADD_ID_ASC 125 -#define X509V3_F_SXNET_ADD_ID_INTEGER 126 -#define X509V3_F_SXNET_ADD_ID_ULONG 127 -#define X509V3_F_SXNET_GET_ID_ASC 128 -#define X509V3_F_SXNET_GET_ID_ULONG 129 -#define X509V3_F_V2I_ASIDENTIFIERS 163 -#define X509V3_F_V2I_ASN1_BIT_STRING 101 -#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 -#define X509V3_F_V2I_AUTHORITY_KEYID 119 -#define X509V3_F_V2I_BASIC_CONSTRAINTS 102 -#define X509V3_F_V2I_CRLD 134 -#define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 -#define X509V3_F_V2I_GENERAL_NAMES 118 -#define X509V3_F_V2I_GENERAL_NAME_EX 117 -#define X509V3_F_V2I_IDP 157 -#define X509V3_F_V2I_IPADDRBLOCKS 159 -#define X509V3_F_V2I_ISSUER_ALT 153 -#define X509V3_F_V2I_NAME_CONSTRAINTS 147 -#define X509V3_F_V2I_POLICY_CONSTRAINTS 146 -#define X509V3_F_V2I_POLICY_MAPPINGS 145 -#define X509V3_F_V2I_SUBJECT_ALT 154 -#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 -#define X509V3_F_V3_GENERIC_EXTENSION 116 -#define X509V3_F_X509V3_ADD1_I2D 140 -#define X509V3_F_X509V3_ADD_VALUE 105 -#define X509V3_F_X509V3_EXT_ADD 104 -#define X509V3_F_X509V3_EXT_ADD_ALIAS 106 -#define X509V3_F_X509V3_EXT_CONF 107 -#define X509V3_F_X509V3_EXT_I2D 136 -#define X509V3_F_X509V3_EXT_NCONF 152 -#define X509V3_F_X509V3_GET_SECTION 142 -#define X509V3_F_X509V3_GET_STRING 143 -#define X509V3_F_X509V3_GET_VALUE_BOOL 110 -#define X509V3_F_X509V3_PARSE_LIST 109 -#define X509V3_F_X509_PURPOSE_ADD 137 -#define X509V3_F_X509_PURPOSE_SET 141 - -/* Reason codes. */ -#define X509V3_R_BAD_IP_ADDRESS 118 -#define X509V3_R_BAD_OBJECT 119 -#define X509V3_R_BN_DEC2BN_ERROR 100 -#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 -#define X509V3_R_DIRNAME_ERROR 149 -#define X509V3_R_DISTPOINT_ALREADY_SET 160 -#define X509V3_R_DUPLICATE_ZONE_ID 133 -#define X509V3_R_ERROR_CONVERTING_ZONE 131 -#define X509V3_R_ERROR_CREATING_EXTENSION 144 -#define X509V3_R_ERROR_IN_EXTENSION 128 -#define X509V3_R_EXPECTED_A_SECTION_NAME 137 -#define X509V3_R_EXTENSION_EXISTS 145 -#define X509V3_R_EXTENSION_NAME_ERROR 115 -#define X509V3_R_EXTENSION_NOT_FOUND 102 -#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 -#define X509V3_R_EXTENSION_VALUE_ERROR 116 -#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 -#define X509V3_R_ILLEGAL_HEX_DIGIT 113 -#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 -#define X509V3_R_INVALID_MULTIPLE_RDNS 161 -#define X509V3_R_INVALID_ASNUMBER 162 -#define X509V3_R_INVALID_ASRANGE 163 -#define X509V3_R_INVALID_BOOLEAN_STRING 104 -#define X509V3_R_INVALID_EXTENSION_STRING 105 -#define X509V3_R_INVALID_INHERITANCE 165 -#define X509V3_R_INVALID_IPADDRESS 166 -#define X509V3_R_INVALID_NAME 106 -#define X509V3_R_INVALID_NULL_ARGUMENT 107 -#define X509V3_R_INVALID_NULL_NAME 108 -#define X509V3_R_INVALID_NULL_VALUE 109 -#define X509V3_R_INVALID_NUMBER 140 -#define X509V3_R_INVALID_NUMBERS 141 -#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 -#define X509V3_R_INVALID_OPTION 138 -#define X509V3_R_INVALID_POLICY_IDENTIFIER 134 -#define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 -#define X509V3_R_INVALID_PURPOSE 146 -#define X509V3_R_INVALID_SAFI 164 -#define X509V3_R_INVALID_SECTION 135 -#define X509V3_R_INVALID_SYNTAX 143 -#define X509V3_R_ISSUER_DECODE_ERROR 126 -#define X509V3_R_MISSING_VALUE 124 -#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 -#define X509V3_R_NO_CONFIG_DATABASE 136 -#define X509V3_R_NO_ISSUER_CERTIFICATE 121 -#define X509V3_R_NO_ISSUER_DETAILS 127 -#define X509V3_R_NO_POLICY_IDENTIFIER 139 -#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 -#define X509V3_R_NO_PUBLIC_KEY 114 -#define X509V3_R_NO_SUBJECT_DETAILS 125 -#define X509V3_R_ODD_NUMBER_OF_DIGITS 112 -#define X509V3_R_OPERATION_NOT_DEFINED 148 -#define X509V3_R_OTHERNAME_ERROR 147 -#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 -#define X509V3_R_POLICY_PATH_LENGTH 156 -#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 -#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 -#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 -#define X509V3_R_SECTION_NOT_FOUND 150 -#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 -#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 -#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 -#define X509V3_R_UNKNOWN_EXTENSION 129 -#define X509V3_R_UNKNOWN_EXTENSION_NAME 130 -#define X509V3_R_UNKNOWN_OPTION 120 -#define X509V3_R_UNSUPPORTED_OPTION 117 -#define X509V3_R_UNSUPPORTED_TYPE 167 -#define X509V3_R_USER_TOO_LONG 132 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/lib/libcrypto/x509/x_all.c b/src/lib/libcrypto/x509/x_all.c deleted file mode 100644 index 5997714061..0000000000 --- a/src/lib/libcrypto/x509/x_all.c +++ /dev/null @@ -1,536 +0,0 @@ -/* $OpenBSD: x_all.c,v 1.32 2024/06/19 08:00:53 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#ifndef OPENSSL_NO_DSA -#include -#endif -#ifndef OPENSSL_NO_RSA -#include -#endif - -#include "x509_local.h" - -X509 * -d2i_X509_bio(BIO *bp, X509 **x509) -{ - return ASN1_item_d2i_bio(&X509_it, bp, x509); -} -LCRYPTO_ALIAS(d2i_X509_bio); - -int -i2d_X509_bio(BIO *bp, X509 *x509) -{ - return ASN1_item_i2d_bio(&X509_it, bp, x509); -} -LCRYPTO_ALIAS(i2d_X509_bio); - -X509 * -d2i_X509_fp(FILE *fp, X509 **x509) -{ - return ASN1_item_d2i_fp(&X509_it, fp, x509); -} -LCRYPTO_ALIAS(d2i_X509_fp); - -int -i2d_X509_fp(FILE *fp, X509 *x509) -{ - return ASN1_item_i2d_fp(&X509_it, fp, x509); -} -LCRYPTO_ALIAS(i2d_X509_fp); - -X509_CRL * -d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) -{ - return ASN1_item_d2i_bio(&X509_CRL_it, bp, crl); -} -LCRYPTO_ALIAS(d2i_X509_CRL_bio); - -int -i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) -{ - return ASN1_item_i2d_bio(&X509_CRL_it, bp, crl); -} -LCRYPTO_ALIAS(i2d_X509_CRL_bio); - -X509_CRL * -d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) -{ - return ASN1_item_d2i_fp(&X509_CRL_it, fp, crl); -} -LCRYPTO_ALIAS(d2i_X509_CRL_fp); - -int -i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) -{ - return ASN1_item_i2d_fp(&X509_CRL_it, fp, crl); -} -LCRYPTO_ALIAS(i2d_X509_CRL_fp); - -X509_REQ * -d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) -{ - return ASN1_item_d2i_bio(&X509_REQ_it, bp, req); -} -LCRYPTO_ALIAS(d2i_X509_REQ_bio); - -int -i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) -{ - return ASN1_item_i2d_bio(&X509_REQ_it, bp, req); -} -LCRYPTO_ALIAS(i2d_X509_REQ_bio); - -X509_REQ * -d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) -{ - return ASN1_item_d2i_fp(&X509_REQ_it, fp, req); -} -LCRYPTO_ALIAS(d2i_X509_REQ_fp); - -int -i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) -{ - return ASN1_item_i2d_fp(&X509_REQ_it, fp, req); -} -LCRYPTO_ALIAS(i2d_X509_REQ_fp); - -#ifndef OPENSSL_NO_RSA -RSA * -d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) -{ - return ASN1_item_d2i_bio(&RSAPrivateKey_it, bp, rsa); -} -LCRYPTO_ALIAS(d2i_RSAPrivateKey_bio); - -int -i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) -{ - return ASN1_item_i2d_bio(&RSAPrivateKey_it, bp, rsa); -} -LCRYPTO_ALIAS(i2d_RSAPrivateKey_bio); - -RSA * -d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) -{ - return ASN1_item_d2i_fp(&RSAPrivateKey_it, fp, rsa); -} -LCRYPTO_ALIAS(d2i_RSAPrivateKey_fp); - -int -i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) -{ - return ASN1_item_i2d_fp(&RSAPrivateKey_it, fp, rsa); -} -LCRYPTO_ALIAS(i2d_RSAPrivateKey_fp); - -RSA * -d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) -{ - return ASN1_item_d2i_bio(&RSAPublicKey_it, bp, rsa); -} -LCRYPTO_ALIAS(d2i_RSAPublicKey_bio); - -int -i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) -{ - return ASN1_item_i2d_bio(&RSAPublicKey_it, bp, rsa); -} -LCRYPTO_ALIAS(i2d_RSAPublicKey_bio); - -RSA * -d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) -{ - return ASN1_item_d2i_fp(&RSAPublicKey_it, fp, rsa); -} -LCRYPTO_ALIAS(d2i_RSAPublicKey_fp); - -int -i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) -{ - return ASN1_item_i2d_fp(&RSAPublicKey_it, fp, rsa); -} -LCRYPTO_ALIAS(i2d_RSAPublicKey_fp); -#endif - -#ifndef OPENSSL_NO_DSA -DSA * -d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) -{ - return ASN1_item_d2i_bio(&DSAPrivateKey_it, bp, dsa); -} -LCRYPTO_ALIAS(d2i_DSAPrivateKey_bio); - -int -i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) -{ - return ASN1_item_i2d_bio(&DSAPrivateKey_it, bp, dsa); -} -LCRYPTO_ALIAS(i2d_DSAPrivateKey_bio); - -DSA * -d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) -{ - return ASN1_item_d2i_fp(&DSAPrivateKey_it, fp, dsa); -} -LCRYPTO_ALIAS(d2i_DSAPrivateKey_fp); - -int -i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) -{ - return ASN1_item_i2d_fp(&DSAPrivateKey_it, fp, dsa); -} -LCRYPTO_ALIAS(i2d_DSAPrivateKey_fp); -#endif - -#ifndef OPENSSL_NO_EC -EC_KEY * -d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) -{ - return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); -} -LCRYPTO_ALIAS(d2i_ECPrivateKey_bio); - -int -i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) -{ - return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); -} -LCRYPTO_ALIAS(i2d_ECPrivateKey_bio); - -EC_KEY * -d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) -{ - return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); -} -LCRYPTO_ALIAS(d2i_ECPrivateKey_fp); - -int -i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) -{ - return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); -} -LCRYPTO_ALIAS(i2d_ECPrivateKey_fp); -#endif - -X509_SIG * -d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) -{ - return ASN1_item_d2i_bio(&X509_SIG_it, bp, p8); -} -LCRYPTO_ALIAS(d2i_PKCS8_bio); - -int -i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) -{ - return ASN1_item_i2d_bio(&X509_SIG_it, bp, p8); -} -LCRYPTO_ALIAS(i2d_PKCS8_bio); - -X509_SIG * -d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) -{ - return ASN1_item_d2i_fp(&X509_SIG_it, fp, p8); -} -LCRYPTO_ALIAS(d2i_PKCS8_fp); - -int -i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) -{ - return ASN1_item_i2d_fp(&X509_SIG_it, fp, p8); -} -LCRYPTO_ALIAS(i2d_PKCS8_fp); - -PKCS8_PRIV_KEY_INFO * -d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf) -{ - return ASN1_item_d2i_bio(&PKCS8_PRIV_KEY_INFO_it, bp, - p8inf); -} -LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_bio); - -int -i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) -{ - return ASN1_item_i2d_bio(&PKCS8_PRIV_KEY_INFO_it, bp, - p8inf); -} -LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_bio); - -PKCS8_PRIV_KEY_INFO * -d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf) -{ - return ASN1_item_d2i_fp(&PKCS8_PRIV_KEY_INFO_it, fp, - p8inf); -} -LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_fp); - -int -i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) -{ - return ASN1_item_i2d_fp(&PKCS8_PRIV_KEY_INFO_it, fp, - p8inf); -} -LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_fp); - -EVP_PKEY * -d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) -{ - return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, - bp, a); -} -LCRYPTO_ALIAS(d2i_PrivateKey_bio); - -int -i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) -{ - return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); -} -LCRYPTO_ALIAS(i2d_PrivateKey_bio); - -EVP_PKEY * -d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) -{ - return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, - fp, a); -} -LCRYPTO_ALIAS(d2i_PrivateKey_fp); - -int -i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) -{ - return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); -} -LCRYPTO_ALIAS(i2d_PrivateKey_fp); - -int -i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) -{ - PKCS8_PRIV_KEY_INFO *p8inf; - int ret; - - p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) - return 0; - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; -} -LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_bio); - -int -i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) -{ - PKCS8_PRIV_KEY_INFO *p8inf; - int ret; - p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) - return 0; - ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; -} -LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_fp); - -int -X509_verify(X509 *a, EVP_PKEY *r) -{ - if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) - return 0; - return ASN1_item_verify(&X509_CINF_it, a->sig_alg, - a->signature, a->cert_info, r); -} -LCRYPTO_ALIAS(X509_verify); - -int -X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) -{ - return ASN1_item_verify(&X509_REQ_INFO_it, - a->sig_alg, a->signature, a->req_info, r); -} -LCRYPTO_ALIAS(X509_REQ_verify); - -int -NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) -{ - return ASN1_item_verify(&NETSCAPE_SPKAC_it, - a->sig_algor, a->signature, a->spkac, r); -} -LCRYPTO_ALIAS(NETSCAPE_SPKI_verify); - -int -X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - x->cert_info->enc.modified = 1; - return ASN1_item_sign(&X509_CINF_it, - x->cert_info->signature, x->sig_alg, x->signature, - x->cert_info, pkey, md); -} -LCRYPTO_ALIAS(X509_sign); - -int -X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) -{ - x->cert_info->enc.modified = 1; - return ASN1_item_sign_ctx(&X509_CINF_it, - x->cert_info->signature, x->sig_alg, x->signature, - x->cert_info, ctx); -} -LCRYPTO_ALIAS(X509_sign_ctx); - -int -X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - return ASN1_item_sign(&X509_REQ_INFO_it, - x->sig_alg, NULL, x->signature, x->req_info, pkey, md); -} -LCRYPTO_ALIAS(X509_REQ_sign); - -int -X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) -{ - return ASN1_item_sign_ctx(&X509_REQ_INFO_it, - x->sig_alg, NULL, x->signature, x->req_info, ctx); -} -LCRYPTO_ALIAS(X509_REQ_sign_ctx); - -int -X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - x->crl->enc.modified = 1; - return ASN1_item_sign(&X509_CRL_INFO_it, x->crl->sig_alg, - x->sig_alg, x->signature, x->crl, pkey, md); -} -LCRYPTO_ALIAS(X509_CRL_sign); - -int -X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) -{ - x->crl->enc.modified = 1; - return ASN1_item_sign_ctx(&X509_CRL_INFO_it, - x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx); -} -LCRYPTO_ALIAS(X509_CRL_sign_ctx); - -int -NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - return ASN1_item_sign(&NETSCAPE_SPKAC_it, - x->sig_algor, NULL, x->signature, x->spkac, pkey, md); -} -LCRYPTO_ALIAS(NETSCAPE_SPKI_sign); - -int -X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - ASN1_BIT_STRING *key; - key = X509_get0_pubkey_bitstr(data); - if (!key) - return 0; - return EVP_Digest(key->data, key->length, md, len, type, NULL); -} -LCRYPTO_ALIAS(X509_pubkey_digest); - -int -X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return ASN1_item_digest(&X509_it, type, (void *)data, md, len); -} -LCRYPTO_ALIAS(X509_digest); - -int -X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return ASN1_item_digest(&X509_CRL_it, type, (void *)data, md, len); -} -LCRYPTO_ALIAS(X509_CRL_digest); - -int -X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return ASN1_item_digest(&X509_REQ_it, type, (void *)data, md, len); -} -LCRYPTO_ALIAS(X509_REQ_digest); - -int -X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return ASN1_item_digest(&X509_NAME_it, type, (void *)data, md, len); -} -LCRYPTO_ALIAS(X509_NAME_digest); - -int -X509_up_ref(X509 *x) -{ - return CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509) > 1; -} -LCRYPTO_ALIAS(X509_up_ref); -- cgit v1.2.3-55-g6feb