early-access version 1255

This commit is contained in:
pineappleEA
2020-12-28 15:15:37 +00:00
parent 84b39492d1
commit 78b48028e1
6254 changed files with 1868140 additions and 0 deletions

422
externals/libressl/crypto/x509/by_dir.c vendored Executable file
View File

@@ -0,0 +1,422 @@
/* $OpenBSD: by_dir.c,v 1.39 2018/08/05 14:17:12 bcook 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 <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
# include <sys/stat.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 X509_LOOKUP_METHOD x509_dir_lookup = {
.name = "Load certs from files in a directory",
.new_item = new_dir,
.free = free_dir,
.init = NULL,
.shutdown = NULL,
.ctrl = dir_ctrl,
.get_by_subject = get_cert_by_subject,
.get_by_issuer_serial = NULL,
.get_by_fingerprint = NULL,
.get_by_alias = NULL,
};
X509_LOOKUP_METHOD *
X509_LOOKUP_hash_dir(void)
{
return (&x509_dir_lookup);
}
static int
dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
char **retp)
{
int ret = 0;
BY_DIR *ld;
ld = (BY_DIR *)ctx->method_data;
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(BY_DIR))) == NULL)
return (0);
if ((a->buffer = BUF_MEM_new()) == NULL) {
free(a);
return (0);
}
a->dirs = NULL;
lu->method_data = (char *)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);
if (ent->hashes)
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 = (BY_DIR *)lu->method_data;
if (a->dirs != NULL)
sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
if (a->buffer != NULL)
BUF_MEM_free(a->buffer);
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) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
}
ent = malloc(sizeof(BY_DIR_ENTRY));
if (!ent) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
ent->dir_type = type;
ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
ent->dir = strndup(ss, (size_t)len);
if (!ent->dir || !ent->hashes) {
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 = (BY_DIR *)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);
{
struct stat st;
if (stat(b->data, &st) < 0)
break;
}
/* found one. */
if (type == X509_LU_X509) {
if ((X509_load_cert_file(xl, b->data,
ent->dir_type)) == 0)
break;
} else if (type == X509_LU_CRL) {
if ((X509_load_crl_file(xl, b->data,
ent->dir_type)) == 0)
break;
}
/* else case will 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);
if (j != -1)
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
else
tmp = NULL;
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) {
htmp.hash = h;
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
if (idx >= 0)
hent = sk_BY_DIR_HASH_value(
ent->hashes, idx);
}
if (!hent) {
hent = malloc(sizeof(BY_DIR_HASH));
if (!hent) {
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));
/*
* If we were going to up the reference count,
* we would need to do it on a perl 'type' basis
*/
/* CRYPTO_add(&tmp->data.x509->references,1,
CRYPTO_LOCK_X509);*/
goto finish;
}
}
finish:
if (b != NULL)
BUF_MEM_free(b);
return (ok);
}

271
externals/libressl/crypto/x509/by_file.c vendored Executable file
View File

@@ -0,0 +1,271 @@
/* $OpenBSD: by_file.c,v 1.21 2017/01/29 17:49:23 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 <errno.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
static X509_LOOKUP_METHOD x509_file_lookup = {
.name = "Load file into cache",
.new_item = NULL,
.free = NULL,
.init = NULL,
.shutdown = NULL,
.ctrl = by_file_ctrl,
.get_by_subject = NULL,
.get_by_issuer_serial = NULL,
.get_by_fingerprint = NULL,
.get_by_alias = NULL,
};
X509_LOOKUP_METHOD *
X509_LOOKUP_file(void)
{
return (&x509_file_lookup);
}
static int
by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
char **ret)
{
int ok = 0;
switch (cmd) {
case X509_L_FILE_LOAD:
if (argl == X509_FILETYPE_DEFAULT) {
ok = (X509_load_cert_crl_file(ctx,
X509_get_default_cert_file(),
X509_FILETYPE_PEM) != 0);
if (!ok) {
X509error(X509_R_LOADING_DEFAULTS);
}
} else {
if (argl == X509_FILETYPE_PEM)
ok = (X509_load_cert_crl_file(ctx, argp,
X509_FILETYPE_PEM) != 0);
else
ok = (X509_load_cert_file(ctx,
argp, (int)argl) != 0);
}
break;
}
return (ok);
}
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;
if (file == NULL)
return (1);
in = BIO_new(BIO_s_file_internal());
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, 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);
}
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;
if (file == NULL)
return (1);
in = BIO_new(BIO_s_file_internal());
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, 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:
if (x != NULL)
X509_CRL_free(x);
BIO_free(in);
return (ret);
}
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, 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++;
}
}
sk_X509_INFO_pop_free(inf, X509_INFO_free);
return count;
}

138
externals/libressl/crypto/x509/by_mem.c vendored Executable file
View File

@@ -0,0 +1,138 @@
/* $OpenBSD: by_mem.c,v 1.4 2017/01/29 17:49:23 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 <sys/uio.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
static int by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **);
static X509_LOOKUP_METHOD x509_mem_lookup = {
.name = "Load cert from memory",
.new_item = NULL,
.free = NULL,
.init = NULL,
.shutdown = NULL,
.ctrl = by_mem_ctrl,
.get_by_subject = NULL,
.get_by_issuer_serial = NULL,
.get_by_fingerprint = NULL,
.get_by_alias = NULL,
};
X509_LOOKUP_METHOD *
X509_LOOKUP_mem(void)
{
return (&x509_mem_lookup);
}
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);
}

133
externals/libressl/crypto/x509/ext_dat.h vendored Executable file
View File

@@ -0,0 +1,133 @@
/* $OpenBSD: ext_dat.h,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/opensslconf.h>
__BEGIN_HIDDEN_DECLS
/* This file contains a table of "standard" extensions */
extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
extern X509V3_EXT_METHOD v3_addr, v3_asid;
/* This table will be searched using OBJ_bsearch so it *must* kept in
* order of the ext_nid values.
*/
static const X509V3_EXT_METHOD *standard_exts[] = {
&v3_nscert,
&v3_ns_ia5_list[0],
&v3_ns_ia5_list[1],
&v3_ns_ia5_list[2],
&v3_ns_ia5_list[3],
&v3_ns_ia5_list[4],
&v3_ns_ia5_list[5],
&v3_ns_ia5_list[6],
&v3_skey_id,
&v3_key_usage,
&v3_pkey_usage_period,
&v3_alt[0],
&v3_alt[1],
&v3_bcons,
&v3_crl_num,
&v3_cpols,
&v3_akey_id,
&v3_crld,
&v3_ext_ku,
&v3_delta_crl,
&v3_crl_reason,
#ifndef OPENSSL_NO_OCSP
&v3_crl_invdate,
#endif
&v3_sxnet,
&v3_info,
#ifndef OPENSSL_NO_OCSP
&v3_ocsp_nonce,
&v3_ocsp_crlid,
&v3_ocsp_accresp,
&v3_ocsp_nocheck,
&v3_ocsp_acutoff,
&v3_ocsp_serviceloc,
#endif
&v3_sinfo,
&v3_policy_constraints,
#ifndef OPENSSL_NO_OCSP
&v3_crl_hold,
#endif
&v3_pci,
&v3_name_constraints,
&v3_policy_mappings,
&v3_inhibit_anyp,
&v3_idp,
&v3_alt[2],
&v3_freshest_crl,
};
/* Number of standard extensions */
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
__END_HIDDEN_DECLS

271
externals/libressl/crypto/x509/pcy_cache.c vendored Executable file
View File

@@ -0,0 +1,271 @@
/* $OpenBSD: pcy_cache.c,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
static int policy_data_cmp(const X509_POLICY_DATA * const *a,
const X509_POLICY_DATA * const *b);
static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
/* Set cache entry according to CertificatePolicies extension.
* Note: this destroys the passed CERTIFICATEPOLICIES structure.
*/
static int
policy_cache_create(X509 *x, CERTIFICATEPOLICIES *policies, int crit)
{
int i;
int ret = 0;
X509_POLICY_CACHE *cache = x->policy_cache;
X509_POLICY_DATA *data = NULL;
POLICYINFO *policy;
if (sk_POLICYINFO_num(policies) == 0)
goto bad_policy;
cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
if (!cache->data)
goto bad_policy;
for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
policy = sk_POLICYINFO_value(policies, i);
data = policy_data_new(policy, NULL, crit);
if (!data)
goto bad_policy;
/* Duplicate policy OIDs are illegal: reject if matches
* found.
*/
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
if (cache->anyPolicy) {
ret = -1;
goto bad_policy;
}
cache->anyPolicy = data;
} else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
ret = -1;
goto bad_policy;
} else if (!sk_X509_POLICY_DATA_push(cache->data, data))
goto bad_policy;
data = NULL;
}
ret = 1;
bad_policy:
if (ret == -1)
x->ex_flags |= EXFLAG_INVALID_POLICY;
if (data)
policy_data_free(data);
sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
if (ret <= 0) {
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
cache->data = NULL;
}
return ret;
}
static int
policy_cache_new(X509 *x)
{
X509_POLICY_CACHE *cache;
ASN1_INTEGER *ext_any = NULL;
POLICY_CONSTRAINTS *ext_pcons = NULL;
CERTIFICATEPOLICIES *ext_cpols = NULL;
POLICY_MAPPINGS *ext_pmaps = NULL;
int i;
cache = malloc(sizeof(X509_POLICY_CACHE));
if (!cache)
return 0;
cache->anyPolicy = NULL;
cache->data = NULL;
cache->any_skip = -1;
cache->explicit_skip = -1;
cache->map_skip = -1;
x->policy_cache = cache;
/* Handle requireExplicitPolicy *first*. Need to process this
* even if we don't have any policies.
*/
ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
if (!ext_pcons) {
if (i != -1)
goto bad_cache;
} else {
if (!ext_pcons->requireExplicitPolicy &&
!ext_pcons->inhibitPolicyMapping)
goto bad_cache;
if (!policy_cache_set_int(&cache->explicit_skip,
ext_pcons->requireExplicitPolicy))
goto bad_cache;
if (!policy_cache_set_int(&cache->map_skip,
ext_pcons->inhibitPolicyMapping))
goto bad_cache;
}
/* Process CertificatePolicies */
ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
/* If no CertificatePolicies extension or problem decoding then
* there is no point continuing because the valid policies will be
* NULL.
*/
if (!ext_cpols) {
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
return 1;
}
i = policy_cache_create(x, ext_cpols, i);
/* NB: ext_cpols freed by policy_cache_set_policies */
if (i <= 0)
return i;
ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
if (!ext_pmaps) {
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
} else {
i = policy_cache_set_mapping(x, ext_pmaps);
if (i <= 0)
goto bad_cache;
}
ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
if (!ext_any) {
if (i != -1)
goto bad_cache;
} else if (!policy_cache_set_int(&cache->any_skip, ext_any))
goto bad_cache;
if (0) {
bad_cache:
x->ex_flags |= EXFLAG_INVALID_POLICY;
}
if (ext_pcons)
POLICY_CONSTRAINTS_free(ext_pcons);
if (ext_any)
ASN1_INTEGER_free(ext_any);
return 1;
}
void
policy_cache_free(X509_POLICY_CACHE *cache)
{
if (!cache)
return;
if (cache->anyPolicy)
policy_data_free(cache->anyPolicy);
if (cache->data)
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
free(cache);
}
const X509_POLICY_CACHE *
policy_cache_set(X509 *x)
{
if (x->policy_cache == NULL) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
policy_cache_new(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
return x->policy_cache;
}
X509_POLICY_DATA *
policy_cache_find_data(const X509_POLICY_CACHE *cache, const ASN1_OBJECT *id)
{
int idx;
X509_POLICY_DATA tmp;
tmp.valid_policy = (ASN1_OBJECT *)id;
idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
if (idx == -1)
return NULL;
return sk_X509_POLICY_DATA_value(cache->data, idx);
}
static int
policy_data_cmp(const X509_POLICY_DATA * const *a,
const X509_POLICY_DATA * const *b)
{
return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
}
static int
policy_cache_set_int(long *out, ASN1_INTEGER *value)
{
if (value == NULL)
return 1;
if (value->type == V_ASN1_NEG_INTEGER)
return 0;
*out = ASN1_INTEGER_get(value);
return 1;
}

129
externals/libressl/crypto/x509/pcy_data.c vendored Executable file
View File

@@ -0,0 +1,129 @@
/* $OpenBSD: pcy_data.c,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
/* Policy Node routines */
void
policy_data_free(X509_POLICY_DATA *data)
{
ASN1_OBJECT_free(data->valid_policy);
/* Don't free qualifiers if shared */
if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
sk_POLICYQUALINFO_pop_free(data->qualifier_set,
POLICYQUALINFO_free);
sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
free(data);
}
/* Create a data based on an existing policy. If 'id' is NULL use the
* oid in the policy, otherwise use 'id'. This behaviour covers the two
* types of data in RFC3280: data with from a CertificatePolcies extension
* and additional data with just the qualifiers of anyPolicy and ID from
* another source.
*/
X509_POLICY_DATA *
policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *cid, int crit)
{
X509_POLICY_DATA *ret = NULL;
ASN1_OBJECT *id = NULL;
if (policy == NULL && cid == NULL)
return NULL;
if (cid != NULL) {
id = OBJ_dup(cid);
if (id == NULL)
return NULL;
}
ret = malloc(sizeof(X509_POLICY_DATA));
if (ret == NULL)
goto err;
ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
if (ret->expected_policy_set == NULL)
goto err;
if (crit)
ret->flags = POLICY_DATA_FLAG_CRITICAL;
else
ret->flags = 0;
if (id != NULL)
ret->valid_policy = id;
else {
ret->valid_policy = policy->policyid;
policy->policyid = NULL;
}
if (policy != NULL) {
ret->qualifier_set = policy->qualifiers;
policy->qualifiers = NULL;
} else
ret->qualifier_set = NULL;
return ret;
err:
free(ret);
ASN1_OBJECT_free(id);
return NULL;
}

209
externals/libressl/crypto/x509/pcy_int.h vendored Executable file
View File

@@ -0,0 +1,209 @@
/* $OpenBSD: pcy_int.h,v 1.1 2020/06/04 15:19:31 jsing 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).
*
*/
__BEGIN_HIDDEN_DECLS
typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
DECLARE_STACK_OF(X509_POLICY_DATA)
/* Internal structures */
/* This structure and the field names correspond to the Policy 'node' of
* RFC3280. NB this structure contains no pointers to parent or child
* data: X509_POLICY_NODE contains that. This means that the main policy data
* can be kept static and cached with the certificate.
*/
struct X509_POLICY_DATA_st {
unsigned int flags;
/* Policy OID and qualifiers for this data */
ASN1_OBJECT *valid_policy;
STACK_OF(POLICYQUALINFO) *qualifier_set;
STACK_OF(ASN1_OBJECT) *expected_policy_set;
};
/* X509_POLICY_DATA flags values */
/* This flag indicates the structure has been mapped using a policy mapping
* extension. If policy mapping is not active its references get deleted.
*/
#define POLICY_DATA_FLAG_MAPPED 0x1
/* This flag indicates the data doesn't correspond to a policy in Certificate
* Policies: it has been mapped to any policy.
*/
#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
/* AND with flags to see if any mapping has occurred */
#define POLICY_DATA_FLAG_MAP_MASK 0x3
/* qualifiers are shared and shouldn't be freed */
#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
/* Parent node is an extra node and should be freed */
#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
/* Corresponding CertificatePolicies is critical */
#define POLICY_DATA_FLAG_CRITICAL 0x10
/* This structure is cached with a certificate */
struct X509_POLICY_CACHE_st {
/* anyPolicy data or NULL if no anyPolicy */
X509_POLICY_DATA *anyPolicy;
/* other policy data */
STACK_OF(X509_POLICY_DATA) *data;
/* If InhibitAnyPolicy present this is its value or -1 if absent. */
long any_skip;
/* If policyConstraints and requireExplicitPolicy present this is its
* value or -1 if absent.
*/
long explicit_skip;
/* If policyConstraints and policyMapping present this is its
* value or -1 if absent.
*/
long map_skip;
};
/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/
/* This structure represents the relationship between nodes */
struct X509_POLICY_NODE_st {
/* node data this refers to */
const X509_POLICY_DATA *data;
/* Parent node */
X509_POLICY_NODE *parent;
/* Number of child nodes */
int nchild;
};
struct X509_POLICY_LEVEL_st {
/* Cert for this level */
X509 *cert;
/* nodes at this level */
STACK_OF(X509_POLICY_NODE) *nodes;
/* anyPolicy node */
X509_POLICY_NODE *anyPolicy;
/* Extra data */
/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
unsigned int flags;
};
struct X509_POLICY_TREE_st {
/* This is the tree 'level' data */
X509_POLICY_LEVEL *levels;
int nlevel;
/* Extra policy data when additional nodes (not from the certificate)
* are required.
*/
STACK_OF(X509_POLICY_DATA) *extra_data;
/* This is the authority constained policy set */
STACK_OF(X509_POLICY_NODE) *auth_policies;
STACK_OF(X509_POLICY_NODE) *user_policies;
unsigned int flags;
};
/* Set if anyPolicy present in user policies */
#define POLICY_FLAG_ANY_POLICY 0x2
/* Useful macros */
#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
#define node_critical(node) node_data_critical(node->data)
/* Internal functions */
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
int crit);
void policy_data_free(X509_POLICY_DATA *data);
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
const ASN1_OBJECT *id);
int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
void policy_cache_init(void);
void policy_cache_free(X509_POLICY_CACHE *cache);
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
const X509_POLICY_NODE *parent, const ASN1_OBJECT *id);
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
const ASN1_OBJECT *id);
int level_add_node(X509_POLICY_LEVEL *level,
const X509_POLICY_DATA *data, X509_POLICY_NODE *parent,
X509_POLICY_TREE *tree, X509_POLICY_NODE **nodep);
void policy_node_free(X509_POLICY_NODE *node);
int policy_node_match(const X509_POLICY_LEVEL *lvl,
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
const X509_POLICY_CACHE *policy_cache_set(X509 *x);
__END_HIDDEN_DECLS

157
externals/libressl/crypto/x509/pcy_lib.c vendored Executable file
View File

@@ -0,0 +1,157 @@
/* $OpenBSD: pcy_lib.c,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
/* accessor functions */
/* X509_POLICY_TREE stuff */
int
X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
{
if (!tree)
return 0;
return tree->nlevel;
}
X509_POLICY_LEVEL *
X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
{
if (!tree || (i < 0) || (i >= tree->nlevel))
return NULL;
return tree->levels + i;
}
STACK_OF(X509_POLICY_NODE) *
X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
{
if (!tree)
return NULL;
return tree->auth_policies;
}
STACK_OF(X509_POLICY_NODE) *
X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
{
if (!tree)
return NULL;
if (tree->flags & POLICY_FLAG_ANY_POLICY)
return tree->auth_policies;
else
return tree->user_policies;
}
/* X509_POLICY_LEVEL stuff */
int
X509_policy_level_node_count(X509_POLICY_LEVEL *level)
{
int n;
if (!level)
return 0;
if (level->anyPolicy)
n = 1;
else
n = 0;
if (level->nodes)
n += sk_X509_POLICY_NODE_num(level->nodes);
return n;
}
X509_POLICY_NODE *
X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
{
if (!level)
return NULL;
if (level->anyPolicy) {
if (i == 0)
return level->anyPolicy;
i--;
}
return sk_X509_POLICY_NODE_value(level->nodes, i);
}
/* X509_POLICY_NODE stuff */
const ASN1_OBJECT *
X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
{
if (!node)
return NULL;
return node->data->valid_policy;
}
STACK_OF(POLICYQUALINFO) *
X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
{
if (!node)
return NULL;
return node->data->qualifier_set;
}
const X509_POLICY_NODE *
X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
{
if (!node)
return NULL;
return node->parent;
}

126
externals/libressl/crypto/x509/pcy_map.c vendored Executable file
View File

@@ -0,0 +1,126 @@
/* $OpenBSD: pcy_map.c,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
/* Set policy mapping entries in cache.
* Note: this modifies the passed POLICY_MAPPINGS structure
*/
int
policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
{
POLICY_MAPPING *map;
X509_POLICY_DATA *data;
X509_POLICY_CACHE *cache = x->policy_cache;
int i;
int ret = 0;
if (sk_POLICY_MAPPING_num(maps) == 0) {
ret = -1;
goto bad_mapping;
}
for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
map = sk_POLICY_MAPPING_value(maps, i);
/* Reject if map to or from anyPolicy */
if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) ||
(OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
ret = -1;
goto bad_mapping;
}
/* Attempt to find matching policy data */
data = policy_cache_find_data(cache, map->issuerDomainPolicy);
/* If we don't have anyPolicy can't map */
if (!data && !cache->anyPolicy)
continue;
/* Create a NODE from anyPolicy */
if (!data) {
data = policy_data_new(NULL, map->issuerDomainPolicy,
cache->anyPolicy->flags &
POLICY_DATA_FLAG_CRITICAL);
if (!data)
goto bad_mapping;
data->qualifier_set = cache->anyPolicy->qualifier_set;
/*map->issuerDomainPolicy = NULL;*/
data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
policy_data_free(data);
goto bad_mapping;
}
} else
data->flags |= POLICY_DATA_FLAG_MAPPED;
if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
map->subjectDomainPolicy))
goto bad_mapping;
map->subjectDomainPolicy = NULL;
}
ret = 1;
bad_mapping:
if (ret == -1)
x->ex_flags |= EXFLAG_INVALID_POLICY;
sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
return ret;
}

200
externals/libressl/crypto/x509/pcy_node.c vendored Executable file
View File

@@ -0,0 +1,200 @@
/* $OpenBSD: pcy_node.c,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
static int
node_cmp(const X509_POLICY_NODE * const *a, const X509_POLICY_NODE * const *b)
{
return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
}
STACK_OF(X509_POLICY_NODE) *
policy_node_cmp_new(void)
{
return sk_X509_POLICY_NODE_new(node_cmp);
}
X509_POLICY_NODE *
tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, const ASN1_OBJECT *id)
{
X509_POLICY_DATA n;
X509_POLICY_NODE l;
int idx;
n.valid_policy = (ASN1_OBJECT *)id;
l.data = &n;
idx = sk_X509_POLICY_NODE_find(nodes, &l);
if (idx == -1)
return NULL;
return sk_X509_POLICY_NODE_value(nodes, idx);
}
X509_POLICY_NODE *
level_find_node(const X509_POLICY_LEVEL *level, const X509_POLICY_NODE *parent,
const ASN1_OBJECT *id)
{
X509_POLICY_NODE *node;
int i;
for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
node = sk_X509_POLICY_NODE_value(level->nodes, i);
if (node->parent == parent) {
if (!OBJ_cmp(node->data->valid_policy, id))
return node;
}
}
return NULL;
}
int
level_add_node(X509_POLICY_LEVEL *level, const X509_POLICY_DATA *data,
X509_POLICY_NODE *parent, X509_POLICY_TREE *tree, X509_POLICY_NODE **nodep)
{
X509_POLICY_NODE *node = NULL;
if (level) {
node = malloc(sizeof(X509_POLICY_NODE));
if (!node)
goto node_error;
node->data = data;
node->parent = parent;
node->nchild = 0;
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
if (level->anyPolicy)
goto node_error;
level->anyPolicy = node;
if (parent)
parent->nchild++;
} else {
if (!level->nodes)
level->nodes = policy_node_cmp_new();
if (!level->nodes)
goto node_error;
if (!sk_X509_POLICY_NODE_push(level->nodes, node))
goto node_error;
if (parent)
parent->nchild++;
}
}
if (tree) {
if (!tree->extra_data)
tree->extra_data = sk_X509_POLICY_DATA_new_null();
if (!tree->extra_data)
goto node_error_cond;
if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
goto node_error_cond;
}
if (nodep)
*nodep = node;
return 1;
node_error_cond:
if (level)
node = NULL;
node_error:
policy_node_free(node);
node = NULL;
if (nodep)
*nodep = node;
return 0;
}
void
policy_node_free(X509_POLICY_NODE *node)
{
free(node);
}
/* See if a policy node matches a policy OID. If mapping enabled look through
* expected policy set otherwise just valid policy.
*/
int
policy_node_match(const X509_POLICY_LEVEL *lvl, const X509_POLICY_NODE *node,
const ASN1_OBJECT *oid)
{
int i;
ASN1_OBJECT *policy_oid;
const X509_POLICY_DATA *x = node->data;
if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) ||
!(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
if (!OBJ_cmp(x->valid_policy, oid))
return 1;
return 0;
}
for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
if (!OBJ_cmp(policy_oid, oid))
return 1;
}
return 0;
}

770
externals/libressl/crypto/x509/pcy_tree.c vendored Executable file
View File

@@ -0,0 +1,770 @@
/* $OpenBSD: pcy_tree.c,v 1.1 2020/06/04 15:19:31 jsing 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 <openssl/x509.h>
#include <openssl/x509v3.h>
#include "pcy_int.h"
/* Enable this to print out the complete policy tree at various point during
* evaluation.
*/
/*#define OPENSSL_POLICY_DEBUG*/
#ifdef OPENSSL_POLICY_DEBUG
static void
expected_print(BIO *err, X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node,
int indent)
{
if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) ||
!(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
BIO_puts(err, " Not Mapped\n");
else {
int i;
STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
ASN1_OBJECT *oid;
BIO_puts(err, " Expected: ");
for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
oid = sk_ASN1_OBJECT_value(pset, i);
if (i)
BIO_puts(err, ", ");
i2a_ASN1_OBJECT(err, oid);
}
BIO_puts(err, "\n");
}
}
static void
tree_print(char *str, X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
{
X509_POLICY_LEVEL *plev;
X509_POLICY_NODE *node;
int i;
BIO *err;
if ((err = BIO_new_fp(stderr, BIO_NOCLOSE)) == NULL)
return;
if (!curr)
curr = tree->levels + tree->nlevel;
else
curr++;
BIO_printf(err, "Level print after %s\n", str);
BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
for (plev = tree->levels; plev != curr; plev++) {
BIO_printf(err, "Level %ld, flags = %x\n",
plev - tree->levels, plev->flags);
for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
node = sk_X509_POLICY_NODE_value(plev->nodes, i);
X509_POLICY_NODE_print(err, node, 2);
expected_print(err, plev, node, 2);
BIO_printf(err, " Flags: %x\n", node->data->flags);
}
if (plev->anyPolicy)
X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
}
BIO_free(err);
}
#else
#define tree_print(a,b,c) /* */
#endif
/* Initialize policy tree. Return values:
* 0 Some internal error occured.
* -1 Inconsistent or invalid extensions in certificates.
* 1 Tree initialized OK.
* 2 Policy tree is empty.
* 5 Tree OK and requireExplicitPolicy true.
* 6 Tree empty and requireExplicitPolicy true.
*/
static int
tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, unsigned int flags)
{
X509_POLICY_TREE *tree;
X509_POLICY_LEVEL *level;
const X509_POLICY_CACHE *cache;
X509_POLICY_DATA *data = NULL;
X509 *x;
int ret = 1;
int i, n;
int explicit_policy;
int any_skip;
int map_skip;
*ptree = NULL;
n = sk_X509_num(certs);
if (flags & X509_V_FLAG_EXPLICIT_POLICY)
explicit_policy = 0;
else
explicit_policy = n + 1;
if (flags & X509_V_FLAG_INHIBIT_ANY)
any_skip = 0;
else
any_skip = n + 1;
if (flags & X509_V_FLAG_INHIBIT_MAP)
map_skip = 0;
else
map_skip = n + 1;
/* Can't do anything with just a trust anchor */
if (n == 1)
return 1;
/* First setup policy cache in all certificates apart from the
* trust anchor. Note any bad cache results on the way. Also can
* calculate explicit_policy value at this point.
*/
for (i = n - 2; i >= 0; i--) {
x = sk_X509_value(certs, i);
X509_check_purpose(x, -1, -1);
cache = policy_cache_set(x);
/* If cache NULL something bad happened: return immediately */
if (cache == NULL)
return 0;
/* If inconsistent extensions keep a note of it but continue */
if (x->ex_flags & EXFLAG_INVALID_POLICY)
ret = -1;
/* Otherwise if we have no data (hence no CertificatePolicies)
* and haven't already set an inconsistent code note it.
*/
else if ((ret == 1) && !cache->data)
ret = 2;
if (explicit_policy > 0) {
if (!(x->ex_flags & EXFLAG_SI))
explicit_policy--;
if ((cache->explicit_skip != -1) &&
(cache->explicit_skip < explicit_policy))
explicit_policy = cache->explicit_skip;
}
}
if (ret != 1) {
if (ret == 2 && !explicit_policy)
return 6;
return ret;
}
/* If we get this far initialize the tree */
tree = malloc(sizeof(X509_POLICY_TREE));
if (!tree)
return 0;
tree->flags = 0;
tree->levels = calloc(n, sizeof(X509_POLICY_LEVEL));
tree->nlevel = 0;
tree->extra_data = NULL;
tree->auth_policies = NULL;
tree->user_policies = NULL;
if (!tree->levels) {
free(tree);
return 0;
}
tree->nlevel = n;
level = tree->levels;
/* Root data: initialize to anyPolicy */
data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
if (!data || !level_add_node(level, data, NULL, tree, NULL))
goto bad_tree;
for (i = n - 2; i >= 0; i--) {
level++;
x = sk_X509_value(certs, i);
cache = policy_cache_set(x);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
level->cert = x;
if (!cache->anyPolicy)
level->flags |= X509_V_FLAG_INHIBIT_ANY;
/* Determine inhibit any and inhibit map flags */
if (any_skip == 0) {
/* Any matching allowed if certificate is self
* issued and not the last in the chain.
*/
if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
level->flags |= X509_V_FLAG_INHIBIT_ANY;
} else {
if (!(x->ex_flags & EXFLAG_SI))
any_skip--;
if ((cache->any_skip >= 0) &&
(cache->any_skip < any_skip))
any_skip = cache->any_skip;
}
if (map_skip == 0)
level->flags |= X509_V_FLAG_INHIBIT_MAP;
else {
if (!(x->ex_flags & EXFLAG_SI))
map_skip--;
if ((cache->map_skip >= 0) &&
(cache->map_skip < map_skip))
map_skip = cache->map_skip;
}
}
*ptree = tree;
if (explicit_policy)
return 1;
else
return 5;
bad_tree:
X509_policy_tree_free(tree);
return 0;
}
static int
tree_link_matching_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_DATA *data)
{
X509_POLICY_LEVEL *last = curr - 1;
X509_POLICY_NODE *node;
int i, matched = 0;
/* Iterate through all in nodes linking matches */
for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
node = sk_X509_POLICY_NODE_value(last->nodes, i);
if (policy_node_match(last, node, data->valid_policy)) {
if (!level_add_node(curr, data, node, NULL, NULL))
return 0;
matched = 1;
}
}
if (!matched && last->anyPolicy) {
if (!level_add_node(curr, data, last->anyPolicy, NULL, NULL))
return 0;
}
return 1;
}
/* This corresponds to RFC3280 6.1.3(d)(1):
* link any data from CertificatePolicies onto matching parent
* or anyPolicy if no match.
*/
static int
tree_link_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache)
{
int i;
X509_POLICY_DATA *data;
for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
data = sk_X509_POLICY_DATA_value(cache->data, i);
/* Look for matching nodes in previous level */
if (!tree_link_matching_nodes(curr, data))
return 0;
}
return 1;
}
/* This corresponds to RFC3280 6.1.3(d)(2):
* Create new data for any unmatched policies in the parent and link
* to anyPolicy.
*/
static int
tree_add_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
const ASN1_OBJECT *id, X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
{
X509_POLICY_DATA *data;
if (id == NULL)
id = node->data->valid_policy;
/* Create a new node with qualifiers from anyPolicy and
* id from unmatched node.
*/
data = policy_data_new(NULL, id, node_critical(node));
if (data == NULL)
return 0;
/* Curr may not have anyPolicy */
data->qualifier_set = cache->anyPolicy->qualifier_set;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
if (!level_add_node(curr, data, node, tree, NULL)) {
policy_data_free(data);
return 0;
}
return 1;
}
static int
tree_link_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
{
const X509_POLICY_LEVEL *last = curr - 1;
int i;
if ((last->flags & X509_V_FLAG_INHIBIT_MAP) ||
!(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
/* If no policy mapping: matched if one child present */
if (node->nchild)
return 1;
if (!tree_add_unmatched(curr, cache, NULL, node, tree))
return 0;
/* Add it */
} else {
/* If mapping: matched if one child per expected policy set */
STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
if (node->nchild == sk_ASN1_OBJECT_num(expset))
return 1;
/* Locate unmatched nodes */
for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
if (level_find_node(curr, node, oid))
continue;
if (!tree_add_unmatched(curr, cache, oid, node, tree))
return 0;
}
}
return 1;
}
static int
tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
X509_POLICY_TREE *tree)
{
int i;
X509_POLICY_NODE *node;
X509_POLICY_LEVEL *last = curr - 1;
for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
node = sk_X509_POLICY_NODE_value(last->nodes, i);
if (!tree_link_unmatched(curr, cache, node, tree))
return 0;
}
/* Finally add link to anyPolicy */
if (last->anyPolicy) {
if (!level_add_node(curr, cache->anyPolicy,
last->anyPolicy, NULL, NULL))
return 0;
}
return 1;
}
/* Prune the tree: delete any child mapped child data on the current level
* then proceed up the tree deleting any data with no children. If we ever
* have no data on a level we can halt because the tree will be empty.
*/
static int
tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
{
STACK_OF(X509_POLICY_NODE) *nodes;
X509_POLICY_NODE *node;
int i;
nodes = curr->nodes;
if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
node = sk_X509_POLICY_NODE_value(nodes, i);
/* Delete any mapped data: see RFC3280 XXXX */
if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
node->parent->nchild--;
free(node);
(void)sk_X509_POLICY_NODE_delete(nodes, i);
}
}
}
for (;;) {
--curr;
nodes = curr->nodes;
for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
node = sk_X509_POLICY_NODE_value(nodes, i);
if (node->nchild == 0) {
node->parent->nchild--;
free(node);
(void)sk_X509_POLICY_NODE_delete(nodes, i);
}
}
if (curr->anyPolicy && !curr->anyPolicy->nchild) {
if (curr->anyPolicy->parent)
curr->anyPolicy->parent->nchild--;
free(curr->anyPolicy);
curr->anyPolicy = NULL;
}
if (curr == tree->levels) {
/* If we zapped anyPolicy at top then tree is empty */
if (!curr->anyPolicy)
return 2;
return 1;
}
}
return 1;
}
static int
tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy)
{
if (!*pnodes) {
*pnodes = policy_node_cmp_new();
if (!*pnodes)
return 0;
} else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
return 1;
if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
return 0;
return 1;
}
/* Calculate the authority set based on policy tree.
* The 'pnodes' parameter is used as a store for the set of policy nodes
* used to calculate the user set. If the authority set is not anyPolicy
* then pnodes will just point to the authority set. If however the authority
* set is anyPolicy then the set of valid policies (other than anyPolicy)
* is store in pnodes. The return value of '2' is used in this case to indicate
* that pnodes should be freed.
*/
static int
tree_calculate_authority_set(X509_POLICY_TREE *tree,
STACK_OF(X509_POLICY_NODE) **pnodes)
{
X509_POLICY_LEVEL *curr;
X509_POLICY_NODE *node, *anyptr;
STACK_OF(X509_POLICY_NODE) **addnodes;
int i, j;
curr = tree->levels + tree->nlevel - 1;
/* If last level contains anyPolicy set is anyPolicy */
if (curr->anyPolicy) {
if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
return 0;
addnodes = pnodes;
} else
/* Add policies to authority set */
addnodes = &tree->auth_policies;
curr = tree->levels;
for (i = 1; i < tree->nlevel; i++) {
/* If no anyPolicy node on this this level it can't
* appear on lower levels so end search.
*/
if (!(anyptr = curr->anyPolicy))
break;
curr++;
for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
node = sk_X509_POLICY_NODE_value(curr->nodes, j);
if ((node->parent == anyptr) &&
!tree_add_auth_node(addnodes, node))
return 0;
}
}
if (addnodes == pnodes)
return 2;
*pnodes = tree->auth_policies;
return 1;
}
static int
tree_calculate_user_set(X509_POLICY_TREE *tree,
STACK_OF(ASN1_OBJECT) *policy_oids, STACK_OF(X509_POLICY_NODE) *auth_nodes)
{
int i;
X509_POLICY_NODE *node;
ASN1_OBJECT *oid;
X509_POLICY_NODE *anyPolicy;
X509_POLICY_DATA *extra;
/* Check if anyPolicy present in authority constrained policy set:
* this will happen if it is a leaf node.
*/
if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
return 1;
anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
oid = sk_ASN1_OBJECT_value(policy_oids, i);
if (OBJ_obj2nid(oid) == NID_any_policy) {
tree->flags |= POLICY_FLAG_ANY_POLICY;
return 1;
}
}
for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
oid = sk_ASN1_OBJECT_value(policy_oids, i);
node = tree_find_sk(auth_nodes, oid);
if (!node) {
if (!anyPolicy)
continue;
/* Create a new node with policy ID from user set
* and qualifiers from anyPolicy.
*/
extra = policy_data_new(NULL, oid,
node_critical(anyPolicy));
if (!extra)
return 0;
extra->qualifier_set = anyPolicy->data->qualifier_set;
extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS |
POLICY_DATA_FLAG_EXTRA_NODE;
(void) level_add_node(NULL, extra, anyPolicy->parent,
tree, &node);
}
if (!tree->user_policies) {
tree->user_policies = sk_X509_POLICY_NODE_new_null();
if (!tree->user_policies)
return 1;
}
if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
return 0;
}
return 1;
}
static int
tree_evaluate(X509_POLICY_TREE *tree)
{
int ret, i;
X509_POLICY_LEVEL *curr = tree->levels + 1;
const X509_POLICY_CACHE *cache;
for (i = 1; i < tree->nlevel; i++, curr++) {
cache = policy_cache_set(curr->cert);
if (!tree_link_nodes(curr, cache))
return 0;
if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) &&
!tree_link_any(curr, cache, tree))
return 0;
tree_print("before tree_prune()", tree, curr);
ret = tree_prune(tree, curr);
if (ret != 1)
return ret;
}
return 1;
}
static void
exnode_free(X509_POLICY_NODE *node)
{
if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
free(node);
}
void
X509_policy_tree_free(X509_POLICY_TREE *tree)
{
X509_POLICY_LEVEL *curr;
int i;
if (!tree)
return;
sk_X509_POLICY_NODE_free(tree->auth_policies);
sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
X509_free(curr->cert);
if (curr->nodes)
sk_X509_POLICY_NODE_pop_free(curr->nodes,
policy_node_free);
if (curr->anyPolicy)
policy_node_free(curr->anyPolicy);
}
if (tree->extra_data)
sk_X509_POLICY_DATA_pop_free(tree->extra_data,
policy_data_free);
free(tree->levels);
free(tree);
}
/* Application policy checking function.
* Return codes:
* 0 Internal Error.
* 1 Successful.
* -1 One or more certificates contain invalid or inconsistent extensions
* -2 User constrained policy set empty and requireExplicit true.
*/
int
X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids,
unsigned int flags)
{
int ret, ret2;
X509_POLICY_TREE *tree = NULL;
STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
*ptree = NULL;
*pexplicit_policy = 0;
ret = tree_init(&tree, certs, flags);
switch (ret) {
/* Tree empty requireExplicit False: OK */
case 2:
return 1;
/* Some internal error */
case -1:
return -1;
/* Some internal error */
case 0:
return 0;
/* Tree empty requireExplicit True: Error */
case 6:
*pexplicit_policy = 1;
return -2;
/* Tree OK requireExplicit True: OK and continue */
case 5:
*pexplicit_policy = 1;
break;
/* Tree OK: continue */
case 1:
if (!tree)
/*
* tree_init() returns success and a null tree
* if it's just looking at a trust anchor.
* I'm not sure that returning success here is
* correct, but I'm sure that reporting this
* as an internal error which our caller
* interprets as a malloc failure is wrong.
*/
return 1;
break;
}
if (!tree)
goto error;
ret = tree_evaluate(tree);
tree_print("tree_evaluate()", tree, NULL);
if (ret <= 0)
goto error;
/* Return value 2 means tree empty */
if (ret == 2) {
X509_policy_tree_free(tree);
if (*pexplicit_policy)
return -2;
else
return 1;
}
/* Tree is not empty: continue */
ret = tree_calculate_authority_set(tree, &auth_nodes);
if (ret == 0)
goto error;
ret2 = tree_calculate_user_set(tree, policy_oids, auth_nodes);
/* Return value 2 means auth_nodes needs to be freed */
if (ret == 2)
sk_X509_POLICY_NODE_free(auth_nodes);
if (ret2 == 0)
goto error;
if (tree)
*ptree = tree;
if (*pexplicit_policy) {
nodes = X509_policy_tree_get0_user_policies(tree);
if (sk_X509_POLICY_NODE_num(nodes) <= 0)
return -2;
}
return 1;
error:
X509_policy_tree_free(tree);
return 0;
}

75
externals/libressl/crypto/x509/vpm_int.h vendored Executable file
View File

@@ -0,0 +1,75 @@
/* $OpenBSD: vpm_int.h,v 1.4 2018/04/06 07:08:20 beck 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).
*
*/
__BEGIN_HIDDEN_DECLS
/* internal only structure to hold additional X509_VERIFY_PARAM data */
struct X509_VERIFY_PARAM_ID_st {
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;
};
__END_HIDDEN_DECLS

237
externals/libressl/crypto/x509/x509_akey.c vendored Executable file
View File

@@ -0,0 +1,237 @@
/* $OpenBSD: x509_akey.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_akey_id = {
.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,
};
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;
}

124
externals/libressl/crypto/x509/x509_akeya.c vendored Executable file
View File

@@ -0,0 +1,124 @@
/* $OpenBSD: x509_akeya.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
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",
};
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);
}
int
i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_KEYID_it);
}
AUTHORITY_KEYID *
AUTHORITY_KEYID_new(void)
{
return (AUTHORITY_KEYID *)ASN1_item_new(&AUTHORITY_KEYID_it);
}
void
AUTHORITY_KEYID_free(AUTHORITY_KEYID *a)
{
ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_KEYID_it);
}

699
externals/libressl/crypto/x509/x509_alt.c vendored Executable file
View File

@@ -0,0 +1,699 @@
/* $OpenBSD: x509_alt.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_alt[] = {
{
.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,
},
{
.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,
},
{
.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,
},
};
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;
}
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", "<unsupported>", &ret))
goto err;
break;
case GEN_X400:
if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
goto err;
break;
case GEN_EDIPARTY:
if (!X509V3_add_value("EdiPartyName", "<unsupported>", &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", "<invalid>", &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;
}
int
GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
{
unsigned char *p;
int i;
switch (gen->type) {
case GEN_OTHERNAME:
BIO_printf(out, "othername:<unsupported>");
break;
case GEN_X400:
BIO_printf(out, "X400Name:<unsupported>");
break;
case GEN_EDIPARTY:
/* Maybe fix this: it is supported now */
BIO_printf(out, "EdiPartyName:<unsupported>");
break;
case GEN_EMAIL:
BIO_printf(out, "email:%s", gen->d.ia5->data);
break;
case GEN_DNS:
BIO_printf(out, "DNS:%s", gen->d.ia5->data);
break;
case GEN_URI:
BIO_printf(out, "URI:%s", 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:<invalid>");
break;
}
break;
case GEN_RID:
BIO_printf(out, "Registered ID");
i2a_ASN1_OBJECT(out, gen->d.rid);
break;
}
return 1;
}
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;
GENERAL_NAME *gen;
X509_EXTENSION *ext;
int i;
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++) {
gen = sk_GENERAL_NAME_value(ialt, i);
if (!sk_GENERAL_NAME_push(gens, gen)) {
X509V3error(ERR_R_MALLOC_FAILURE);
goto err;
}
}
sk_GENERAL_NAME_free(ialt);
return 1;
err:
return 0;
}
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;
}
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);
}
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;
}
GENERAL_NAME *
v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
{
int type;
char *name, *value;
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;
}
return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
}
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_get_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;
X509V3_section_free(ctx, sk);
return ret;
}

399
externals/libressl/crypto/x509/x509_att.c vendored Executable file
View File

@@ -0,0 +1,399 @@
/* $OpenBSD: x509_att.c,v 1.17 2018/05/18 19:21:33 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int
X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
{
return sk_X509_ATTRIBUTE_num(x);
}
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);
}
X509_ATTRIBUTE *
X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
return NULL;
else
return sk_X509_ATTRIBUTE_value(x, loc);
}
X509_ATTRIBUTE *
X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
X509_ATTRIBUTE *ret;
if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
return (NULL);
ret = sk_X509_ATTRIBUTE_delete(x, loc);
return (ret);
}
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 = X509at_get_attr(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);
}
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);
}
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;
}
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;
}
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;
}
if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
goto err;
attr->single = 0;
/* 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->value.set, ttmp))
goto err;
return 1;
err:
ASN1_TYPE_free(ttmp);
ASN1_STRING_free(stmp);
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
int
X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
{
if (!attr->single)
return sk_ASN1_TYPE_num(attr->value.set);
if (attr->value.single)
return 1;
return 0;
}
ASN1_OBJECT *
X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
{
if (attr == NULL)
return (NULL);
return (attr->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;
}
ASN1_TYPE *
X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
{
if (attr == NULL)
return (NULL);
if (idx >= X509_ATTRIBUTE_count(attr))
return NULL;
if (!attr->single)
return sk_ASN1_TYPE_value(attr->value.set, idx);
else
return attr->value.single;
}

199
externals/libressl/crypto/x509/x509_bcons.c vendored Executable file
View File

@@ -0,0 +1,199 @@
/* $OpenBSD: x509_bcons.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_bcons = {
.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,
};
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",
};
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);
}
int
i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &BASIC_CONSTRAINTS_it);
}
BASIC_CONSTRAINTS *
BASIC_CONSTRAINTS_new(void)
{
return (BASIC_CONSTRAINTS *)ASN1_item_new(&BASIC_CONSTRAINTS_it);
}
void
BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a)
{
ASN1_item_free((ASN1_VALUE *)a, &BASIC_CONSTRAINTS_it);
}
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;
}

187
externals/libressl/crypto/x509/x509_bitst.c vendored Executable file
View File

@@ -0,0 +1,187 @@
/* $OpenBSD: x509_bitst.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
static 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 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}
};
const X509V3_EXT_METHOD v3_nscert = {
.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 v3_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,
};
STACK_OF(CONF_VALUE) *
i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits,
STACK_OF(CONF_VALUE) *ret)
{
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;
}
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;
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;
}

397
externals/libressl/crypto/x509/x509_cmp.c vendored Executable file
View File

@@ -0,0 +1,397 @@
/* $OpenBSD: x509_cmp.c,v 1.35 2019/03/13 20:34:00 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 <ctype.h>
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.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));
}
#ifndef OPENSSL_NO_MD5
unsigned long
X509_issuer_and_serial_hash(X509 *a)
{
unsigned long ret = 0;
EVP_MD_CTX ctx;
unsigned char md[16];
char *f;
EVP_MD_CTX_init(&ctx);
f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
if (f == NULL)
goto err;
if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
goto err;
if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
goto err;
free(f);
f = NULL;
if (!EVP_DigestUpdate(&ctx,
(unsigned char *)a->cert_info->serialNumber->data,
(unsigned long)a->cert_info->serialNumber->length))
goto err;
if (!EVP_DigestFinal_ex(&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_cleanup(&ctx);
free(f);
return (ret);
}
#endif
int
X509_issuer_name_cmp(const X509 *a, const X509 *b)
{
return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
}
int
X509_subject_name_cmp(const X509 *a, const X509 *b)
{
return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
}
int
X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
{
return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
}
#ifndef OPENSSL_NO_SHA
int
X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
{
return memcmp(a->sha1_hash, b->sha1_hash, 20);
}
#endif
X509_NAME *
X509_get_issuer_name(const X509 *a)
{
return (a->cert_info->issuer);
}
unsigned long
X509_issuer_name_hash(X509 *x)
{
return (X509_NAME_hash(x->cert_info->issuer));
}
#ifndef OPENSSL_NO_MD5
unsigned long
X509_issuer_name_hash_old(X509 *x)
{
return (X509_NAME_hash_old(x->cert_info->issuer));
}
#endif
X509_NAME *
X509_get_subject_name(const X509 *a)
{
return (a->cert_info->subject);
}
ASN1_INTEGER *
X509_get_serialNumber(X509 *a)
{
return (a->cert_info->serialNumber);
}
const ASN1_INTEGER *
X509_get0_serialNumber(const X509 *a)
{
return (a->cert_info->serialNumber);
}
unsigned long
X509_subject_name_hash(X509 *x)
{
return (X509_NAME_hash(x->cert_info->subject));
}
#ifndef OPENSSL_NO_MD5
unsigned long
X509_subject_name_hash_old(X509 *x)
{
return (X509_NAME_hash_old(x->cert_info->subject));
}
#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->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
}
#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);
}
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);
}
#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];
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x, NULL);
EVP_MD_CTX_init(&md_ctx);
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_cleanup(&md_ctx);
return (ret);
}
#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);
}
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);
}
EVP_PKEY *
X509_get_pubkey(X509 *x)
{
if (x == NULL || x->cert_info == NULL)
return (NULL);
return (X509_PUBKEY_get(x->cert_info->key));
}
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));
}
ASN1_BIT_STRING *
X509_get0_pubkey_bitstr(const X509 *x)
{
if (!x)
return NULL;
return x->cert_info->key->public_key;
}
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;
}
/*
* 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;
}

570
externals/libressl/crypto/x509/x509_conf.c vendored Executable file
View File

@@ -0,0 +1,570 @@
/* $OpenBSD: x509_conf.c,v 1.1 2020/06/04 15:19:31 jsing 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 <ctype.h>
#include <stdio.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
static int v3_check_critical(const char **value);
static int v3_check_generic(const char **value);
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
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 char *conf_lhash_get_string(void *db, const char *section,
const char *value);
static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db,
const char *section);
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
int crit, void *ext_struc);
static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
long *ext_len);
/* CONF *conf: Config file */
/* char *name: Name */
/* char *value: Value */
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;
}
/* CONF *conf: Config file */
/* char *value: Value */
X509_EXTENSION *
X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_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(ext_nid),
value, crit, ext_type, ctx);
return do_ext_nconf(conf, ctx, ext_nid, crit, value);
}
/* CONF *conf: Config file */
/* char *value: Value */
static X509_EXTENSION *
do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit,
const char *value)
{
const X509V3_EXT_METHOD *method;
X509_EXTENSION *ext;
void *ext_struc;
if (ext_nid == NID_undef) {
X509V3error(X509V3_R_UNKNOWN_EXTENSION_NAME);
return NULL;
}
if (!(method = X509V3_EXT_get_nid(ext_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(ext_nid), value);
if (*value != '@')
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
return NULL;
}
ext_struc = method->v2i(method, ctx, nval);
if (*value != '@')
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
} else if (method->s2i) {
ext_struc = method->s2i(method, ctx, value);
} else if (method->r2i) {
if (!ctx->db || !ctx->db_meth) {
X509V3error(X509V3_R_NO_CONFIG_DATABASE);
return NULL;
}
ext_struc = method->r2i(method, ctx, value);
} else {
X509V3error(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
ERR_asprintf_error_data("name=%s", OBJ_nid2sn(ext_nid));
return NULL;
}
if (ext_struc == NULL)
return NULL;
ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
if (method->it)
ASN1_item_free(ext_struc, method->it);
else
method->ext_free(ext_struc);
return ext;
}
static X509_EXTENSION *
do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit,
void *ext_struc)
{
unsigned char *ext_der;
int ext_len;
ASN1_OCTET_STRING *ext_oct = NULL;
X509_EXTENSION *ext;
/* Convert internal representation to DER */
if (method->it) {
ext_der = NULL;
ext_len = ASN1_item_i2d(ext_struc, &ext_der,
method->it);
if (ext_len < 0)
goto merr;
} else {
unsigned char *p;
ext_len = method->i2d(ext_struc, NULL);
if (!(ext_der = malloc(ext_len)))
goto merr;
p = ext_der;
method->i2d(ext_struc, &p);
}
if (!(ext_oct = ASN1_OCTET_STRING_new()))
goto merr;
ext_oct->data = ext_der;
ext_oct->length = ext_len;
ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
if (!ext)
goto merr;
ASN1_OCTET_STRING_free(ext_oct);
return ext;
merr:
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 ext_nid, int crit, void *ext_struc)
{
const X509V3_EXT_METHOD *method;
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
X509V3error(X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
return do_ext_i2d(method, ext_nid, crit, ext_struc);
}
/* 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 *ext, 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 *extension = NULL;
if (!(obj = OBJ_txt2obj(ext, 0))) {
X509V3error(X509V3_R_EXTENSION_NAME_ERROR);
ERR_asprintf_error_data("name=%s", ext);
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())) {
X509V3error(ERR_R_MALLOC_FAILURE);
goto err;
}
oct->data = ext_der;
oct->length = ext_len;
ext_der = NULL;
extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
err:
ASN1_OBJECT_free(obj);
ASN1_OCTET_STRING_free(oct);
free(ext_der);
return extension;
}
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;
}
/* Convenience functions to add extensions to a certificate, CRL and request */
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);
}
/* Same as above but for a CRL */
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);
}
/* Add extensions to certificate request */
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;
}
/* Config database functions */
char *
X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section)
{
if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
X509V3error(X509V3_R_OPERATION_NOT_DEFINED);
return NULL;
}
return ctx->db_meth->get_string(ctx->db, name, section);
}
STACK_OF(CONF_VALUE) *
X509V3_get_section(X509V3_CTX *ctx, const char *section)
{
if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
X509V3error(X509V3_R_OPERATION_NOT_DEFINED);
return NULL;
}
return ctx->db_meth->get_section(ctx->db, section);
}
void
X509V3_string_free(X509V3_CTX *ctx, char *str)
{
if (!str)
return;
if (ctx->db_meth->free_string)
ctx->db_meth->free_string(ctx->db, str);
}
void
X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
{
if (!section)
return;
if (ctx->db_meth->free_section)
ctx->db_meth->free_section(ctx->db, section);
}
static char *
nconf_get_string(void *db, const char *section, const char *value)
{
return NCONF_get_string(db, section, value);
}
static STACK_OF(CONF_VALUE) *
nconf_get_section(void *db, const char *section)
{
return NCONF_get_section(db, section);
}
static X509V3_CONF_METHOD nconf_method = {
nconf_get_string,
nconf_get_section,
NULL,
NULL
};
void
X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
{
ctx->db_meth = &nconf_method;
ctx->db = conf;
}
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;
}
/* Old conf compatibility functions */
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);
}
/* LHASH *conf: Config file */
/* char *value: Value */
X509_EXTENSION *
X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid,
const char *value)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
}
static char *
conf_lhash_get_string(void *db, const char *section, const char *value)
{
return CONF_get_string(db, section, value);
}
static STACK_OF(CONF_VALUE) *
conf_lhash_get_section(void *db, const char *section)
{
return CONF_get_section(db, section);
}
static X509V3_CONF_METHOD conf_lhash_method = {
conf_lhash_get_string,
conf_lhash_get_section,
NULL,
NULL
};
void
X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
{
ctx->db_meth = &conf_lhash_method;
ctx->db = lhash;
}
int
X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
const char *section, X509 *cert)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
}
/* Same as above but for a CRL */
int
X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
const char *section, X509_CRL *crl)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
}
/* Add extensions to certificate request */
int
X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
const char *section, X509_REQ *req)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
}

File diff suppressed because it is too large Load Diff

763
externals/libressl/crypto/x509/x509_cpols.c vendored Executable file
View File

@@ -0,0 +1,763 @@
/* $OpenBSD: x509_cpols.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "pcy_int.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);
const X509V3_EXT_METHOD v3_cpols = {
.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,
};
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",
};
CERTIFICATEPOLICIES *
d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len)
{
return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&CERTIFICATEPOLICIES_it);
}
int
i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it);
}
CERTIFICATEPOLICIES *
CERTIFICATEPOLICIES_new(void)
{
return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it);
}
void
CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a)
{
ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it);
}
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",
};
POLICYINFO *
d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len)
{
return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&POLICYINFO_it);
}
int
i2d_POLICYINFO(POLICYINFO *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it);
}
POLICYINFO *
POLICYINFO_new(void)
{
return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it);
}
void
POLICYINFO_free(POLICYINFO *a)
{
ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it);
}
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),
.app_items = 0,
.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",
};
POLICYQUALINFO *
d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len)
{
return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&POLICYQUALINFO_it);
}
int
i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it);
}
POLICYQUALINFO *
POLICYQUALINFO_new(void)
{
return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it);
}
void
POLICYQUALINFO_free(POLICYQUALINFO *a)
{
ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it);
}
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",
};
USERNOTICE *
d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len)
{
return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&USERNOTICE_it);
}
int
i2d_USERNOTICE(USERNOTICE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it);
}
USERNOTICE *
USERNOTICE_new(void)
{
return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it);
}
void
USERNOTICE_free(USERNOTICE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it);
}
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",
};
NOTICEREF *
d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len)
{
return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&NOTICEREF_it);
}
int
i2d_NOTICEREF(NOTICEREF *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it);
}
NOTICEREF *
NOTICEREF_new(void)
{
return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it);
}
void
NOTICEREF_free(NOTICEREF *a)
{
ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it);
}
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_get_section(ctx, pstr + 1);
if (!polsect) {
X509V3error(X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
}
pol = policy_section(ctx, polsect, ia5org);
X509V3_section_free(ctx, polsect);
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_get_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);
X509V3_section_free(ctx, unot);
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_VISIBLESTRING_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->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->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->data);
}
void
X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
{
const X509_POLICY_DATA *dat = node->data;
BIO_printf(out, "%*sPolicy: ", indent, "");
i2a_ASN1_OBJECT(out, dat->valid_policy);
BIO_puts(out, "\n");
BIO_printf(out, "%*s%s\n", indent + 2, "",
node_data_critical(dat) ? "Critical" : "Non Critical");
if (dat->qualifier_set)
print_qualifiers(out, dat->qualifier_set, indent + 2);
else
BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
}

809
externals/libressl/crypto/x509/x509_crld.c vendored Executable file
View File

@@ -0,0 +1,809 @@
/* $OpenBSD: x509_crld.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_crld = {
.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 v3_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,
};
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_get_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 == '@')
X509V3_section_free(ctx, gnsect);
else
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_get_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);
X509V3_section_free(ctx, dnsect);
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, "<EMPTY>\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_get_section(ctx, cnf->name);
if (!dpsect)
goto err;
point = crldp_from_section(ctx, dpsect);
X509V3_section_free(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",
};
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);
}
int
i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it);
}
DIST_POINT_NAME *
DIST_POINT_NAME_new(void)
{
return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it);
}
void
DIST_POINT_NAME_free(DIST_POINT_NAME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it);
}
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",
};
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);
}
int
i2d_DIST_POINT(DIST_POINT *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it);
}
DIST_POINT *
DIST_POINT_new(void)
{
return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it);
}
void
DIST_POINT_free(DIST_POINT *a)
{
ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it);
}
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",
};
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);
}
int
i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it);
}
CRL_DIST_POINTS *
CRL_DIST_POINTS_new(void)
{
return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it);
}
void
CRL_DIST_POINTS_free(CRL_DIST_POINTS *a)
{
ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it);
}
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",
};
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);
}
int
i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it);
}
ISSUING_DIST_POINT *
ISSUING_DIST_POINT_new(void)
{
return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it);
}
void
ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it);
}
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);
const X509V3_EXT_METHOD v3_idp = {
NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
&ISSUING_DIST_POINT_it,
0, 0, 0, 0,
0, 0,
0,
v2i_idp,
i2r_idp, 0,
NULL
};
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<EMPTY>\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;
}

128
externals/libressl/crypto/x509/x509_d2.c vendored Executable file
View File

@@ -0,0 +1,128 @@
/* $OpenBSD: x509_d2.c,v 1.10 2015/01/22 09:06:39 reyk 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 <stdio.h>
#include <sys/uio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/x509.h>
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);
}
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);
}
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);
}

98
externals/libressl/crypto/x509/x509_def.c vendored Executable file
View File

@@ -0,0 +1,98 @@
/* $OpenBSD: x509_def.c,v 1.5 2014/06/12 15:49:31 deraadt 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 <stdio.h>
#include "cryptlib.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
const char *
X509_get_default_private_dir(void)
{
return (X509_PRIVATE_DIR);
}
const char *
X509_get_default_cert_area(void)
{
return (X509_CERT_AREA);
}
const char *
X509_get_default_cert_dir(void)
{
return (X509_CERT_DIR);
}
const char *
X509_get_default_cert_file(void)
{
return (X509_CERT_FILE);
}
const char *
X509_get_default_cert_dir_env(void)
{
return (X509_CERT_DIR_EVP);
}
const char *
X509_get_default_cert_file_env(void)
{
return (X509_CERT_FILE_EVP);
}

107
externals/libressl/crypto/x509/x509_enum.c vendored Executable file
View File

@@ -0,0 +1,107 @@
/* $OpenBSD: x509_enum.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/x509v3.h>
static ENUMERATED_NAMES 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}
};
const X509V3_EXT_METHOD v3_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,
};
char *
i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *e)
{
ENUMERATED_NAMES *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);
}

210
externals/libressl/crypto/x509/x509_err.c vendored Executable file
View File

@@ -0,0 +1,210 @@
/* $OpenBSD: x509_err.c,v 1.15 2020/06/05 16:51:12 jsing 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).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
/* BEGIN ERROR CODES */
#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 ERR_STRING_DATA X509_str_functs[] = {
{ERR_FUNC(0xfff), "CRYPTO_internal"},
{0, NULL}
};
static ERR_STRING_DATA X509V3_str_functs[] = {
{ERR_FUNC(0xfff), "CRYPTO_internal"},
{0, NULL}
};
static 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_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_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}
};
static 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_strings(0, X509_str_functs);
ERR_load_strings(0, X509_str_reasons);
}
#endif
}
void
ERR_load_X509V3_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) {
ERR_load_strings(0, X509V3_str_functs);
ERR_load_strings(0, X509V3_str_reasons);
}
#endif
}

233
externals/libressl/crypto/x509/x509_ext.c vendored Executable file
View File

@@ -0,0 +1,233 @@
/* $OpenBSD: x509_ext.c,v 1.12 2018/05/18 19:28:27 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int
X509_CRL_get_ext_count(const X509_CRL *x)
{
return (X509v3_get_ext_count(x->crl->extensions));
}
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));
}
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));
}
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));
}
X509_EXTENSION *
X509_CRL_get_ext(const X509_CRL *x, int loc)
{
return (X509v3_get_ext(x->crl->extensions, loc));
}
X509_EXTENSION *
X509_CRL_delete_ext(X509_CRL *x, int loc)
{
return (X509v3_delete_ext(x->crl->extensions, loc));
}
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);
}
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);
}
int
X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
{
return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL);
}
int
X509_get_ext_count(const X509 *x)
{
return (X509v3_get_ext_count(x->cert_info->extensions));
}
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));
}
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));
}
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));
}
X509_EXTENSION *
X509_get_ext(const X509 *x, int loc)
{
return (X509v3_get_ext(x->cert_info->extensions, loc));
}
X509_EXTENSION *
X509_delete_ext(X509 *x, int loc)
{
return (X509v3_delete_ext(x->cert_info->extensions, loc));
}
int
X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
{
return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL);
}
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);
}
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);
}
int
X509_REVOKED_get_ext_count(const X509_REVOKED *x)
{
return (X509v3_get_ext_count(x->extensions));
}
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));
}
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));
}
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));
}
X509_EXTENSION *
X509_REVOKED_get_ext(const X509_REVOKED *x, int loc)
{
return (X509v3_get_ext(x->extensions, loc));
}
X509_EXTENSION *
X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
{
return (X509v3_delete_ext(x->extensions, loc));
}
int
X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
{
return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
}
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);
}
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);
}

217
externals/libressl/crypto/x509/x509_extku.c vendored Executable file
View File

@@ -0,0 +1,217 @@
/* $OpenBSD: x509_extku.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_ext_ku = {
.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,
};
/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
const X509V3_EXT_METHOD v3_ocsp_accresp = {
.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,
};
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",
};
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);
}
int
i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &EXTENDED_KEY_USAGE_it);
}
EXTENDED_KEY_USAGE *
EXTENDED_KEY_USAGE_new(void)
{
return (EXTENDED_KEY_USAGE *)ASN1_item_new(&EXTENDED_KEY_USAGE_it);
}
void
EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &EXTENDED_KEY_USAGE_it);
}
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;
}

474
externals/libressl/crypto/x509/x509_genn.c vendored Executable file
View File

@@ -0,0 +1,474 @@
/* $OpenBSD: x509_genn.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
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",
};
OTHERNAME *
d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len)
{
return (OTHERNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&OTHERNAME_it);
}
int
i2d_OTHERNAME(OTHERNAME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it);
}
OTHERNAME *
OTHERNAME_new(void)
{
return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it);
}
void
OTHERNAME_free(OTHERNAME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it);
}
static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = {
{
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(EDIPARTYNAME, nameAssigner),
.field_name = "nameAssigner",
.item = &DIRECTORYSTRING_it,
},
{
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
.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",
};
EDIPARTYNAME *
d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len)
{
return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&EDIPARTYNAME_it);
}
int
i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it);
}
EDIPARTYNAME *
EDIPARTYNAME_new(void)
{
return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it);
}
void
EDIPARTYNAME_free(EDIPARTYNAME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it);
}
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",
};
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);
}
int
i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it);
}
GENERAL_NAME *
GENERAL_NAME_new(void)
{
return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it);
}
void
GENERAL_NAME_free(GENERAL_NAME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it);
}
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",
};
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);
}
int
i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it);
}
GENERAL_NAMES *
GENERAL_NAMES_new(void)
{
return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it);
}
void
GENERAL_NAMES_free(GENERAL_NAMES *a)
{
ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it);
}
GENERAL_NAME *
GENERAL_NAME_dup(GENERAL_NAME *a)
{
return ASN1_item_dup(&GENERAL_NAME_it, a);
}
/* 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:
case GEN_EDIPARTY:
result = ASN1_TYPE_cmp(a->d.other, b->d.other);
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;
}
/* 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;
}
void
GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
{
switch (type) {
case GEN_X400:
case GEN_EDIPARTY:
a->d.other = 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;
}
void *
GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
{
if (ptype)
*ptype = a->type;
switch (a->type) {
case GEN_X400:
case GEN_EDIPARTY:
return a->d.other;
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;
}
}
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;
}
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;
}

238
externals/libressl/crypto/x509/x509_ia5.c vendored Executable file
View File

@@ -0,0 +1,238 @@
/* $OpenBSD: x509_ia5.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
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);
const X509V3_EXT_METHOD v3_ns_ia5_list[] = {
{
.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,
},
{
.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,
},
{
.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,
},
{
.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,
},
{
.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,
},
{
.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,
},
{
.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,
},
{
.ext_nid = -1,
.ext_flags = 0,
.it = NULL,
.ext_new = NULL,
.ext_free = NULL,
.d2i = NULL,
.i2d = NULL,
.i2s = NULL,
.s2i = NULL,
.i2v = NULL,
.v2i = NULL,
.i2r = NULL,
.r2i = NULL,
.usr_data = NULL,
},
};
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;
}

308
externals/libressl/crypto/x509/x509_info.c vendored Executable file
View File

@@ -0,0 +1,308 @@
/* $OpenBSD: x509_info.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
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);
const X509V3_EXT_METHOD v3_info = {
.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 v3_sinfo = {
.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,
};
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",
};
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);
}
int
i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ACCESS_DESCRIPTION_it);
}
ACCESS_DESCRIPTION *
ACCESS_DESCRIPTION_new(void)
{
return (ACCESS_DESCRIPTION *)ASN1_item_new(&ACCESS_DESCRIPTION_it);
}
void
ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ACCESS_DESCRIPTION_it);
}
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",
};
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);
}
int
i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_INFO_ACCESS_it);
}
AUTHORITY_INFO_ACCESS *
AUTHORITY_INFO_ACCESS_new(void)
{
return (AUTHORITY_INFO_ACCESS *)ASN1_item_new(&AUTHORITY_INFO_ACCESS_it);
}
void
AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a)
{
ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_INFO_ACCESS_it);
}
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;
}

110
externals/libressl/crypto/x509/x509_int.c vendored Executable file
View File

@@ -0,0 +1,110 @@
/* $OpenBSD: x509_int.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <openssl/x509v3.h>
const X509V3_EXT_METHOD v3_crl_num = {
.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 v3_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,
};
static void *
s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
{
return s2i_ASN1_INTEGER(meth, value);
}
const X509V3_EXT_METHOD v3_inhibit_anyp = {
NID_inhibit_any_policy, 0, &ASN1_INTEGER_it,
0, 0, 0, 0,
(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
(X509V3_EXT_S2I)s2i_asn1_int,
0, 0, 0, 0,
NULL
};

128
externals/libressl/crypto/x509/x509_internal.h vendored Executable file
View File

@@ -0,0 +1,128 @@
/* $OpenBSD: x509_internal.h,v 1.3 2020/09/15 11:55:14 beck Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
* 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 <netinet/in.h>
#include <openssl/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_len;
size_t names_count;
};
struct x509_verify_chain {
STACK_OF(X509) *certs; /* Kept in chain order, includes leaf */
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 */
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);
void x509v3_cache_extensions(X509 *x);
int x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm,
int notafter);
struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc,
STACK_OF(X509) *roots);
void x509_constraints_name_clear(struct x509_constraints_name *name);
int x509_constraints_names_add(struct x509_constraints_names *names,
struct x509_constraints_name *name);
struct x509_constraints_names *x509_constraints_names_dup(
struct x509_constraints_names *names);
void x509_constraints_names_clear(struct x509_constraints_names *names);
struct x509_constraints_names *x509_constraints_names_new(void);
void x509_constraints_names_free(struct x509_constraints_names *names);
int x509_constraints_valid_host(uint8_t *name, size_t len);
int x509_constraints_valid_sandns(uint8_t *name, size_t len);
int x509_constraints_domain(char *domain, size_t dlen, char *constraint,
size_t len);
int x509_constraints_parse_mailbox(uint8_t *candidate, size_t len,
struct x509_constraints_name *name);
int x509_constraints_valid_domain_constraint(uint8_t *constraint,
size_t len);
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_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);
__END_HIDDEN_DECLS
#endif

View File

@@ -0,0 +1,167 @@
/* $OpenBSD: x509_issuer_cache.c,v 1.1 2020/09/11 14:30:51 beck Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
* 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 <pthread.h>
#include <string.h>
#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;
}
/*
* 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) {
struct x509_issuer *old;
if ((old = TAILQ_LAST(&x509_issuer_lru, lruqueue)) == NULL)
goto err;
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--;
}
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;
}
err:
(void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
if (new != NULL) {
free(new->parent_md);
free(new->child_md);
}
free(new);
return;
}

View File

@@ -0,0 +1,47 @@
/* $OpenBSD: x509_issuer_cache.h,v 1.1 2020/09/11 14:30:51 beck Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
* 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 <sys/tree.h>
#include <sys/queue.h>
#include <openssl/x509.h>
__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);
__END_HIDDEN_DECLS
#endif

63
externals/libressl/crypto/x509/x509_lcl.h vendored Executable file
View File

@@ -0,0 +1,63 @@
/* x509_lcl.h */
/* 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).
*
*/
__BEGIN_HIDDEN_DECLS
int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet);
__END_HIDDEN_DECLS

362
externals/libressl/crypto/x509/x509_lib.c vendored Executable file
View File

@@ -0,0 +1,362 @@
/* $OpenBSD: x509_lib.c,v 1.2 2020/09/14 11:35:32 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).
*
*/
/* X509 v3 extension utilities */
#include <stdio.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "ext_dat.h"
static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
static int ext_cmp(const X509V3_EXT_METHOD * const *a,
const X509V3_EXT_METHOD * const *b);
static void ext_list_free(X509V3_EXT_METHOD *ext);
int
X509V3_EXT_add(X509V3_EXT_METHOD *ext)
{
if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
static int
ext_cmp(const X509V3_EXT_METHOD * const *a, const X509V3_EXT_METHOD * const *b)
{
return ((*a)->ext_nid - (*b)->ext_nid);
}
static int ext_cmp_BSEARCH_CMP_FN(const void *, const void *);
static int ext_cmp(const X509V3_EXT_METHOD * const *, const X509V3_EXT_METHOD * const *);
static const X509V3_EXT_METHOD * *OBJ_bsearch_ext(const X509V3_EXT_METHOD * *key, const X509V3_EXT_METHOD * const *base, int num);
static int
ext_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
{
const X509V3_EXT_METHOD * const *a = a_;
const X509V3_EXT_METHOD * const *b = b_;
return ext_cmp(a, b);
}
static const X509V3_EXT_METHOD **
OBJ_bsearch_ext(const X509V3_EXT_METHOD **key,
const X509V3_EXT_METHOD *const *base, int num)
{
return (const X509V3_EXT_METHOD **)OBJ_bsearch_(key, base, num,
sizeof(const X509V3_EXT_METHOD *), ext_cmp_BSEARCH_CMP_FN);
}
const X509V3_EXT_METHOD *
X509V3_EXT_get_nid(int nid)
{
X509V3_EXT_METHOD tmp;
const X509V3_EXT_METHOD *t = &tmp, * const *ret;
int idx;
if (nid < 0)
return NULL;
tmp.ext_nid = nid;
ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
if (ret)
return *ret;
if (!ext_list)
return NULL;
idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
if (idx == -1)
return NULL;
return sk_X509V3_EXT_METHOD_value(ext_list, idx);
}
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);
}
int
X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
{
for (; extlist->ext_nid!=-1; extlist++)
if (!X509V3_EXT_add(extlist))
return 0;
return 1;
}
int
X509V3_EXT_add_alias(int nid_to, int nid_from)
{
const X509V3_EXT_METHOD *ext;
X509V3_EXT_METHOD *tmpext;
if (!(ext = X509V3_EXT_get_nid(nid_from))) {
X509V3error(X509V3_R_EXTENSION_NOT_FOUND);
return 0;
}
if (!(tmpext = malloc(sizeof(X509V3_EXT_METHOD)))) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
*tmpext = *ext;
tmpext->ext_nid = nid_to;
tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
if (!X509V3_EXT_add(tmpext)) {
free(tmpext);
return 0;
}
return 1;
}
void
X509V3_EXT_cleanup(void)
{
sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
ext_list = NULL;
}
static void
ext_list_free(X509V3_EXT_METHOD *ext)
{
if (ext->ext_flags & X509V3_EXT_DYNAMIC)
free(ext);
}
/* Legacy function: we don't need to add standard extensions
* any more because they are now kept in ext_dat.h.
*/
int
X509V3_add_standard_extensions(void)
{
return 1;
}
/* 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)))
return NULL;
p = ext->value->data;
if (method->it)
return ASN1_item_d2i(NULL, &p, ext->value->length,
method->it);
return method->d2i(NULL, &p, ext->value->length);
}
/* Get critical flag and decoded version of extension from a NID.
* The "idx" variable returns the last found extension and can
* be used to retrieve multiple extensions of the same NID.
* However multiple extensions with the same NID is usually
* due to a badly encoded certificate so if idx is NULL we
* choke if multiple extensions exist.
* The "crit" variable is set to the critical value.
* The return value is the decoded extension or NULL on
* error. The actual error can have several different causes,
* the value of *crit reflects the cause:
* >= 0, extension found but not decoded (reflects critical value).
* -1 extension not found.
* -2 extension occurs more than once.
*/
void *
X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
{
int lastpos, i;
X509_EXTENSION *ex, *found_ex = NULL;
if (!x) {
if (idx)
*idx = -1;
if (crit)
*crit = -1;
return NULL;
}
if (idx)
lastpos = *idx + 1;
else
lastpos = 0;
if (lastpos < 0)
lastpos = 0;
for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
ex = sk_X509_EXTENSION_value(x, i);
if (OBJ_obj2nid(ex->object) == nid) {
if (idx) {
*idx = i;
found_ex = ex;
break;
} else if (found_ex) {
/* Found more than one */
if (crit)
*crit = -2;
return NULL;
}
found_ex = ex;
}
}
if (found_ex) {
/* Found it */
if (crit)
*crit = X509_EXTENSION_get_critical(found_ex);
return X509V3_EXT_d2i(found_ex);
}
/* Extension not found */
if (idx)
*idx = -1;
if (crit)
*crit = -1;
return NULL;
}
/* This function is a general extension append, replace and delete utility.
* The precise operation is governed by the 'flags' value. The 'crit' and
* 'value' arguments (if relevant) are the extensions internal structure.
*/
int
X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
int crit, unsigned long flags)
{
int extidx = -1;
int errcode;
X509_EXTENSION *ext, *extmp;
unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
/* If appending we don't care if it exists, otherwise
* look for existing extension.
*/
if (ext_op != X509V3_ADD_APPEND)
extidx = X509v3_get_ext_by_NID(*x, nid, -1);
/* See if extension exists */
if (extidx >= 0) {
/* If keep existing, nothing to do */
if (ext_op == X509V3_ADD_KEEP_EXISTING)
return 1;
/* If default then its an error */
if (ext_op == X509V3_ADD_DEFAULT) {
errcode = X509V3_R_EXTENSION_EXISTS;
goto err;
}
/* If delete, just delete it */
if (ext_op == X509V3_ADD_DELETE) {
if (!sk_X509_EXTENSION_delete(*x, extidx))
return -1;
return 1;
}
} else {
/* If replace existing or delete, error since
* extension must exist
*/
if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
(ext_op == X509V3_ADD_DELETE)) {
errcode = X509V3_R_EXTENSION_NOT_FOUND;
goto err;
}
}
/* If we get this far then we have to create an extension:
* could have some flags for alternative encoding schemes...
*/
ext = X509V3_EXT_i2d(nid, crit, value);
if (!ext) {
X509V3error(X509V3_R_ERROR_CREATING_EXTENSION);
return 0;
}
/* If extension exists replace it.. */
if (extidx >= 0) {
extmp = sk_X509_EXTENSION_value(*x, extidx);
X509_EXTENSION_free(extmp);
if (!sk_X509_EXTENSION_set(*x, extidx, ext))
return -1;
return 1;
}
if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
return -1;
if (!sk_X509_EXTENSION_push(*x, ext))
return -1;
return 1;
err:
if (!(flags & X509V3_ADD_SILENT))
X509V3error(errcode);
return 0;
}

815
externals/libressl/crypto/x509/x509_lu.c vendored Executable file
View File

@@ -0,0 +1,815 @@
/* $OpenBSD: x509_lu.c,v 1.30 2018/08/24 19:21:09 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 <stdio.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static void X509_OBJECT_dec_ref_count(X509_OBJECT *a);
X509_LOOKUP *
X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
{
X509_LOOKUP *ret;
ret = malloc(sizeof(X509_LOOKUP));
if (ret == NULL)
return NULL;
ret->init = 0;
ret->skip = 0;
ret->method = method;
ret->method_data = NULL;
ret->store_ctx = NULL;
if ((method->new_item != NULL) && !method->new_item(ret)) {
free(ret);
return NULL;
}
return ret;
}
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);
}
int
X509_LOOKUP_init(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
return 0;
if (ctx->method->init != NULL)
return ctx->method->init(ctx);
else
return 1;
}
int
X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
return 0;
if (ctx->method->shutdown != NULL)
return ctx->method->shutdown(ctx);
else
return 1;
}
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 ctx->method->ctrl(ctx, cmd, argc, argl, ret);
else
return 1;
}
int
X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
return X509_LU_FAIL;
if (ctx->skip)
return 0;
return ctx->method->get_by_subject(ctx, type, name, ret);
}
int
X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
ASN1_INTEGER *serial, X509_OBJECT *ret)
{
if ((ctx->method == NULL) ||
(ctx->method->get_by_issuer_serial == NULL))
return X509_LU_FAIL;
return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
}
int
X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
const unsigned char *bytes, int len, X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
return X509_LU_FAIL;
return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
}
int
X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, const char *str, int len,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
return X509_LU_FAIL;
return ctx->method->get_by_alias(ctx, type, str, len, ret);
}
static int
x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
{
int ret;
ret = ((*a)->type - (*b)->type);
if (ret)
return ret;
switch ((*a)->type) {
case X509_LU_X509:
ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
break;
case X509_LU_CRL:
ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
break;
default:
/* abort(); */
return 0;
}
return ret;
}
X509_STORE *
X509_STORE_new(void)
{
X509_STORE *ret;
if ((ret = malloc(sizeof(X509_STORE))) == NULL)
return NULL;
ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
ret->cache = 1;
ret->get_cert_methods = sk_X509_LOOKUP_new_null();
ret->verify = 0;
ret->verify_cb = 0;
if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
goto err;
ret->get_issuer = 0;
ret->check_issued = 0;
ret->check_revocation = 0;
ret->get_crl = 0;
ret->check_crl = 0;
ret->cert_crl = 0;
ret->lookup_certs = 0;
ret->lookup_crls = 0;
ret->cleanup = 0;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
goto err;
ret->references = 1;
return ret;
err:
X509_VERIFY_PARAM_free(ret->param);
sk_X509_LOOKUP_free(ret->get_cert_methods);
sk_X509_OBJECT_free(ret->objs);
free(ret);
return NULL;
}
static void
X509_OBJECT_free(X509_OBJECT *a)
{
X509_OBJECT_free_contents(a);
free(a);
}
void
X509_STORE_free(X509_STORE *vfy)
{
int i;
STACK_OF(X509_LOOKUP) *sk;
X509_LOOKUP *lu;
if (vfy == NULL)
return;
i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);
if (i > 0)
return;
sk = vfy->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
lu = sk_X509_LOOKUP_value(sk, i);
X509_LOOKUP_shutdown(lu);
X509_LOOKUP_free(lu);
}
sk_X509_LOOKUP_free(sk);
sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
X509_VERIFY_PARAM_free(vfy->param);
free(vfy);
}
int
X509_STORE_up_ref(X509_STORE *x)
{
int refs = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_STORE);
return (refs > 1) ? 1 : 0;
}
X509_LOOKUP *
X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
{
int i;
STACK_OF(X509_LOOKUP) *sk;
X509_LOOKUP *lu;
sk = v->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
lu = sk_X509_LOOKUP_value(sk, i);
if (m == lu->method) {
return lu;
}
}
/* a new one */
lu = X509_LOOKUP_new(m);
if (lu == NULL)
return NULL;
else {
lu->store_ctx = v;
if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
return lu;
else {
X509_LOOKUP_free(lu);
return NULL;
}
}
}
int
X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
X509_OBJECT *ret)
{
X509_STORE *ctx = vs->ctx;
X509_LOOKUP *lu;
X509_OBJECT stmp, *tmp;
int i, j;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (tmp == NULL || type == X509_LU_CRL) {
for (i = vs->current_method;
i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
if (j < 0) {
vs->current_method = j;
return j;
} else if (j) {
tmp = &stmp;
break;
}
}
vs->current_method = 0;
if (tmp == NULL)
return 0;
}
/* if (ret->data.ptr != NULL)
X509_OBJECT_free_contents(ret); */
ret->type = tmp->type;
ret->data.ptr = tmp->data.ptr;
X509_OBJECT_up_ref_count(ret);
return 1;
}
int
X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
{
X509_OBJECT *obj;
int ret = 1;
if (x == NULL)
return 0;
obj = malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type = X509_LU_X509;
obj->data.x509 = x;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_up_ref_count(obj);
if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
X509error(X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
} else {
if (sk_X509_OBJECT_push(ctx->objs, obj) == 0) {
X509error(ERR_R_MALLOC_FAILURE);
ret = 0;
}
}
if (ret == 0)
X509_OBJECT_dec_ref_count(obj);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (ret == 0) {
obj->data.x509 = NULL; /* owned by the caller */
X509_OBJECT_free(obj);
}
return ret;
}
int
X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
{
X509_OBJECT *obj;
int ret = 1;
if (x == NULL)
return 0;
obj = malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type = X509_LU_CRL;
obj->data.crl = x;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_up_ref_count(obj);
if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
X509error(X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
} else {
if (sk_X509_OBJECT_push(ctx->objs, obj) == 0) {
X509error(ERR_R_MALLOC_FAILURE);
ret = 0;
}
}
if (ret == 0)
X509_OBJECT_dec_ref_count(obj);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (ret == 0) {
obj->data.crl = NULL; /* owned by the caller */
X509_OBJECT_free(obj);
}
return ret;
}
static void
X509_OBJECT_dec_ref_count(X509_OBJECT *a)
{
switch (a->type) {
case X509_LU_X509:
CRYPTO_add(&a->data.x509->references, -1, CRYPTO_LOCK_X509);
break;
case X509_LU_CRL:
CRYPTO_add(&a->data.crl->references, -1, CRYPTO_LOCK_X509_CRL);
break;
}
}
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;
}
int
X509_OBJECT_get_type(const X509_OBJECT *a)
{
return a->type;
}
void
X509_OBJECT_free_contents(X509_OBJECT *a)
{
switch (a->type) {
case X509_LU_X509:
X509_free(a->data.x509);
break;
case X509_LU_CRL:
X509_CRL_free(a->data.crl);
break;
}
}
static int
x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name,
int *pnmatch)
{
X509_OBJECT 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:
/* abort(); */
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, int type, X509_NAME *name)
{
return x509_object_idx_cnt(h, type, name, NULL);
}
X509_OBJECT *
X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
X509_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);
}
X509 *
X509_OBJECT_get0_X509(const X509_OBJECT *xo)
{
if (xo != NULL && xo->type == X509_LU_X509)
return xo->data.x509;
return NULL;
}
X509_CRL *
X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo)
{
if (xo != NULL && xo->type == X509_LU_CRL)
return xo->data.crl;
return NULL;
}
STACK_OF(X509) *
X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
{
int i, idx, cnt;
STACK_OF(X509) *sk;
X509 *x;
X509_OBJECT *obj;
sk = sk_X509_new_null();
if (sk == NULL)
return NULL;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0) {
/* Nothing found in cache: do lookup to possibly add new
* objects to cache
*/
X509_OBJECT xobj;
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
sk_X509_free(sk);
return NULL;
}
X509_OBJECT_free_contents(&xobj);
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = x509_object_idx_cnt(ctx->ctx->objs,
X509_LU_X509, nm, &cnt);
if (idx < 0) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
sk_X509_free(sk);
return NULL;
}
}
for (i = 0; i < cnt; i++, idx++) {
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.x509;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
if (!sk_X509_push(sk, x)) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_free(x);
sk_X509_pop_free(sk, X509_free);
return NULL;
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return sk;
}
STACK_OF(X509_CRL) *
X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
{
int i, idx, cnt;
STACK_OF(X509_CRL) *sk;
X509_CRL *x;
X509_OBJECT *obj, xobj;
sk = sk_X509_CRL_new_null();
if (sk == NULL)
return NULL;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
/* Check cache first */
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
/* Always do lookup to possibly add new CRLs to cache
*/
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
sk_X509_CRL_free(sk);
return NULL;
}
X509_OBJECT_free_contents(&xobj);
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
if (idx < 0) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
sk_X509_CRL_free(sk);
return NULL;
}
for (i = 0; i < cnt; i++, idx++) {
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.crl;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
if (!sk_X509_CRL_push(sk, x)) {
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_CRL_free(x);
sk_X509_CRL_pop_free(sk, X509_CRL_free);
return NULL;
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return sk;
}
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;
}
/* 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 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
X509_NAME *xn;
X509_OBJECT obj, *pobj;
int i, ok, idx, ret;
*issuer = NULL;
xn = X509_get_issuer_name(x);
ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
if (ok != X509_LU_X509) {
if (ok == X509_LU_RETRY) {
X509_OBJECT_free_contents(&obj);
X509error(X509_R_SHOULD_RETRY);
return -1;
} else if (ok != X509_LU_FAIL) {
X509_OBJECT_free_contents(&obj);
/* not good :-(, break anyway */
return -1;
}
return 0;
}
/* If certificate matches all OK */
if (ctx->check_issued(ctx, x, obj.data.x509)) {
if (x509_check_cert_time(ctx, obj.data.x509, 1)) {
*issuer = obj.data.x509;
return 1;
}
}
X509_OBJECT_free_contents(&obj);
/* Else find index of first cert accepted by 'check_issued' */
ret = 0;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
if (idx != -1) /* should be true as we've had at least one match */ {
/* Look through all matching certs for suitable issuer */
for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
/* 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;
ret = 1;
/*
* 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;
}
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (*issuer)
CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
return ret;
}
STACK_OF(X509_OBJECT) *
X509_STORE_get0_objects(X509_STORE *xs)
{
return xs->objs;
}
void *
X509_STORE_get_ex_data(X509_STORE *xs, int idx)
{
return CRYPTO_get_ex_data(&xs->ex_data, idx);
}
int
X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data)
{
return CRYPTO_set_ex_data(&xs->ex_data, idx, data);
}
int
X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
{
return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
}
int
X509_STORE_set_depth(X509_STORE *ctx, int depth)
{
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
return 1;
}
int
X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
{
return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
}
int
X509_STORE_set_trust(X509_STORE *ctx, int trust)
{
return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
}
int
X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
{
return X509_VERIFY_PARAM_set1(ctx->param, param);
}
X509_VERIFY_PARAM *
X509_STORE_get0_param(X509_STORE *ctx)
{
return ctx->param;
}
void
X509_STORE_set_verify_cb(X509_STORE *ctx,
int (*verify_cb)(int, X509_STORE_CTX *))
{
ctx->verify_cb = verify_cb;
}

554
externals/libressl/crypto/x509/x509_ncons.c vendored Executable file
View File

@@ -0,0 +1,554 @@
/* $OpenBSD: x509_ncons.c,v 1.4 2020/09/16 18:12:06 beck 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 <stdio.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_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,
};
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",
};
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",
};
GENERAL_SUBTREE *
GENERAL_SUBTREE_new(void)
{
return (GENERAL_SUBTREE*)ASN1_item_new(&GENERAL_SUBTREE_it);
}
void
GENERAL_SUBTREE_free(GENERAL_SUBTREE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &GENERAL_SUBTREE_it);
}
NAME_CONSTRAINTS *
NAME_CONSTRAINTS_new(void)
{
return (NAME_CONSTRAINTS*)ASN1_item_new(&NAME_CONSTRAINTS_it);
}
void
NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a)
{
ASN1_item_free((ASN1_VALUE *)a, &NAME_CONSTRAINTS_it);
}
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:<invalid>");
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;
}
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: inital '.' 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: inital '.' 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;
}

179
externals/libressl/crypto/x509/x509_obj.c vendored Executable file
View File

@@ -0,0 +1,179 @@
/* $OpenBSD: x509_obj.c,v 1.18 2018/05/18 18:19:31 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 <stdio.h>
#include <string.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
char *
X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
{
X509_NAME_ENTRY *ne;
int i;
int n, lold, l, l1, l2, num, j, type;
const char *s;
char *p;
unsigned char *q;
BUF_MEM *b = NULL;
static const char hex[17] = "0123456789ABCDEF";
int gs_doit[4];
char tmp_buf[80];
if (buf == NULL) {
if ((b = BUF_MEM_new()) == NULL)
goto err;
if (!BUF_MEM_grow(b, 200))
goto err;
b->data[0] = '\0';
len = 200;
}
if (a == NULL) {
if (b) {
buf = b->data;
free(b);
}
strlcpy(buf, "NO X509_NAME", len);
return buf;
}
len--; /* space for '\0' */
l = 0;
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
ne = sk_X509_NAME_ENTRY_value(a->entries, i);
n = OBJ_obj2nid(ne->object);
if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
s = tmp_buf;
}
l1 = strlen(s);
type = ne->value->type;
num = ne->value->length;
q = ne->value->data;
if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
for (j = 0; j < num; j++)
if (q[j] != 0)
gs_doit[j & 3] = 1;
if (gs_doit[0]|gs_doit[1]|gs_doit[2])
gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
else {
gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
gs_doit[3] = 1;
}
} else
gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
for (l2 = j=0; j < num; j++) {
if (!gs_doit[j&3])
continue;
l2++;
if ((q[j] < ' ') || (q[j] > '~'))
l2 += 3;
}
lold = l;
l += 1 + l1 + 1 + l2;
if (b != NULL) {
if (!BUF_MEM_grow(b, l + 1))
goto err;
p = &(b->data[lold]);
} else if (l > len) {
break;
} else
p = &(buf[lold]);
*(p++) = '/';
memcpy(p, s, l1);
p += l1;
*(p++) = '=';
q = ne->value->data;
for (j = 0; j < num; j++) {
if (!gs_doit[j & 3])
continue;
n = q[j];
if ((n < ' ') || (n > '~')) {
*(p++) = '\\';
*(p++) = 'x';
*(p++) = hex[(n >> 4) & 0x0f];
*(p++) = hex[n & 0x0f];
} else
*(p++) = n;
}
*p = '\0';
}
if (b != NULL) {
p = b->data;
free(b);
} else
p = buf;
if (i == 0)
*p = '\0';
return (p);
err:
X509error(ERR_R_MALLOC_FAILURE);
if (b != NULL)
BUF_MEM_free(b);
return (NULL);
}

380
externals/libressl/crypto/x509/x509_ocsp.c vendored Executable file
View File

@@ -0,0 +1,380 @@
/* $OpenBSD: x509_ocsp.c,v 1.1 2020/06/04 15:19:31 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_OCSP
#include <openssl/asn1.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/ocsp.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_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 v3_ocsp_acutoff = {
.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 v3_crl_invdate = {
.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 v3_crl_hold = {
.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 v3_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 v3_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 v3_ocsp_serviceloc = {
.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,
};
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

310
externals/libressl/crypto/x509/x509_pci.c vendored Executable file
View File

@@ -0,0 +1,310 @@
/* $OpenBSD: x509_pci.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
/* Contributed to the OpenSSL Project 2004
* by Richard Levitte (richard@levitte.org)
*/
/* Copyright (c) 2004 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.
*/
#include <stdio.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
BIO *out, int indent);
static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, char *str);
const X509V3_EXT_METHOD v3_pci = {
.ext_nid = NID_proxyCertInfo,
.ext_flags = 0,
.it = &PROXY_CERT_INFO_EXTENSION_it,
.ext_new = NULL,
.ext_free = NULL,
.d2i = NULL,
.i2d = NULL,
.i2s = NULL,
.s2i = NULL,
.i2v = NULL,
.v2i = NULL,
.i2r = (X509V3_EXT_I2R)i2r_pci,
.r2i = (X509V3_EXT_R2I)r2i_pci,
.usr_data = NULL,
};
static int
i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, BIO *out,
int indent)
{
BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
if (pci->pcPathLengthConstraint)
i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
else
BIO_printf(out, "infinite");
BIO_puts(out, "\n");
BIO_printf(out, "%*sPolicy Language: ", indent, "");
i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
BIO_puts(out, "\n");
if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
pci->proxyPolicy->policy->data);
return 1;
}
static int
process_pci_value(CONF_VALUE *val, ASN1_OBJECT **language,
ASN1_INTEGER **pathlen, ASN1_OCTET_STRING **policy)
{
int free_policy = 0;
if (strcmp(val->name, "language") == 0) {
if (*language) {
X509V3error(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
X509V3_conf_err(val);
return 0;
}
if (!(*language = OBJ_txt2obj(val->value, 0))) {
X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return 0;
}
}
else if (strcmp(val->name, "pathlen") == 0) {
if (*pathlen) {
X509V3error(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
X509V3_conf_err(val);
return 0;
}
if (!X509V3_get_value_int(val, pathlen)) {
X509V3error(X509V3_R_POLICY_PATH_LENGTH);
X509V3_conf_err(val);
return 0;
}
}
else if (strcmp(val->name, "policy") == 0) {
unsigned char *tmp_data = NULL;
long val_len;
if (!*policy) {
*policy = ASN1_OCTET_STRING_new();
if (!*policy) {
X509V3error(ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
return 0;
}
free_policy = 1;
}
if (strncmp(val->value, "hex:", 4) == 0) {
unsigned char *tmp_data2 =
string_to_hex(val->value + 4, &val_len);
if (!tmp_data2) {
X509V3error(X509V3_R_ILLEGAL_HEX_DIGIT);
X509V3_conf_err(val);
goto err;
}
tmp_data = realloc((*policy)->data,
(*policy)->length + val_len + 1);
if (tmp_data) {
(*policy)->data = tmp_data;
memcpy(&(*policy)->data[(*policy)->length],
tmp_data2, val_len);
(*policy)->length += val_len;
(*policy)->data[(*policy)->length] = '\0';
} else {
free(tmp_data2);
free((*policy)->data);
(*policy)->data = NULL;
(*policy)->length = 0;
X509V3error(ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
free(tmp_data2);
}
else if (strncmp(val->value, "file:", 5) == 0) {
unsigned char buf[2048];
int n;
BIO *b = BIO_new_file(val->value + 5, "r");
if (!b) {
X509V3error(ERR_R_BIO_LIB);
X509V3_conf_err(val);
goto err;
}
while ((n = BIO_read(b, buf, sizeof(buf))) > 0 ||
(n == 0 && BIO_should_retry(b))) {
if (!n)
continue;
tmp_data = realloc((*policy)->data,
(*policy)->length + n + 1);
if (!tmp_data)
break;
(*policy)->data = tmp_data;
memcpy(&(*policy)->data[(*policy)->length],
buf, n);
(*policy)->length += n;
(*policy)->data[(*policy)->length] = '\0';
}
BIO_free_all(b);
if (n < 0) {
X509V3error(ERR_R_BIO_LIB);
X509V3_conf_err(val);
goto err;
}
}
else if (strncmp(val->value, "text:", 5) == 0) {
val_len = strlen(val->value + 5);
tmp_data = realloc((*policy)->data,
(*policy)->length + val_len + 1);
if (tmp_data) {
(*policy)->data = tmp_data;
memcpy(&(*policy)->data[(*policy)->length],
val->value + 5, val_len);
(*policy)->length += val_len;
(*policy)->data[(*policy)->length] = '\0';
} else {
free((*policy)->data);
(*policy)->data = NULL;
(*policy)->length = 0;
X509V3error(ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
} else {
X509V3error(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
X509V3_conf_err(val);
goto err;
}
if (!tmp_data) {
X509V3error(ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
}
return 1;
err:
if (free_policy) {
ASN1_OCTET_STRING_free(*policy);
*policy = NULL;
}
return 0;
}
static PROXY_CERT_INFO_EXTENSION *
r2i_pci(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value)
{
PROXY_CERT_INFO_EXTENSION *pci = NULL;
STACK_OF(CONF_VALUE) *vals;
ASN1_OBJECT *language = NULL;
ASN1_INTEGER *pathlen = NULL;
ASN1_OCTET_STRING *policy = NULL;
int i, j;
vals = X509V3_parse_list(value);
for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
X509V3error(X509V3_R_INVALID_PROXY_POLICY_SETTING);
X509V3_conf_err(cnf);
goto err;
}
if (*cnf->name == '@') {
STACK_OF(CONF_VALUE) *sect;
int success_p = 1;
sect = X509V3_get_section(ctx, cnf->name + 1);
if (!sect) {
X509V3error(X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
}
for (j = 0; success_p &&
j < sk_CONF_VALUE_num(sect); j++) {
success_p = process_pci_value(
sk_CONF_VALUE_value(sect, j),
&language, &pathlen, &policy);
}
X509V3_section_free(ctx, sect);
if (!success_p)
goto err;
} else {
if (!process_pci_value(cnf,
&language, &pathlen, &policy)) {
X509V3_conf_err(cnf);
goto err;
}
}
}
/* Language is mandatory */
if (!language) {
X509V3error(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
goto err;
}
i = OBJ_obj2nid(language);
if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) {
X509V3error(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
goto err;
}
pci = PROXY_CERT_INFO_EXTENSION_new();
if (!pci) {
X509V3error(ERR_R_MALLOC_FAILURE);
goto err;
}
pci->proxyPolicy->policyLanguage = language;
language = NULL;
pci->proxyPolicy->policy = policy;
policy = NULL;
pci->pcPathLengthConstraint = pathlen;
pathlen = NULL;
goto end;
err:
ASN1_OBJECT_free(language);
language = NULL;
ASN1_INTEGER_free(pathlen);
pathlen = NULL;
ASN1_OCTET_STRING_free(policy);
policy = NULL;
end:
sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
return pci;
}

145
externals/libressl/crypto/x509/x509_pcia.c vendored Executable file
View File

@@ -0,0 +1,145 @@
/* $OpenBSD: x509_pcia.c,v 1.1 2020/06/04 15:19:32 jsing Exp $ */
/* Contributed to the OpenSSL Project 2004
* by Richard Levitte (richard@levitte.org)
*/
/* Copyright (c) 2004 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.
*/
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/x509v3.h>
static const ASN1_TEMPLATE PROXY_POLICY_seq_tt[] = {
{
.flags = 0,
.tag = 0,
.offset = offsetof(PROXY_POLICY, policyLanguage),
.field_name = "policyLanguage",
.item = &ASN1_OBJECT_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(PROXY_POLICY, policy),
.field_name = "policy",
.item = &ASN1_OCTET_STRING_it,
},
};
const ASN1_ITEM PROXY_POLICY_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = PROXY_POLICY_seq_tt,
.tcount = sizeof(PROXY_POLICY_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(PROXY_POLICY),
.sname = "PROXY_POLICY",
};
PROXY_POLICY *
d2i_PROXY_POLICY(PROXY_POLICY **a, const unsigned char **in, long len)
{
return (PROXY_POLICY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&PROXY_POLICY_it);
}
int
i2d_PROXY_POLICY(PROXY_POLICY *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PROXY_POLICY_it);
}
PROXY_POLICY *
PROXY_POLICY_new(void)
{
return (PROXY_POLICY *)ASN1_item_new(&PROXY_POLICY_it);
}
void
PROXY_POLICY_free(PROXY_POLICY *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PROXY_POLICY_it);
}
static const ASN1_TEMPLATE PROXY_CERT_INFO_EXTENSION_seq_tt[] = {
{
.flags = ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(PROXY_CERT_INFO_EXTENSION, pcPathLengthConstraint),
.field_name = "pcPathLengthConstraint",
.item = &ASN1_INTEGER_it,
},
{
.flags = 0,
.tag = 0,
.offset = offsetof(PROXY_CERT_INFO_EXTENSION, proxyPolicy),
.field_name = "proxyPolicy",
.item = &PROXY_POLICY_it,
},
};
const ASN1_ITEM PROXY_CERT_INFO_EXTENSION_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = PROXY_CERT_INFO_EXTENSION_seq_tt,
.tcount = sizeof(PROXY_CERT_INFO_EXTENSION_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(PROXY_CERT_INFO_EXTENSION),
.sname = "PROXY_CERT_INFO_EXTENSION",
};
PROXY_CERT_INFO_EXTENSION *
d2i_PROXY_CERT_INFO_EXTENSION(PROXY_CERT_INFO_EXTENSION **a, const unsigned char **in, long len)
{
return (PROXY_CERT_INFO_EXTENSION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&PROXY_CERT_INFO_EXTENSION_it);
}
int
i2d_PROXY_CERT_INFO_EXTENSION(PROXY_CERT_INFO_EXTENSION *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PROXY_CERT_INFO_EXTENSION_it);
}
PROXY_CERT_INFO_EXTENSION *
PROXY_CERT_INFO_EXTENSION_new(void)
{
return (PROXY_CERT_INFO_EXTENSION *)ASN1_item_new(&PROXY_CERT_INFO_EXTENSION_it);
}
void
PROXY_CERT_INFO_EXTENSION_free(PROXY_CERT_INFO_EXTENSION *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PROXY_CERT_INFO_EXTENSION_it);
}

194
externals/libressl/crypto/x509/x509_pcons.c vendored Executable file
View File

@@ -0,0 +1,194 @@
/* $OpenBSD: x509_pcons.c,v 1.1 2020/06/04 15:19:32 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_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,
};
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",
};
POLICY_CONSTRAINTS *
POLICY_CONSTRAINTS_new(void)
{
return (POLICY_CONSTRAINTS*)ASN1_item_new(&POLICY_CONSTRAINTS_it);
}
void
POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a)
{
ASN1_item_free((ASN1_VALUE *)a, &POLICY_CONSTRAINTS_it);
}
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;
}

154
externals/libressl/crypto/x509/x509_pku.c vendored Executable file
View File

@@ -0,0 +1,154 @@
/* $OpenBSD: x509_pku.c,v 1.1 2020/06/04 15:19:32 jsing 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/x509v3.h>
static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
const X509V3_EXT_METHOD v3_pkey_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,
};
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",
};
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);
}
int
i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKEY_USAGE_PERIOD_it);
}
PKEY_USAGE_PERIOD *
PKEY_USAGE_PERIOD_new(void)
{
return (PKEY_USAGE_PERIOD *)ASN1_item_new(&PKEY_USAGE_PERIOD_it);
}
void
PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PKEY_USAGE_PERIOD_it);
}
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;
}

235
externals/libressl/crypto/x509/x509_pmaps.c vendored Executable file
View File

@@ -0,0 +1,235 @@
/* $OpenBSD: x509_pmaps.c,v 1.1 2020/06/04 15:19:32 jsing 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 <stdio.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.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);
const X509V3_EXT_METHOD v3_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,
};
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",
};
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",
};
POLICY_MAPPING *
POLICY_MAPPING_new(void)
{
return (POLICY_MAPPING*)ASN1_item_new(&POLICY_MAPPING_it);
}
void
POLICY_MAPPING_free(POLICY_MAPPING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &POLICY_MAPPING_it);
}
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;
}

225
externals/libressl/crypto/x509/x509_prn.c vendored Executable file
View File

@@ -0,0 +1,225 @@
/* $OpenBSD: x509_prn.c,v 1.1 2020/06/04 15:19:32 jsing 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 <stdio.h>
#include <openssl/conf.h>
#include <openssl/x509v3.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, "<EMPTY>\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");
}
}
/* 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;
}
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;
}
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<Parse Error>", indent, "");
else
BIO_printf(out, "%*s<Not Supported>", 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;
}

893
externals/libressl/crypto/x509/x509_purp.c vendored Executable file
View File

@@ -0,0 +1,893 @@
/* $OpenBSD: x509_purp.c,v 1.2 2020/09/13 15:06:17 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 <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#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)))
void x509v3_cache_extensions(X509 *x);
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 int xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b);
static void xptable_free(X509_PURPOSE *p);
static X509_PURPOSE xstandard[] = {
{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL},
{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL},
{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL},
{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
};
#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
static STACK_OF(X509_PURPOSE) *xptable = NULL;
static int
xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b)
{
return (*a)->purpose - (*b)->purpose;
}
/* 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 (!(x->ex_flags & EXFLAG_SET)) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
if (id == -1)
return 1;
idx = X509_PURPOSE_get_by_id(id);
if (idx == -1)
return -1;
pt = X509_PURPOSE_get0(idx);
return pt->check_purpose(pt, x, ca);
}
int
X509_PURPOSE_set(int *p, int purpose)
{
if (X509_PURPOSE_get_by_id(purpose) == -1) {
X509V3error(X509V3_R_INVALID_PURPOSE);
return 0;
}
*p = purpose;
return 1;
}
int
X509_PURPOSE_get_count(void)
{
if (!xptable)
return X509_PURPOSE_COUNT;
return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
}
X509_PURPOSE *
X509_PURPOSE_get0(int idx)
{
if (idx < 0)
return NULL;
if (idx < (int)X509_PURPOSE_COUNT)
return xstandard + idx;
return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
}
int
X509_PURPOSE_get_by_sname(const char *sname)
{
int i;
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;
}
int
X509_PURPOSE_get_by_id(int purpose)
{
X509_PURPOSE tmp;
int idx;
if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
return purpose - X509_PURPOSE_MIN;
tmp.purpose = purpose;
if (!xptable)
return -1;
idx = sk_X509_PURPOSE_find(xptable, &tmp);
if (idx == -1)
return -1;
return idx + X509_PURPOSE_COUNT;
}
int
X509_PURPOSE_add(int id, int trust, int flags,
int (*ck)(const X509_PURPOSE *, const X509 *, int), const char *name,
const char *sname, void *arg)
{
int idx;
X509_PURPOSE *ptmp;
char *name_dup, *sname_dup;
name_dup = sname_dup = NULL;
if (name == NULL || sname == NULL) {
X509V3error(X509V3_R_INVALID_NULL_ARGUMENT);
return 0;
}
/* This is set according to what we change: application can't set it */
flags &= ~X509_PURPOSE_DYNAMIC;
/* This will always be set for application modified trust entries */
flags |= X509_PURPOSE_DYNAMIC_NAME;
/* Get existing entry if any */
idx = X509_PURPOSE_get_by_id(id);
/* Need a new entry */
if (idx == -1) {
if ((ptmp = malloc(sizeof(X509_PURPOSE))) == NULL) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
ptmp->flags = X509_PURPOSE_DYNAMIC;
} else
ptmp = X509_PURPOSE_get0(idx);
if ((name_dup = strdup(name)) == NULL)
goto err;
if ((sname_dup = strdup(sname)) == NULL)
goto err;
/* free existing name if dynamic */
if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
free(ptmp->name);
free(ptmp->sname);
}
/* dup supplied name */
ptmp->name = name_dup;
ptmp->sname = sname_dup;
/* Keep the dynamic flag of existing entry */
ptmp->flags &= X509_PURPOSE_DYNAMIC;
/* Set all other flags */
ptmp->flags |= flags;
ptmp->purpose = id;
ptmp->trust = trust;
ptmp->check_purpose = ck;
ptmp->usr_data = arg;
/* If its a new entry manage the dynamic table */
if (idx == -1) {
if (xptable == NULL &&
(xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL)
goto err;
if (sk_X509_PURPOSE_push(xptable, ptmp) == 0)
goto err;
}
return 1;
err:
free(name_dup);
free(sname_dup);
if (idx == -1)
free(ptmp);
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
static void
xptable_free(X509_PURPOSE *p)
{
if (!p)
return;
if (p->flags & X509_PURPOSE_DYNAMIC) {
if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
free(p->name);
free(p->sname);
}
free(p);
}
}
void
X509_PURPOSE_cleanup(void)
{
unsigned int i;
sk_X509_PURPOSE_pop_free(xptable, xptable_free);
for(i = 0; i < X509_PURPOSE_COUNT; i++)
xptable_free(xstandard + i);
xptable = NULL;
}
int
X509_PURPOSE_get_id(const X509_PURPOSE *xp)
{
return xp->purpose;
}
char *
X509_PURPOSE_get0_name(const X509_PURPOSE *xp)
{
return xp->name;
}
char *
X509_PURPOSE_get0_sname(const X509_PURPOSE *xp)
{
return xp->sname;
}
int
X509_PURPOSE_get_trust(const X509_PURPOSE *xp)
{
return xp->trust;
}
static int
nid_cmp(const int *a, const int *b)
{
return *a - *b;
}
static int nid_cmp_BSEARCH_CMP_FN(const void *, const void *);
static int nid_cmp(int const *, int const *);
static int *OBJ_bsearch_nid(int *key, int const *base, int num);
static int
nid_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
{
int const *a = a_;
int const *b = b_;
return nid_cmp(a, b);
}
static int *
OBJ_bsearch_nid(int *key, int const *base, int num)
{
return (int *)OBJ_bsearch_(key, base, num, sizeof(int),
nid_cmp_BSEARCH_CMP_FN);
}
int
X509_supported_extension(X509_EXTENSION *ex)
{
/* This table is a list of the NIDs of supported extensions:
* that is those which are used by the verify process. If
* an extension is critical and doesn't appear in this list
* then the verify process will normally reject the certificate.
* The list must be kept in numerical order because it will be
* searched using bsearch.
*/
static const int supported_nids[] = {
NID_netscape_cert_type, /* 71 */
NID_key_usage, /* 83 */
NID_subject_alt_name, /* 85 */
NID_basic_constraints, /* 87 */
NID_certificate_policies, /* 89 */
NID_ext_key_usage, /* 126 */
NID_policy_constraints, /* 401 */
NID_proxyCertInfo, /* 663 */
NID_name_constraints, /* 666 */
NID_policy_mappings, /* 747 */
NID_inhibit_any_policy /* 748 */
};
int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
if (ex_nid == NID_undef)
return 0;
if (OBJ_bsearch_nid(&ex_nid, supported_nids,
sizeof(supported_nids) / sizeof(int)))
return 1;
return 0;
}
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, NULL, NULL);
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
}
void
x509v3_cache_extensions(X509 *x)
{
BASIC_CONSTRAINTS *bs;
PROXY_CERT_INFO_EXTENSION *pci;
ASN1_BIT_STRING *usage;
ASN1_BIT_STRING *ns;
EXTENDED_KEY_USAGE *extusage;
X509_EXTENSION *ex;
int i;
if (x->ex_flags & EXFLAG_SET)
return;
#ifndef OPENSSL_NO_SHA
X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
#endif
/* V1 should mean no extensions ... */
if (!X509_get_version(x))
x->ex_flags |= EXFLAG_V1;
/* Handle basic constraints */
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
if (bs->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;
}
/* Handle proxy certificates */
if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
if (x->ex_flags & EXFLAG_CA ||
X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 ||
X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
x->ex_flags |= EXFLAG_INVALID;
}
if (pci->pcPathLengthConstraint) {
if (pci->pcPathLengthConstraint->type ==
V_ASN1_NEG_INTEGER) {
x->ex_flags |= EXFLAG_INVALID;
x->ex_pcpathlen = 0;
} else
x->ex_pcpathlen =
ASN1_INTEGER_get(pci->
pcPathLengthConstraint);
} else
x->ex_pcpathlen = -1;
PROXY_CERT_INFO_EXTENSION_free(pci);
x->ex_flags |= EXFLAG_PROXY;
}
/* Handle key usage */
if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, 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);
}
x->ex_xkusage = 0;
if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, 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;
}
}
sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
}
if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, 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);
}
x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
/* 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, NULL, NULL);
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);
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;
}
}
x->ex_flags |= EXFLAG_SET;
}
/* 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)
{
if (!(x->ex_flags & EXFLAG_SET)) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
return check_ca(x);
}
/* 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;
x509v3_cache_extensions(issuer);
x509v3_cache_extensions(subject);
if (subject->akid) {
int ret = X509_check_akid(issuer, subject->akid);
if (ret != X509_V_OK)
return ret;
}
if (subject->ex_flags & EXFLAG_PROXY) {
if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
} else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
return X509_V_OK;
}
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;
}

115
externals/libressl/crypto/x509/x509_r2x.c vendored Executable file
View File

@@ -0,0 +1,115 @@
/* $OpenBSD: x509_r2x.c,v 1.11 2017/01/29 17:49:23 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
X509 *
X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
{
X509 *ret = NULL;
X509_CINF *xi = NULL;
X509_NAME *xn;
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 ((xi->version = ASN1_INTEGER_new()) == NULL)
goto err;
if (!ASN1_INTEGER_set(xi->version, 2))
goto err;
/* xi->extensions=ri->attributes; <- bad, should not ever be done
ri->attributes=NULL; */
}
xn = X509_REQ_get_subject_name(r);
if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
goto err;
if (X509_set_issuer_name(ret, X509_NAME_dup(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;
X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
if (!X509_sign(ret, pkey, EVP_md5()))
goto err;
if (0) {
err:
X509_free(ret);
ret = NULL;
}
return (ret);
}

343
externals/libressl/crypto/x509/x509_req.c vendored Executable file
View File

@@ -0,0 +1,343 @@
/* $OpenBSD: x509_req.c,v 1.21 2018/05/13 06:48:00 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 <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
X509_REQ *
X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
X509_REQ *ret;
X509_REQ_INFO *ri;
int i;
EVP_PKEY *pktmp;
ret = X509_REQ_new();
if (ret == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
goto err;
}
ri = ret->req_info;
if ((ri->version = ASN1_INTEGER_new()) == NULL)
goto err;
if (ASN1_INTEGER_set(ri->version, 0) == 0)
goto err;
if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
goto err;
if ((pktmp = X509_get_pubkey(x)) == NULL)
goto err;
i = X509_REQ_set_pubkey(ret, pktmp);
EVP_PKEY_free(pktmp);
if (!i)
goto err;
if (pkey != NULL) {
if (!X509_REQ_sign(ret, pkey, md))
goto err;
}
return (ret);
err:
X509_REQ_free(ret);
return (NULL);
}
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));
}
int
X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
{
EVP_PKEY *xk = NULL;
int ok = 0;
xk = X509_REQ_get_pubkey(x);
switch (EVP_PKEY_cmp(xk, k)) {
case 1:
ok = 1;
break;
case 0:
X509error(X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
X509error(X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
#ifndef OPENSSL_NO_EC
if (k->type == EVP_PKEY_EC) {
X509error(ERR_R_EC_LIB);
break;
}
#endif
#ifndef OPENSSL_NO_DH
if (k->type == EVP_PKEY_DH) {
/* No idea */
X509error(X509_R_CANT_CHECK_DH_KEY);
break;
}
#endif
X509error(X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
return (ok);
}
/* It seems several organisations had the same idea of including a list of
* extensions in a certificate request. There are at least two OIDs that are
* used and there may be more: so the list is configurable.
*/
static int ext_nid_list[] = {NID_ext_req, NID_ms_ext_req, NID_undef};
static int *ext_nids = ext_nid_list;
int
X509_REQ_extension_nid(int req_nid)
{
int i, nid;
for (i = 0; ; i++) {
nid = ext_nids[i];
if (nid == NID_undef)
return 0;
else if (req_nid == nid)
return 1;
}
}
int *
X509_REQ_get_extension_nids(void)
{
return ext_nids;
}
void
X509_REQ_set_extension_nids(int *nids)
{
ext_nids = nids;
}
STACK_OF(X509_EXTENSION) *
X509_REQ_get_extensions(X509_REQ *req)
{
X509_ATTRIBUTE *attr;
ASN1_TYPE *ext = NULL;
int idx, *pnid;
const unsigned char *p;
if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
return (NULL);
for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
if (idx == -1)
continue;
attr = X509_REQ_get_attr(req, idx);
if (attr->single)
ext = attr->value.single;
else if (sk_ASN1_TYPE_num(attr->value.set))
ext = sk_ASN1_TYPE_value(attr->value.set, 0);
break;
}
if (!ext || (ext->type != V_ASN1_SEQUENCE))
return NULL;
p = ext->value.sequence->data;
return (STACK_OF(X509_EXTENSION) *)ASN1_item_d2i(NULL, &p,
ext->value.sequence->length, &X509_EXTENSIONS_it);
}
/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
* in case we want to create a non standard one.
*/
int
X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
int nid)
{
ASN1_TYPE *at = NULL;
X509_ATTRIBUTE *attr = NULL;
if (!(at = ASN1_TYPE_new()) ||
!(at->value.sequence = ASN1_STRING_new()))
goto err;
at->type = V_ASN1_SEQUENCE;
/* Generate encoding of extensions */
at->value.sequence->length = ASN1_item_i2d((ASN1_VALUE *)exts,
&at->value.sequence->data, &X509_EXTENSIONS_it);
if (!(attr = X509_ATTRIBUTE_new()))
goto err;
if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
goto err;
if (!sk_ASN1_TYPE_push(attr->value.set, at))
goto err;
at = NULL;
attr->single = 0;
attr->object = OBJ_nid2obj(nid);
if (!req->req_info->attributes) {
if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
goto err;
}
if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
goto err;
return 1;
err:
X509_ATTRIBUTE_free(attr);
ASN1_TYPE_free(at);
return 0;
}
/* 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);
}
/* Request attribute functions */
int
X509_REQ_get_attr_count(const X509_REQ *req)
{
return X509at_get_attr_count(req->req_info->attributes);
}
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);
}
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);
}
X509_ATTRIBUTE *
X509_REQ_get_attr(const X509_REQ *req, int loc)
{
return X509at_get_attr(req->req_info->attributes, loc);
}
X509_ATTRIBUTE *
X509_REQ_delete_attr(X509_REQ *req, int loc)
{
return X509at_delete_attr(req->req_info->attributes, loc);
}
int
X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
{
if (X509at_add1_attr(&req->req_info->attributes, attr))
return 1;
return 0;
}
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;
}
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;
}
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;
}

218
externals/libressl/crypto/x509/x509_set.c vendored Executable file
View File

@@ -0,0 +1,218 @@
/* $OpenBSD: x509_set.c,v 1.17 2018/08/24 19:55:58 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
const STACK_OF(X509_EXTENSION) *
X509_get0_extensions(const X509 *x)
{
return x->cert_info->extensions;
}
const X509_ALGOR *
X509_get0_tbs_sigalg(const X509 *x)
{
return x->cert_info->signature;
}
int
X509_set_version(X509 *x, long version)
{
if (x == NULL)
return (0);
if (x->cert_info->version == NULL) {
if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL)
return (0);
}
return (ASN1_INTEGER_set(x->cert_info->version, version));
}
long
X509_get_version(const X509 *x)
{
return ASN1_INTEGER_get(x->cert_info->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) {
ASN1_INTEGER_free(x->cert_info->serialNumber);
x->cert_info->serialNumber = in;
}
}
return (in != NULL);
}
int
X509_set_issuer_name(X509 *x, X509_NAME *name)
{
if ((x == NULL) || (x->cert_info == NULL))
return (0);
return (X509_NAME_set(&x->cert_info->issuer, name));
}
int
X509_set_subject_name(X509 *x, X509_NAME *name)
{
if (x == NULL || x->cert_info == NULL)
return (0);
return (X509_NAME_set(&x->cert_info->subject, name));
}
const ASN1_TIME *
X509_get0_notBefore(const X509 *x)
{
return X509_getm_notBefore(x);
}
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;
}
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) {
ASN1_TIME_free(x->cert_info->validity->notBefore);
x->cert_info->validity->notBefore = in;
}
}
return (in != NULL);
}
int
X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
{
return X509_set_notBefore(x, tm);
}
const ASN1_TIME *
X509_get0_notAfter(const X509 *x)
{
return X509_getm_notAfter(x);
}
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;
}
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) {
ASN1_TIME_free(x->cert_info->validity->notAfter);
x->cert_info->validity->notAfter = in;
}
}
return (in != NULL);
}
int
X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
{
return X509_set_notAfter(x, tm);
}
int
X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
{
if ((x == NULL) || (x->cert_info == NULL))
return (0);
return (X509_PUBKEY_set(&(x->cert_info->key), pkey));
}
int
X509_get_signature_type(const X509 *x)
{
return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm));
}

161
externals/libressl/crypto/x509/x509_skey.c vendored Executable file
View File

@@ -0,0 +1,161 @@
/* $OpenBSD: x509_skey.c,v 1.1 2020/06/04 15:19:32 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, char *str);
const X509V3_EXT_METHOD v3_skey_id = {
.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,
};
char *
i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, const ASN1_OCTET_STRING *oct)
{
return hex_to_string(oct->data, oct->length);
}
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;
}
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;
}

383
externals/libressl/crypto/x509/x509_sxnet.c vendored Executable file
View File

@@ -0,0 +1,383 @@
/* $OpenBSD: x509_sxnet.c,v 1.1 2020/06/04 15:19:32 jsing 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
/* Support for Thawte strong extranet extension */
#define SXNET_TEST
static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
int indent);
#ifdef SXNET_TEST
static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
STACK_OF(CONF_VALUE) *nval);
#endif
const X509V3_EXT_METHOD v3_sxnet = {
.ext_nid = NID_sxnet,
.ext_flags = X509V3_EXT_MULTILINE,
.it = &SXNET_it,
.ext_new = NULL,
.ext_free = NULL,
.d2i = NULL,
.i2d = NULL,
.i2s = NULL,
.s2i = NULL,
.i2v = NULL,
#ifdef SXNET_TEST
.v2i = (X509V3_EXT_V2I)sxnet_v2i,
#else
.v2i = NULL,
#endif
.i2r = (X509V3_EXT_I2R)sxnet_i2r,
.r2i = NULL,
.usr_data = NULL,
};
static const ASN1_TEMPLATE SXNETID_seq_tt[] = {
{
.flags = 0,
.tag = 0,
.offset = offsetof(SXNETID, zone),
.field_name = "zone",
.item = &ASN1_INTEGER_it,
},
{
.flags = 0,
.tag = 0,
.offset = offsetof(SXNETID, user),
.field_name = "user",
.item = &ASN1_OCTET_STRING_it,
},
};
const ASN1_ITEM SXNETID_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = SXNETID_seq_tt,
.tcount = sizeof(SXNETID_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(SXNETID),
.sname = "SXNETID",
};
SXNETID *
d2i_SXNETID(SXNETID **a, const unsigned char **in, long len)
{
return (SXNETID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&SXNETID_it);
}
int
i2d_SXNETID(SXNETID *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &SXNETID_it);
}
SXNETID *
SXNETID_new(void)
{
return (SXNETID *)ASN1_item_new(&SXNETID_it);
}
void
SXNETID_free(SXNETID *a)
{
ASN1_item_free((ASN1_VALUE *)a, &SXNETID_it);
}
static const ASN1_TEMPLATE SXNET_seq_tt[] = {
{
.flags = 0,
.tag = 0,
.offset = offsetof(SXNET, version),
.field_name = "version",
.item = &ASN1_INTEGER_it,
},
{
.flags = ASN1_TFLG_SEQUENCE_OF,
.tag = 0,
.offset = offsetof(SXNET, ids),
.field_name = "ids",
.item = &SXNETID_it,
},
};
const ASN1_ITEM SXNET_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = SXNET_seq_tt,
.tcount = sizeof(SXNET_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(SXNET),
.sname = "SXNET",
};
SXNET *
d2i_SXNET(SXNET **a, const unsigned char **in, long len)
{
return (SXNET *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&SXNET_it);
}
int
i2d_SXNET(SXNET *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &SXNET_it);
}
SXNET *
SXNET_new(void)
{
return (SXNET *)ASN1_item_new(&SXNET_it);
}
void
SXNET_free(SXNET *a)
{
ASN1_item_free((ASN1_VALUE *)a, &SXNET_it);
}
static int
sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent)
{
long v;
char *tmp;
SXNETID *id;
int i;
v = ASN1_INTEGER_get(sx->version);
BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
id = sk_SXNETID_value(sx->ids, i);
tmp = i2s_ASN1_INTEGER(NULL, id->zone);
BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
free(tmp);
ASN1_STRING_print(out, id->user);
}
return 1;
}
#ifdef SXNET_TEST
/* NBB: this is used for testing only. It should *not* be used for anything
* else because it will just take static IDs from the configuration file and
* they should really be separate values for each user.
*/
static SXNET *
sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
STACK_OF(CONF_VALUE) *nval)
{
CONF_VALUE *cnf;
SXNET *sx = NULL;
int i;
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
cnf = sk_CONF_VALUE_value(nval, i);
if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
return NULL;
}
return sx;
}
#endif
/* Strong Extranet utility functions */
/* Add an id given the zone as an ASCII number */
int
SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen)
{
ASN1_INTEGER *izone = NULL;
if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
X509V3error(X509V3_R_ERROR_CONVERTING_ZONE);
return 0;
}
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
}
/* Add an id given the zone as an unsigned long */
int
SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user,
int userlen)
{
ASN1_INTEGER *izone = NULL;
if (!(izone = ASN1_INTEGER_new()) ||
!ASN1_INTEGER_set(izone, lzone)) {
X509V3error(ERR_R_MALLOC_FAILURE);
ASN1_INTEGER_free(izone);
return 0;
}
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
}
/* Add an id given the zone as an ASN1_INTEGER.
* Note this version uses the passed integer and doesn't make a copy so don't
* free it up afterwards.
*/
int
SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user,
int userlen)
{
SXNET *sx = NULL;
SXNETID *id = NULL;
if (!psx || !zone || !user) {
X509V3error(X509V3_R_INVALID_NULL_ARGUMENT);
return 0;
}
if (userlen == -1)
userlen = strlen(user);
if (userlen > 64) {
X509V3error(X509V3_R_USER_TOO_LONG);
return 0;
}
if (!*psx) {
if (!(sx = SXNET_new()))
goto err;
if (!ASN1_INTEGER_set(sx->version, 0))
goto err;
*psx = sx;
} else
sx = *psx;
if (SXNET_get_id_INTEGER(sx, zone)) {
X509V3error(X509V3_R_DUPLICATE_ZONE_ID);
return 0;
}
if (!(id = SXNETID_new()))
goto err;
if (userlen == -1)
userlen = strlen(user);
if (!ASN1_STRING_set(id->user, user, userlen))
goto err;
if (!sk_SXNETID_push(sx->ids, id))
goto err;
id->zone = zone;
return 1;
err:
X509V3error(ERR_R_MALLOC_FAILURE);
SXNETID_free(id);
SXNET_free(sx);
*psx = NULL;
return 0;
}
ASN1_OCTET_STRING *
SXNET_get_id_asc(SXNET *sx, const char *zone)
{
ASN1_INTEGER *izone = NULL;
ASN1_OCTET_STRING *oct;
if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
X509V3error(X509V3_R_ERROR_CONVERTING_ZONE);
return NULL;
}
oct = SXNET_get_id_INTEGER(sx, izone);
ASN1_INTEGER_free(izone);
return oct;
}
ASN1_OCTET_STRING *
SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
{
ASN1_INTEGER *izone = NULL;
ASN1_OCTET_STRING *oct;
if (!(izone = ASN1_INTEGER_new()) ||
!ASN1_INTEGER_set(izone, lzone)) {
X509V3error(ERR_R_MALLOC_FAILURE);
ASN1_INTEGER_free(izone);
return NULL;
}
oct = SXNET_get_id_INTEGER(sx, izone);
ASN1_INTEGER_free(izone);
return oct;
}
ASN1_OCTET_STRING *
SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
{
SXNETID *id;
int i;
for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
id = sk_SXNETID_value(sx->ids, i);
if (!ASN1_INTEGER_cmp(id->zone, zone))
return id->user;
}
return NULL;
}

348
externals/libressl/crypto/x509/x509_trs.c vendored Executable file
View File

@@ -0,0 +1,348 @@
/* $OpenBSD: x509_trs.c,v 1.23 2018/05/18 18:40: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).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
static int tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b);
static void trtable_free(X509_TRUST *p);
static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
static int obj_trust(int id, X509 *x, int flags);
static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
/* WARNING: the following table should be kept in order of trust
* and without any gaps so we can just subtract the minimum trust
* value to get an index into the table
*/
static X509_TRUST trstandard[] = {
{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL},
{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL},
{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL},
{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
};
#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
static STACK_OF(X509_TRUST) *trtable = NULL;
static int
tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b)
{
return (*a)->trust - (*b)->trust;
}
int
(*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
{
int (*oldtrust)(int , X509 *, int);
oldtrust = default_trust;
default_trust = trust;
return oldtrust;
}
int
X509_check_trust(X509 *x, int id, int flags)
{
X509_TRUST *pt;
int idx;
if (id == -1)
return 1;
/*
* XXX beck/jsing This enables self signed certs to be trusted for
* an unspecified id/trust flag value (this is NOT the
* X509_TRUST_DEFAULT), which was the longstanding
* openssl behaviour. boringssl does not have this behaviour.
*
* This should be revisited, but changing the default "not default"
* may break things.
*/
if (id == 0) {
int rv;
rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
if (rv != X509_TRUST_UNTRUSTED)
return rv;
return trust_compat(NULL, x, 0);
}
idx = X509_TRUST_get_by_id(id);
if (idx == -1)
return default_trust(id, x, flags);
pt = X509_TRUST_get0(idx);
return pt->check_trust(pt, x, flags);
}
int
X509_TRUST_get_count(void)
{
if (!trtable)
return X509_TRUST_COUNT;
return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
}
X509_TRUST *
X509_TRUST_get0(int idx)
{
if (idx < 0)
return NULL;
if (idx < (int)X509_TRUST_COUNT)
return trstandard + idx;
return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
}
int
X509_TRUST_get_by_id(int id)
{
X509_TRUST tmp;
int idx;
if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
return id - X509_TRUST_MIN;
tmp.trust = id;
if (!trtable)
return -1;
idx = sk_X509_TRUST_find(trtable, &tmp);
if (idx == -1)
return -1;
return idx + X509_TRUST_COUNT;
}
int
X509_TRUST_set(int *t, int trust)
{
if (X509_TRUST_get_by_id(trust) == -1) {
X509error(X509_R_INVALID_TRUST);
return 0;
}
*t = trust;
return 1;
}
int
X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
const char *name, int arg1, void *arg2)
{
int idx;
X509_TRUST *trtmp;
char *name_dup;
/* This is set according to what we change: application can't set it */
flags &= ~X509_TRUST_DYNAMIC;
/* This will always be set for application modified trust entries */
flags |= X509_TRUST_DYNAMIC_NAME;
/* Get existing entry if any */
idx = X509_TRUST_get_by_id(id);
/* Need a new entry */
if (idx == -1) {
if (!(trtmp = malloc(sizeof(X509_TRUST)))) {
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
trtmp->flags = X509_TRUST_DYNAMIC;
} else {
trtmp = X509_TRUST_get0(idx);
if (trtmp == NULL) {
X509error(X509_R_INVALID_TRUST);
return 0;
}
}
if ((name_dup = strdup(name)) == NULL)
goto err;
/* free existing name if dynamic */
if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
free(trtmp->name);
/* dup supplied name */
trtmp->name = name_dup;
/* Keep the dynamic flag of existing entry */
trtmp->flags &= X509_TRUST_DYNAMIC;
/* Set all other flags */
trtmp->flags |= flags;
trtmp->trust = id;
trtmp->check_trust = ck;
trtmp->arg1 = arg1;
trtmp->arg2 = arg2;
/* If it's a new entry, manage the dynamic table */
if (idx == -1) {
if (trtable == NULL &&
(trtable = sk_X509_TRUST_new(tr_cmp)) == NULL)
goto err;
if (sk_X509_TRUST_push(trtable, trtmp) == 0)
goto err;
}
return 1;
err:
free(name_dup);
if (idx == -1)
free(trtmp);
X509error(ERR_R_MALLOC_FAILURE);
return 0;
}
static void
trtable_free(X509_TRUST *p)
{
if (!p)
return;
if (p->flags & X509_TRUST_DYNAMIC) {
if (p->flags & X509_TRUST_DYNAMIC_NAME)
free(p->name);
free(p);
}
}
void
X509_TRUST_cleanup(void)
{
unsigned int i;
for (i = 0; i < X509_TRUST_COUNT; i++)
trtable_free(trstandard + i);
sk_X509_TRUST_pop_free(trtable, trtable_free);
trtable = NULL;
}
int
X509_TRUST_get_flags(const X509_TRUST *xp)
{
return xp->flags;
}
char *
X509_TRUST_get0_name(const X509_TRUST *xp)
{
return xp->name;
}
int
X509_TRUST_get_trust(const X509_TRUST *xp)
{
return xp->trust;
}
static int
trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
{
if (x->aux && (x->aux->trust || x->aux->reject))
return obj_trust(trust->arg1, x, flags);
/* we don't have any trust settings: for compatibility
* we return trusted if it is self signed
*/
return trust_compat(trust, x, flags);
}
static int
trust_1oid(X509_TRUST *trust, X509 *x, int flags)
{
if (x->aux)
return obj_trust(trust->arg1, x, flags);
return X509_TRUST_UNTRUSTED;
}
static int
trust_compat(X509_TRUST *trust, X509 *x, int flags)
{
X509_check_purpose(x, -1, 0);
if (x->ex_flags & EXFLAG_SS)
return X509_TRUST_TRUSTED;
else
return X509_TRUST_UNTRUSTED;
}
static int
obj_trust(int id, X509 *x, int flags)
{
ASN1_OBJECT *obj;
int i;
X509_CERT_AUX *ax;
ax = x->aux;
if (!ax)
return X509_TRUST_UNTRUSTED;
if (ax->reject) {
for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
obj = sk_ASN1_OBJECT_value(ax->reject, i);
if (OBJ_obj2nid(obj) == id)
return X509_TRUST_REJECTED;
}
}
if (ax->trust) {
for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
obj = sk_ASN1_OBJECT_value(ax->trust, i);
if (OBJ_obj2nid(obj) == id)
return X509_TRUST_TRUSTED;
}
}
return X509_TRUST_UNTRUSTED;
}

189
externals/libressl/crypto/x509/x509_txt.c vendored Executable file
View File

@@ -0,0 +1,189 @@
/* $OpenBSD: x509_txt.c,v 1.19 2014/07/11 08:44:49 jsing 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 <errno.h>
#include <stdio.h>
#include <time.h>
#include <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/lhash.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
const char *
X509_verify_cert_error_string(long n)
{
static char buf[100];
switch ((int)n) {
case X509_V_OK:
return("ok");
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_CRL_NOT_YET_VALID:
return("CRL is not yet valid");
case X509_V_ERR_CERT_HAS_EXPIRED:
return("certificate has expired");
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_INVALID_NON_CA:
return ("invalid non-CA certificate (has CA markings)");
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
return ("path length constraint exceeded");
case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
return("proxy path length constraint exceeded");
case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
return("proxy certificates not allowed, please set the appropriate flag");
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_APPLICATION_VERIFICATION:
return("application verification failure");
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_KEYUSAGE_NO_DIGITAL_SIGNATURE:
return("key usage does not include digital signature");
case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
return("unhandled critical CRL extension");
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");
default:
(void) snprintf(buf, sizeof buf, "error number %ld", n);
return(buf);
}
}

1388
externals/libressl/crypto/x509/x509_utl.c vendored Executable file

File diff suppressed because it is too large Load Diff

298
externals/libressl/crypto/x509/x509_v3.c vendored Executable file
View File

@@ -0,0 +1,298 @@
/* $OpenBSD: x509_v3.c,v 1.17 2018/05/19 10:54: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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int
X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
{
if (x == NULL)
return (0);
return (sk_X509_EXTENSION_num(x));
}
int
X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, int lastpos)
{
ASN1_OBJECT *obj;
obj = OBJ_nid2obj(nid);
if (obj == NULL)
return (-2);
return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
}
int
X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
const ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_EXTENSION *ex;
if (sk == NULL)
return (-1);
lastpos++;
if (lastpos < 0)
lastpos = 0;
n = sk_X509_EXTENSION_num(sk);
for (; lastpos < n; lastpos++) {
ex = sk_X509_EXTENSION_value(sk, lastpos);
if (OBJ_cmp(ex->object, obj) == 0)
return (lastpos);
}
return (-1);
}
int
X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
int lastpos)
{
int n;
X509_EXTENSION *ex;
if (sk == NULL)
return (-1);
lastpos++;
if (lastpos < 0)
lastpos = 0;
n = sk_X509_EXTENSION_num(sk);
for (; lastpos < n; lastpos++) {
ex = sk_X509_EXTENSION_value(sk, lastpos);
if (((ex->critical > 0) && crit) ||
((ex->critical <= 0) && !crit))
return (lastpos);
}
return (-1);
}
X509_EXTENSION *
X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
{
if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
return NULL;
else
return sk_X509_EXTENSION_value(x, loc);
}
X509_EXTENSION *
X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
{
X509_EXTENSION *ret;
if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
return (NULL);
ret = sk_X509_EXTENSION_delete(x, loc);
return (ret);
}
STACK_OF(X509_EXTENSION) *
X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc)
{
X509_EXTENSION *new_ex = NULL;
int n;
STACK_OF(X509_EXTENSION) *sk = NULL;
if (x == NULL) {
X509error(ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
if (*x == NULL) {
if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
goto err;
} else
sk= *x;
n = sk_X509_EXTENSION_num(sk);
if (loc > n)
loc = n;
else if (loc < 0)
loc = n;
if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
goto err2;
if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
goto err;
if (*x == NULL)
*x = sk;
return (sk);
err:
X509error(ERR_R_MALLOC_FAILURE);
err2:
if (new_ex != NULL)
X509_EXTENSION_free(new_ex);
if (sk != NULL && (x != NULL && sk != *x))
sk_X509_EXTENSION_free(sk);
return (NULL);
}
X509_EXTENSION *
X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit,
ASN1_OCTET_STRING *data)
{
ASN1_OBJECT *obj;
X509_EXTENSION *ret;
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509error(X509_R_UNKNOWN_NID);
return (NULL);
}
ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
if (ret == NULL)
ASN1_OBJECT_free(obj);
return (ret);
}
X509_EXTENSION *
X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, const ASN1_OBJECT *obj,
int crit, ASN1_OCTET_STRING *data)
{
X509_EXTENSION *ret;
if ((ex == NULL) || (*ex == NULL)) {
if ((ret = X509_EXTENSION_new()) == NULL) {
X509error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
} else
ret= *ex;
if (!X509_EXTENSION_set_object(ret, obj))
goto err;
if (!X509_EXTENSION_set_critical(ret, crit))
goto err;
if (!X509_EXTENSION_set_data(ret, data))
goto err;
if ((ex != NULL) && (*ex == NULL))
*ex = ret;
return (ret);
err:
if ((ex == NULL) || (ret != *ex))
X509_EXTENSION_free(ret);
return (NULL);
}
int
X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
{
if ((ex == NULL) || (obj == NULL))
return (0);
ASN1_OBJECT_free(ex->object);
ex->object = OBJ_dup(obj);
return ex->object != NULL;
}
int
X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
{
if (ex == NULL)
return (0);
ex->critical = (crit) ? 0xFF : -1;
return (1);
}
int
X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
{
int i;
if (ex == NULL)
return (0);
i = ASN1_STRING_set(ex->value, data->data, data->length);
if (!i)
return (0);
return (1);
}
ASN1_OBJECT *
X509_EXTENSION_get_object(X509_EXTENSION *ex)
{
if (ex == NULL)
return (NULL);
return (ex->object);
}
ASN1_OCTET_STRING *
X509_EXTENSION_get_data(X509_EXTENSION *ex)
{
if (ex == NULL)
return (NULL);
return (ex->value);
}
int
X509_EXTENSION_get_critical(const X509_EXTENSION *ex)
{
if (ex == NULL)
return (0);
if (ex->critical > 0)
return 1;
return 0;
}

928
externals/libressl/crypto/x509/x509_verify.c vendored Executable file
View File

@@ -0,0 +1,928 @@
/* $OpenBSD: x509_verify.c,v 1.13 2020/09/26 15:44:06 jsing Exp $ */
/*
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
*
* 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 <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <openssl/safestack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.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 void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
struct x509_verify_chain *current_chain);
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);
#define X509_VERIFY_CERT_HASH (EVP_sha512())
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->names = x509_constraints_names_new()) == 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;
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 = x509_verify_chain_new()) == NULL)
goto err;
if ((new_chain->certs = X509_chain_up_ref(chain->certs)) == NULL)
goto err;
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;
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;
}
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]);
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);
memset(ctx, 0, sizeof(*ctx));
}
static int
x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert)
{
int i;
for (i = 0; i < sk_X509_num(ctx->roots); i++) {
if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0)
return 1;
}
return 0;
}
static int
x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx,
struct x509_verify_chain *chain)
{
size_t depth;
X509 *last = x509_verify_chain_last(chain);
if (ctx->xsc == NULL)
return 1;
depth = sk_X509_num(chain->certs);
if (depth > 0)
depth--;
ctx->xsc->last_untrusted = depth ? depth - 1 : 0;
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, last, depth,
X509_V_ERR_OUT_OF_MEM, 0);
return 1;
}
/* 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)
{
size_t depth;
X509 *last = x509_verify_chain_last(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);
/*
* 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.
*/
if (ctx->xsc != NULL) {
if (!x509_verify_ctx_set_xsc_chain(ctx, chain))
return 0;
/*
* 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))
return 0;
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))
return 0;
}
if (!x509_vfy_check_revocation(ctx->xsc))
return 0;
if (!x509_vfy_check_policy(ctx->xsc))
return 0;
}
/*
* no xsc means we are being called from the non-legacy API,
* 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 (ctx->xsc != NULL)
return (ctx->xsc->check_issued(ctx->xsc, child, parent));
/* XXX key usage */
return X509_check_issued(child, parent) != X509_V_OK;
}
static int
x509_verify_parent_signature(X509 *parent, X509 *child,
unsigned char *child_md, int *error)
{
unsigned char parent_md[EVP_MAX_MD_SIZE] = { 0 };
EVP_PKEY *pkey;
int cached;
int ret = 0;
/* Use cached value if we have it */
if (child_md != NULL) {
if (!X509_digest(parent, X509_VERIFY_CERT_HASH, parent_md,
NULL))
return 0;
if ((cached = x509_issuer_cache_find(parent_md, child_md)) >= 0)
return cached;
}
/* Check signature. Did parent sign child? */
if ((pkey = X509_get_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 */
if (child_md != NULL)
x509_issuer_cache_add(parent_md, child_md, ret);
EVP_PKEY_free(pkey);
return ret;
}
static int
x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
unsigned char *cert_md, int is_root_cert, X509 *candidate,
struct x509_verify_chain *current_chain)
{
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, cert_md,
&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)) {
x509_verify_chain_free(new_chain);
return 0;
}
if (x509_verify_cert_error(ctx, candidate, depth, X509_V_OK, 1)) {
(void) x509_verify_ctx_add_chain(ctx, new_chain);
goto done;
}
}
x509_verify_build_chains(ctx, candidate, new_chain);
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)
{
unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 };
X509 *candidate;
int i, depth, count;
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;
if (!X509_digest(cert, X509_VERIFY_CERT_HASH, cert_md, NULL) &&
!x509_verify_cert_error(ctx, cert, depth,
X509_V_ERR_UNSPECIFIED, 0))
return;
count = ctx->chains_count;
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
ctx->error_depth = depth;
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)) {
x509_verify_consider_candidate(ctx, cert,
cert_md, 1, candidate, current_chain);
}
}
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,
cert_md, 0, candidate, current_chain);
}
}
}
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;
(void) ctx->xsc->verify_cb(1, ctx->xsc);
}
} else if (ctx->error_depth == depth) {
(void) x509_verify_cert_error(ctx, cert, depth,
ctx->error, 0);
}
}
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)
return x509_vfy_check_id(ctx->xsc);
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;
}
int
x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, int notafter)
{
int type;
memset(tm, 0, sizeof(*tm));
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.
*/
if (timegm(tm) == -1)
return 0;
return 1;
}
static int
x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1,
time_t *cmp_time, int *error)
{
struct tm cert_tm, when_tm;
time_t when;
if (cmp_time == NULL)
when = time(NULL);
else
when = *cmp_time;
if (!x509_verify_asn1_time_to_tm(cert_asn1, &cert_tm,
is_notafter)) {
*error = is_notafter ?
X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD :
X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
return 0;
}
if (gmtime_r(&when, &when_tm) == NULL) {
*error = X509_V_ERR_UNSPECIFIED;
return 0;
}
if (is_notafter) {
if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == -1) {
*error = X509_V_ERR_CERT_HAS_EXPIRED;
return 0;
}
} else {
if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == 1) {
*error = X509_V_ERR_CERT_NOT_YET_VALID;
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()) == NULL) {
err = X509_V_ERR_OUT_OF_MEM;
goto err;
}
if ((excluded = x509_constraints_names_new()) == 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 (!(cert->ex_flags & EXFLAG_SET)) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
x509v3_cache_extensions(cert);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
}
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;
}
/* XXX support proxy certs later in new api */
if (ctx->xsc == NULL && cert->ex_flags & EXFLAG_PROXY) {
ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
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_time(0, X509_get_notBefore(cert),
ctx->check_time, &ctx->error)) {
if (!x509_verify_cert_error(ctx, cert, depth,
ctx->error, 0))
return 0;
}
if (!x509_verify_cert_time(1, X509_get_notAfter(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, STACK_OF(X509) *roots)
{
struct x509_verify_ctx *ctx;
size_t max_depth;
if (xsc == NULL)
return NULL;
if ((ctx = x509_verify_ctx_new(roots)) == 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 (roots == NULL)
return NULL;
if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL)
return NULL;
if ((ctx->roots = X509_chain_up_ref(roots)) == 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;
if (ctx->roots == NULL || ctx->max_depth == 0) {
ctx->error = X509_V_ERR_INVALID_CALL;
return 0;
}
if (ctx->xsc != NULL) {
if (leaf != NULL || name != NULL) {
ctx->error = X509_V_ERR_INVALID_CALL;
return 0;
}
leaf = ctx->xsc->cert;
/*
* 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;
return 0;
}
if (!X509_up_ref(leaf)) {
ctx->error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
if (!sk_X509_push(ctx->xsc->chain, leaf)) {
X509_free(leaf);
ctx->error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
ctx->xsc->error_depth = 0;
ctx->xsc->current_cert = leaf;
}
if (!x509_verify_cert_valid(ctx, leaf, NULL))
return 0;
if (!x509_verify_cert_hostname(ctx, leaf, name))
return 0;
if ((current_chain = x509_verify_chain_new()) == NULL) {
ctx->error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) {
x509_verify_chain_free(current_chain);
return 0;
}
if (x509_verify_ctx_cert_is_root(ctx, leaf))
x509_verify_ctx_add_chain(ctx, current_chain);
else
x509_verify_build_chains(ctx, leaf, current_chain);
x509_verify_chain_free(current_chain);
/*
* 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 == 0)
ctx->error = X509_V_ERR_UNSPECIFIED;
/* Clear whatever errors happened if we have any validated chain */
if (ctx->chains_count > 0)
ctx->error = X509_V_OK;
if (ctx->xsc != NULL) {
ctx->xsc->error = ctx->error;
return ctx->xsc->verify_cb(ctx->chains_count, ctx->xsc);
}
return (ctx->chains_count);
}

2544
externals/libressl/crypto/x509/x509_vfy.c vendored Executable file

File diff suppressed because it is too large Load Diff

714
externals/libressl/crypto/x509/x509_vpm.c vendored Executable file
View File

@@ -0,0 +1,714 @@
/* $OpenBSD: x509_vpm.c,v 1.22 2020/09/14 08:10:04 beck 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 <stdio.h>
#include <string.h>
#include <openssl/buffer.h>
#include <openssl/crypto.h>
#include <openssl/lhash.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "vpm_int.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);
}
#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
/*
* Post 1.0.1 sk function "deep_copy". For the moment we simply make
* these take void * and use them directly without a glorious blob of
* obfuscating macros of dubious value in front of them. All this in
* preparation for a rototilling of safestack.h (likely inspired by
* this).
*/
static void *
sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void)
{
_STACK *sk = sk_void;
void *(*copy_func)(void *) = copy_func_void;
void (*free_func)(void *) = free_func_void;
_STACK *ret = sk_dup(sk);
size_t i;
if (ret == NULL)
return NULL;
for (i = 0; i < ret->num; i++) {
if (ret->data[i] == NULL)
continue;
ret->data[i] = copy_func(ret->data[i]);
if (ret->data[i] == NULL) {
size_t j;
for (j = 0; j < i; j++) {
if (ret->data[j] != NULL)
free_func(ret->data[j]);
}
sk_free(ret);
return NULL;
}
}
return ret;
}
static int
x509_param_set_hosts_internal(X509_VERIFY_PARAM_ID *id, 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 && id->hosts) {
string_stack_free(id->hosts);
id->hosts = NULL;
}
if (name == NULL || namelen == 0)
return 1;
copy = strndup(name, namelen);
if (copy == NULL)
return 0;
if (id->hosts == NULL &&
(id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
free(copy);
return 0;
}
if (!sk_OPENSSL_STRING_push(id->hosts, copy)) {
free(copy);
if (sk_OPENSSL_STRING_num(id->hosts) == 0) {
sk_OPENSSL_STRING_free(id->hosts);
id->hosts = NULL;
}
return 0;
}
return 1;
}
static void
x509_verify_param_zero(X509_VERIFY_PARAM *param)
{
X509_VERIFY_PARAM_ID *paramid;
if (!param)
return;
param->name = NULL;
param->purpose = 0;
param->trust = 0;
/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
param->inh_flags = 0;
param->flags = 0;
param->depth = -1;
if (param->policies) {
sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
param->policies = NULL;
}
paramid = param->id;
if (paramid->hosts) {
string_stack_free(paramid->hosts);
paramid->hosts = NULL;
}
free(paramid->peername);
paramid->peername = NULL;
free(paramid->email);
paramid->email = NULL;
paramid->emaillen = 0;
free(paramid->ip);
paramid->ip = NULL;
paramid->iplen = 0;
paramid->poisoned = 0;
}
X509_VERIFY_PARAM *
X509_VERIFY_PARAM_new(void)
{
X509_VERIFY_PARAM *param;
X509_VERIFY_PARAM_ID *paramid;
param = calloc(1, sizeof(X509_VERIFY_PARAM));
if (param == NULL)
return NULL;
paramid = calloc (1, sizeof(X509_VERIFY_PARAM_ID));
if (paramid == NULL) {
free(param);
return NULL;
}
param->id = paramid;
x509_verify_param_zero(param);
return param;
}
void
X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
{
if (param == NULL)
return;
x509_verify_param_zero(param);
free(param->id);
free(param);
}
/* This function determines how parameters are "inherited" from one structure
* to another. There are several different ways this can happen.
*
* 1. If a child structure needs to have its values initialized from a parent
* they are simply copied across. For example SSL_CTX copied to SSL.
* 2. If the structure should take on values only if they are currently unset.
* For example the values in an SSL structure will take appropriate value
* for SSL servers or clients but only if the application has not set new
* ones.
*
* The "inh_flags" field determines how this function behaves.
*
* Normally any values which are set in the default are not copied from the
* destination and verify flags are ORed together.
*
* If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
* to the destination. Effectively the values in "to" become default values
* which will be used only if nothing new is set in "from".
*
* If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
* they are set or not. Flags is still Ored though.
*
* If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
* of ORed.
*
* If X509_VP_FLAG_LOCKED is set then no values are copied.
*
* If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
* after the next call.
*/
/* Macro to test if a field should be copied from src to dest */
#define test_x509_verify_param_copy(field, def) \
(to_overwrite || \
((src->field != def) && (to_default || (dest->field == def))))
/* As above but for ID fields */
#define test_x509_verify_param_copy_id(idf, def) \
test_x509_verify_param_copy(id->idf, 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;
X509_VERIFY_PARAM_ID *id;
if (!src)
return 1;
id = src->id;
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;
}
/* Copy the host flags if and only if we're copying the host list */
if (test_x509_verify_param_copy_id(hosts, NULL)) {
if (dest->id->hosts) {
string_stack_free(dest->id->hosts);
dest->id->hosts = NULL;
}
if (id->hosts) {
dest->id->hosts =
sk_deep_copy(id->hosts, strdup, str_free);
if (dest->id->hosts == NULL)
return 0;
dest->id->hostflags = id->hostflags;
}
}
if (test_x509_verify_param_copy_id(email, NULL)) {
if (!X509_VERIFY_PARAM_set1_email(dest, id->email,
id->emaillen))
return 0;
}
if (test_x509_verify_param_copy_id(ip, NULL)) {
if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
return 0;
}
return 1;
}
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;
}
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;
}
int
X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
{
param->flags |= flags;
if (flags & X509_V_FLAG_POLICY_MASK)
param->flags |= X509_V_FLAG_POLICY_CHECK;
return 1;
}
int
X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
{
param->flags &= ~flags;
return 1;
}
unsigned long
X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
{
return param->flags;
}
int
X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
{
return X509_PURPOSE_set(&param->purpose, purpose);
}
int
X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
{
return X509_TRUST_set(&param->trust, trust);
}
void
X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
{
param->depth = depth;
}
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;
}
int
X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
{
if (!param->policies) {
param->policies = sk_ASN1_OBJECT_new_null();
if (!param->policies)
return 0;
}
if (!sk_ASN1_OBJECT_push(param->policies, policy))
return 0;
return 1;
}
int
X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
STACK_OF(ASN1_OBJECT) *policies)
{
int i;
ASN1_OBJECT *oid, *doid;
if (!param)
return 0;
if (param->policies)
sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
if (!policies) {
param->policies = NULL;
return 1;
}
param->policies = sk_ASN1_OBJECT_new_null();
if (!param->policies)
return 0;
for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
oid = sk_ASN1_OBJECT_value(policies, i);
doid = OBJ_dup(oid);
if (!doid)
return 0;
if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
ASN1_OBJECT_free(doid);
return 0;
}
}
param->flags |= X509_V_FLAG_POLICY_CHECK;
return 1;
}
int
X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
const char *name, size_t namelen)
{
if (x509_param_set_hosts_internal(param->id, SET_HOST, name, namelen))
return 1;
param->id->poisoned = 1;
return 0;
}
int
X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
const char *name, size_t namelen)
{
if (x509_param_set_hosts_internal(param->id, ADD_HOST, name, namelen))
return 1;
param->id->poisoned = 1;
return 0;
}
void
X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags)
{
param->id->hostflags = flags;
}
char *
X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
{
return param->id->peername;
}
int
X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
size_t emaillen)
{
if (x509_param_set1_internal(&param->id->email, &param->id->emaillen,
email, emaillen, 1))
return 1;
param->id->poisoned = 1;
return 0;
}
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 **)&param->id->ip, &param->id->iplen,
(char *)ip, iplen, 0))
return 1;
err:
param->id->poisoned = 1;
return 0;
}
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);
}
int
X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
{
return param->depth;
}
const char *
X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
{
return param->name;
}
static const X509_VERIFY_PARAM_ID _empty_id = { NULL };
#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
/*
* 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",
.depth = 100,
.trust = 0, /* XXX This is not the default trust value */
.id = vpm_empty_id
},
{
.name = "pkcs7",
.purpose = X509_PURPOSE_SMIME_SIGN,
.trust = X509_TRUST_EMAIL,
.depth = -1,
.id = vpm_empty_id
},
{
.name = "smime_sign",
.purpose = X509_PURPOSE_SMIME_SIGN,
.trust = X509_TRUST_EMAIL,
.depth = -1,
.id = vpm_empty_id
},
{
.name = "ssl_client",
.purpose = X509_PURPOSE_SSL_CLIENT,
.trust = X509_TRUST_SSL_CLIENT,
.depth = -1,
.id = vpm_empty_id
},
{
.name = "ssl_server",
.purpose = X509_PURPOSE_SSL_SERVER,
.trust = X509_TRUST_SSL_SERVER,
.depth = -1,
.id = vpm_empty_id
}
};
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;
if (!param_table) {
param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
if (!param_table)
return 0;
} else {
size_t idx;
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);
}
}
if (!sk_X509_VERIFY_PARAM_push(param_table, param))
return 0;
return 1;
}
int
X509_VERIFY_PARAM_get_count(void)
{
int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
if (param_table)
num += sk_X509_VERIFY_PARAM_num(param_table);
return num;
}
const
X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
{
int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
if (id < num)
return default_table + id;
return sk_X509_VERIFY_PARAM_value(param_table, id - num);
}
const
X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
{
X509_VERIFY_PARAM pm;
unsigned int i, limit;
pm.name = (char *)name;
if (param_table) {
size_t idx;
if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1)
return sk_X509_VERIFY_PARAM_value(param_table, idx);
}
limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
for (i = 0; i < limit; i++) {
if (strcmp(default_table[i].name, name) == 0) {
return &default_table[i];
}
}
return NULL;
}
void
X509_VERIFY_PARAM_table_cleanup(void)
{
if (param_table)
sk_X509_VERIFY_PARAM_pop_free(param_table,
X509_VERIFY_PARAM_free);
param_table = NULL;
}

210
externals/libressl/crypto/x509/x509cset.c vendored Executable file
View File

@@ -0,0 +1,210 @@
/* $OpenBSD: x509cset.c,v 1.14 2018/02/22 17:01:44 jsing 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
int
X509_CRL_up_ref(X509_CRL *x)
{
int refs = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
return (refs > 1) ? 1 : 0;
}
int
X509_CRL_set_version(X509_CRL *x, long version)
{
if (x == NULL)
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));
}
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));
}
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);
}
int
X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
{
return X509_CRL_set_lastUpdate(x, tm);
}
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);
}
int
X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
{
return X509_CRL_set_nextUpdate(x, tm);
}
int
X509_CRL_sort(X509_CRL *c)
{
int i;
X509_REVOKED *r;
/* 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;
}
const STACK_OF(X509_EXTENSION) *
X509_REVOKED_get0_extensions(const X509_REVOKED *x)
{
return x->extensions;
}
const ASN1_TIME *
X509_REVOKED_get0_revocationDate(const X509_REVOKED *x)
{
return x->revocationDate;
}
const ASN1_INTEGER *
X509_REVOKED_get0_serialNumber(const X509_REVOKED *x)
{
return x->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);
}
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);
}

413
externals/libressl/crypto/x509/x509name.c vendored Executable file
View File

@@ -0,0 +1,413 @@
/* $OpenBSD: x509name.c,v 1.26 2018/05/30 15:35:45 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/stack.h>
#include <openssl/x509.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));
}
int
X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
int len)
{
int i;
ASN1_STRING *data;
i = X509_NAME_get_index_by_OBJ(name, obj, -1);
if (i < 0)
return (-1);
data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
i = (data->length > (len - 1)) ? (len - 1) : data->length;
if (buf == NULL)
return (data->length);
if (i >= 0) {
memcpy(buf, data->data, i);
buf[i] = '\0';
}
return (i);
}
int
X509_NAME_entry_count(const X509_NAME *name)
{
if (name == NULL)
return (0);
return (sk_X509_NAME_ENTRY_num(name->entries));
}
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));
}
/* NOTE: you should be passsing -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);
}
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));
}
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);
}
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;
}
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;
}
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;
}
/* 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);
}
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;
}
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;
}
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);
}
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);
}
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);
}
ASN1_OBJECT *
X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne)
{
if (ne == NULL)
return (NULL);
return (ne->object);
}
ASN1_STRING *
X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne)
{
if (ne == NULL)
return (NULL);
return (ne->value);
}
int
X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
{
return (ne->set);
}

100
externals/libressl/crypto/x509/x509rset.c vendored Executable file
View File

@@ -0,0 +1,100 @@
/* $OpenBSD: x509rset.c,v 1.7 2018/08/24 19:55:58 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
int
X509_REQ_set_version(X509_REQ *x, long version)
{
if (x == NULL)
return (0);
return (ASN1_INTEGER_set(x->req_info->version, version));
}
long
X509_REQ_get_version(const X509_REQ *x)
{
return ASN1_INTEGER_get(x->req_info->version);
}
int
X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
{
if ((x == NULL) || (x->req_info == NULL))
return (0);
return (X509_NAME_set(&x->req_info->subject, name));
}
X509_NAME *
X509_REQ_get_subject_name(const X509_REQ *x)
{
return x->req_info->subject;
}
int
X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
{
if ((x == NULL) || (x->req_info == NULL))
return (0);
return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
}

132
externals/libressl/crypto/x509/x509spki.c vendored Executable file
View File

@@ -0,0 +1,132 @@
/* $OpenBSD: x509spki.c,v 1.14 2019/05/23 02:08:34 bcook 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/x509.h>
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));
}
EVP_PKEY *
NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
{
if ((x == NULL) || (x->spkac == NULL))
return (NULL);
return (X509_PUBKEY_get(x->spkac->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;
}
/* 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;
}

123
externals/libressl/crypto/x509/x509type.c vendored Executable file
View File

@@ -0,0 +1,123 @@
/* $OpenBSD: x509type.c,v 1.13 2018/05/30 15:59:33 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 <stdio.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
int
X509_certificate_type(const X509 *x, const EVP_PKEY *pkey)
{
const EVP_PKEY *pk = pkey;
int ret = 0, i;
if (x == NULL)
return (0);
if (pk == NULL) {
if ((pk = X509_get0_pubkey(x)) == NULL)
return (0);
}
switch (pk->type) {
case EVP_PKEY_RSA:
ret = EVP_PK_RSA|EVP_PKT_SIGN|EVP_PKT_ENC;
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_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;
}
i = OBJ_obj2nid(x->sig_alg->algorithm);
if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
switch (i) {
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;
}
}
/* /8 because it's 1024 bits we look for, not bytes */
if (EVP_PKEY_size(pk) <= 1024 / 8)
ret |= EVP_PKT_EXP;
return (ret);
}

609
externals/libressl/crypto/x509/x_all.c vendored Executable file
View File

@@ -0,0 +1,609 @@
/* $OpenBSD: x_all.c,v 1.23 2016/12/30 15:24:51 jsing 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 <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
X509 *
d2i_X509_bio(BIO *bp, X509 **x509)
{
return ASN1_item_d2i_bio(&X509_it, bp, x509);
}
int
i2d_X509_bio(BIO *bp, X509 *x509)
{
return ASN1_item_i2d_bio(&X509_it, bp, x509);
}
X509 *
d2i_X509_fp(FILE *fp, X509 **x509)
{
return ASN1_item_d2i_fp(&X509_it, fp, x509);
}
int
i2d_X509_fp(FILE *fp, X509 *x509)
{
return ASN1_item_i2d_fp(&X509_it, fp, x509);
}
X509_CRL *
d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
{
return ASN1_item_d2i_bio(&X509_CRL_it, bp, crl);
}
int
i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
{
return ASN1_item_i2d_bio(&X509_CRL_it, bp, crl);
}
X509_CRL *
d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
{
return ASN1_item_d2i_fp(&X509_CRL_it, fp, crl);
}
int
i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
{
return ASN1_item_i2d_fp(&X509_CRL_it, fp, crl);
}
PKCS7 *
d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
{
return ASN1_item_d2i_bio(&PKCS7_it, bp, p7);
}
int
i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
{
return ASN1_item_i2d_bio(&PKCS7_it, bp, p7);
}
PKCS7 *
d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
{
return ASN1_item_d2i_fp(&PKCS7_it, fp, p7);
}
int
i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
{
return ASN1_item_i2d_fp(&PKCS7_it, fp, p7);
}
X509_REQ *
d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
{
return ASN1_item_d2i_bio(&X509_REQ_it, bp, req);
}
int
i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
{
return ASN1_item_i2d_bio(&X509_REQ_it, bp, req);
}
X509_REQ *
d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
{
return ASN1_item_d2i_fp(&X509_REQ_it, fp, req);
}
int
i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
{
return ASN1_item_i2d_fp(&X509_REQ_it, fp, req);
}
#ifndef OPENSSL_NO_RSA
RSA *
d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(&RSAPrivateKey_it, bp, rsa);
}
int
i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(&RSAPrivateKey_it, bp, rsa);
}
RSA *
d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
{
return ASN1_item_d2i_fp(&RSAPrivateKey_it, fp, rsa);
}
int
i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(&RSAPrivateKey_it, fp, rsa);
}
RSA *
d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(&RSAPublicKey_it, bp, rsa);
}
int
i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(&RSAPublicKey_it, bp, rsa);
}
RSA *
d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
{
return ASN1_item_d2i_fp(&RSAPublicKey_it, fp, rsa);
}
int
i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(&RSAPublicKey_it, fp, rsa);
}
RSA *
d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
{
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
}
int
i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
{
return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa);
}
int
i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
{
return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa);
}
RSA *
d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
{
return ASN1_d2i_fp((void *(*)(void))RSA_new,
(D2I_OF(void))d2i_RSA_PUBKEY, fp, (void **)rsa);
}
#endif
#ifndef OPENSSL_NO_DSA
DSA *
d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
{
return ASN1_item_d2i_bio(&DSAPrivateKey_it, bp, dsa);
}
int
i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
{
return ASN1_item_i2d_bio(&DSAPrivateKey_it, bp, dsa);
}
DSA *
d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
{
return ASN1_item_d2i_fp(&DSAPrivateKey_it, fp, dsa);
}
int
i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
{
return ASN1_item_i2d_fp(&DSAPrivateKey_it, fp, dsa);
}
DSA *
d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
{
return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
}
int
i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
{
return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa);
}
DSA *
d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
{
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
}
int
i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
{
return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa);
}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *
d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
{
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
}
int
i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
{
return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
}
EC_KEY *
d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
{
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
}
int
i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
}
EC_KEY *
d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
{
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
}
int
i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
{
return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
}
EC_KEY *
d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
{
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
}
int
i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
}
#endif
X509_SIG *
d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
{
return ASN1_item_d2i_bio(&X509_SIG_it, bp, p8);
}
int
i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
{
return ASN1_item_i2d_bio(&X509_SIG_it, bp, p8);
}
X509_SIG *
d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
{
return ASN1_item_d2i_fp(&X509_SIG_it, fp, p8);
}
int
i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
{
return ASN1_item_i2d_fp(&X509_SIG_it, fp, p8);
}
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);
}
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);
}
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);
}
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);
}
EVP_PKEY *
d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
{
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey,
bp, a);
}
int
i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
}
EVP_PKEY *
d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
{
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey,
fp, a);
}
int
i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
}
EVP_PKEY *
d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
{
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
}
int
i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
}
int
i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
}
EVP_PKEY *
d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
{
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
}
int
i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
{
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;
}
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;
}
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));
}
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));
}
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));
}
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));
}
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);
}
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));
}
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);
}
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));
}
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);
}
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));
}
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);
}
int
X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
unsigned int *len)
{
return (ASN1_item_digest(&X509_it, type, (char *)data,
md, len));
}
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, (char *)data,
md, len));
}
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, (char *)data,
md, len));
}
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, (char *)data,
md, len));
}
int
PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
const EVP_MD *type, unsigned char *md, unsigned int *len)
{
return(ASN1_item_digest(&PKCS7_ISSUER_AND_SERIAL_it, type,
(char *)data, md, len));
}
int
X509_up_ref(X509 *x)
{
int i = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
return i > 1 ? 1 : 0;
}