check in v3.8.1 source
This commit is contained in:
413
crypto/x509/by_dir.c
Normal file
413
crypto/x509/by_dir.c
Normal file
@@ -0,0 +1,413 @@
|
||||
/* $OpenBSD: by_dir.c,v 1.44 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#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/x509.h>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
typedef struct lookup_dir_hashes_st {
|
||||
unsigned long hash;
|
||||
int suffix;
|
||||
} BY_DIR_HASH;
|
||||
|
||||
typedef struct lookup_dir_entry_st {
|
||||
char *dir;
|
||||
int dir_type;
|
||||
STACK_OF(BY_DIR_HASH) *hashes;
|
||||
} BY_DIR_ENTRY;
|
||||
|
||||
typedef struct lookup_dir_st {
|
||||
BUF_MEM *buffer;
|
||||
STACK_OF(BY_DIR_ENTRY) *dirs;
|
||||
} BY_DIR;
|
||||
|
||||
DECLARE_STACK_OF(BY_DIR_HASH)
|
||||
DECLARE_STACK_OF(BY_DIR_ENTRY)
|
||||
|
||||
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
|
||||
char **ret);
|
||||
static int new_dir(X509_LOOKUP *lu);
|
||||
static void free_dir(X509_LOOKUP *lu);
|
||||
static int add_cert_dir(BY_DIR *ctx, const char *dir, int type);
|
||||
static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
|
||||
X509_OBJECT *ret);
|
||||
|
||||
static 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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_hash_dir);
|
||||
|
||||
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(*a))) == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if ((a->buffer = BUF_MEM_new()) == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
free(a);
|
||||
return 0;
|
||||
}
|
||||
a->dirs = NULL;
|
||||
lu->method_data = (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);
|
||||
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;
|
||||
sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
|
||||
BUF_MEM_free(a->buffer);
|
||||
free(a);
|
||||
}
|
||||
|
||||
static int
|
||||
add_cert_dir(BY_DIR *ctx, const char *dir, int type)
|
||||
{
|
||||
int j;
|
||||
const char *s, *ss, *p;
|
||||
ptrdiff_t len;
|
||||
|
||||
if (dir == NULL || !*dir) {
|
||||
X509error(X509_R_INVALID_DIRECTORY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = dir;
|
||||
p = s;
|
||||
do {
|
||||
if ((*p == ':') || (*p == '\0')) {
|
||||
BY_DIR_ENTRY *ent;
|
||||
|
||||
ss = s;
|
||||
s = p + 1;
|
||||
len = p - ss;
|
||||
if (len == 0)
|
||||
continue;
|
||||
for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
|
||||
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
|
||||
if (strlen(ent->dir) == (size_t)len &&
|
||||
strncmp(ent->dir, ss, (size_t)len) == 0)
|
||||
break;
|
||||
}
|
||||
if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
|
||||
continue;
|
||||
if (ctx->dirs == NULL) {
|
||||
ctx->dirs = sk_BY_DIR_ENTRY_new_null();
|
||||
if (ctx->dirs == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ent = malloc(sizeof(*ent));
|
||||
if (ent == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
ent->dir_type = type;
|
||||
ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
|
||||
ent->dir = strndup(ss, (size_t)len);
|
||||
if (ent->dir == NULL || ent->hashes == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
by_dir_entry_free(ent);
|
||||
return 0;
|
||||
}
|
||||
if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
by_dir_entry_free(ent);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} while (*p++ != '\0');
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
|
||||
X509_OBJECT *ret)
|
||||
{
|
||||
BY_DIR *ctx;
|
||||
union {
|
||||
struct {
|
||||
X509 st_x509;
|
||||
X509_CINF st_x509_cinf;
|
||||
} x509;
|
||||
struct {
|
||||
X509_CRL st_crl;
|
||||
X509_CRL_INFO st_crl_info;
|
||||
} crl;
|
||||
} data;
|
||||
int ok = 0;
|
||||
int i, j, k;
|
||||
unsigned long h;
|
||||
BUF_MEM *b = NULL;
|
||||
X509_OBJECT stmp, *tmp;
|
||||
const char *postfix="";
|
||||
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
stmp.type = type;
|
||||
if (type == X509_LU_X509) {
|
||||
data.x509.st_x509.cert_info = &data.x509.st_x509_cinf;
|
||||
data.x509.st_x509_cinf.subject = name;
|
||||
stmp.data.x509 = &data.x509.st_x509;
|
||||
postfix="";
|
||||
} else if (type == X509_LU_CRL) {
|
||||
data.crl.st_crl.crl = &data.crl.st_crl_info;
|
||||
data.crl.st_crl_info.issuer = name;
|
||||
stmp.data.crl = &data.crl.st_crl;
|
||||
postfix="r";
|
||||
} else {
|
||||
X509error(X509_R_WRONG_LOOKUP_TYPE);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if ((b = BUF_MEM_new()) == NULL) {
|
||||
X509error(ERR_R_BUF_LIB);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ctx = (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);
|
||||
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
|
||||
/* If a CRL, update the last file suffix added for this */
|
||||
if (type == X509_LU_CRL) {
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
/*
|
||||
* Look for entry again in case another thread added
|
||||
* an entry first.
|
||||
*/
|
||||
if (hent == NULL) {
|
||||
htmp.hash = h;
|
||||
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
|
||||
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
|
||||
}
|
||||
if (hent == NULL) {
|
||||
hent = malloc(sizeof(*hent));
|
||||
if (hent == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
ok = 0;
|
||||
goto finish;
|
||||
}
|
||||
hent->hash = h;
|
||||
hent->suffix = k;
|
||||
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
free(hent);
|
||||
ok = 0;
|
||||
goto finish;
|
||||
}
|
||||
} else if (hent->suffix < k)
|
||||
hent->suffix = k;
|
||||
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
|
||||
}
|
||||
|
||||
if (tmp != NULL) {
|
||||
ok = 1;
|
||||
ret->type = tmp->type;
|
||||
memcpy(&ret->data, &tmp->data, sizeof(ret->data));
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
finish:
|
||||
BUF_MEM_free(b);
|
||||
return ok;
|
||||
}
|
||||
273
crypto/x509/by_file.c
Normal file
273
crypto/x509/by_file.c
Normal file
@@ -0,0 +1,273 @@
|
||||
/* $OpenBSD: by_file.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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/x509.h>
|
||||
|
||||
#include "x509_local.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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_file);
|
||||
|
||||
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;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
|
||||
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
|
||||
X509error(ERR_R_SYS_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (type == X509_FILETYPE_PEM) {
|
||||
for (;;) {
|
||||
x = PEM_read_bio_X509_AUX(in, NULL, NULL, "");
|
||||
if (x == NULL) {
|
||||
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
|
||||
PEM_R_NO_START_LINE) && (count > 0)) {
|
||||
ERR_clear_error();
|
||||
break;
|
||||
} else {
|
||||
X509error(ERR_R_PEM_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
i = X509_STORE_add_cert(ctx->store_ctx, x);
|
||||
if (!i)
|
||||
goto err;
|
||||
count++;
|
||||
X509_free(x);
|
||||
x = NULL;
|
||||
}
|
||||
ret = count;
|
||||
} else if (type == X509_FILETYPE_ASN1) {
|
||||
x = d2i_X509_bio(in, NULL);
|
||||
if (x == NULL) {
|
||||
X509error(ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
i = X509_STORE_add_cert(ctx->store_ctx, x);
|
||||
if (!i)
|
||||
goto err;
|
||||
ret = i;
|
||||
} else {
|
||||
X509error(X509_R_BAD_X509_FILETYPE);
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
X509_free(x);
|
||||
BIO_free(in);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_load_cert_file);
|
||||
|
||||
int
|
||||
X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
|
||||
{
|
||||
int ret = 0;
|
||||
BIO *in = NULL;
|
||||
int i, count = 0;
|
||||
X509_CRL *x = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
|
||||
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
|
||||
X509error(ERR_R_SYS_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (type == X509_FILETYPE_PEM) {
|
||||
for (;;) {
|
||||
x = PEM_read_bio_X509_CRL(in, NULL, NULL, "");
|
||||
if (x == NULL) {
|
||||
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
|
||||
PEM_R_NO_START_LINE) && (count > 0)) {
|
||||
ERR_clear_error();
|
||||
break;
|
||||
} else {
|
||||
X509error(ERR_R_PEM_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
i = X509_STORE_add_crl(ctx->store_ctx, x);
|
||||
if (!i)
|
||||
goto err;
|
||||
count++;
|
||||
X509_CRL_free(x);
|
||||
x = NULL;
|
||||
}
|
||||
ret = count;
|
||||
} else if (type == X509_FILETYPE_ASN1) {
|
||||
x = d2i_X509_CRL_bio(in, NULL);
|
||||
if (x == NULL) {
|
||||
X509error(ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
i = X509_STORE_add_crl(ctx->store_ctx, x);
|
||||
if (!i)
|
||||
goto err;
|
||||
ret = i;
|
||||
} else {
|
||||
X509error(X509_R_BAD_X509_FILETYPE);
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
X509_CRL_free(x);
|
||||
BIO_free(in);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_load_crl_file);
|
||||
|
||||
int
|
||||
X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
|
||||
{
|
||||
STACK_OF(X509_INFO) *inf;
|
||||
X509_INFO *itmp;
|
||||
BIO *in;
|
||||
int i, count = 0;
|
||||
|
||||
if (type != X509_FILETYPE_PEM)
|
||||
return X509_load_cert_file(ctx, file, type);
|
||||
in = BIO_new_file(file, "r");
|
||||
if (!in) {
|
||||
X509error(ERR_R_SYS_LIB);
|
||||
return 0;
|
||||
}
|
||||
inf = PEM_X509_INFO_read_bio(in, NULL, NULL, "");
|
||||
BIO_free(in);
|
||||
if (!inf) {
|
||||
X509error(ERR_R_PEM_LIB);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < sk_X509_INFO_num(inf); i++) {
|
||||
itmp = sk_X509_INFO_value(inf, i);
|
||||
if (itmp->x509) {
|
||||
X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
|
||||
count++;
|
||||
}
|
||||
if (itmp->crl) {
|
||||
X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count == 0)
|
||||
X509error(X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
|
||||
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||
return count;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_load_cert_crl_file);
|
||||
141
crypto/x509/by_mem.c
Normal file
141
crypto/x509/by_mem.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/* $OpenBSD: by_mem.c,v 1.8 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "x509_local.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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_mem);
|
||||
|
||||
static int
|
||||
by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf,
|
||||
long type, char **ret)
|
||||
{
|
||||
STACK_OF(X509_INFO) *inf = NULL;
|
||||
const struct iovec *iov;
|
||||
X509_INFO *itmp;
|
||||
BIO *in = NULL;
|
||||
int i, count = 0, ok = 0;
|
||||
|
||||
iov = (const struct iovec *)buf;
|
||||
|
||||
if (!(cmd == X509_L_MEM && type == X509_FILETYPE_PEM))
|
||||
goto done;
|
||||
|
||||
if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL)
|
||||
goto done;
|
||||
|
||||
if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < sk_X509_INFO_num(inf); i++) {
|
||||
itmp = sk_X509_INFO_value(inf, i);
|
||||
if (itmp->x509) {
|
||||
ok = X509_STORE_add_cert(lu->store_ctx, itmp->x509);
|
||||
if (!ok)
|
||||
goto done;
|
||||
count++;
|
||||
}
|
||||
if (itmp->crl) {
|
||||
ok = X509_STORE_add_crl(lu->store_ctx, itmp->crl);
|
||||
if (!ok)
|
||||
goto done;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ok = count != 0;
|
||||
done:
|
||||
if (count == 0)
|
||||
X509error(ERR_R_PEM_LIB);
|
||||
if (inf != NULL)
|
||||
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||
if (in != NULL)
|
||||
BIO_free(in);
|
||||
return (ok);
|
||||
}
|
||||
2045
crypto/x509/x509_addr.c
Normal file
2045
crypto/x509/x509_addr.c
Normal file
File diff suppressed because it is too large
Load Diff
237
crypto/x509/x509_akey.c
Normal file
237
crypto/x509/x509_akey.c
Normal 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;
|
||||
}
|
||||
128
crypto/x509/x509_akeya.c
Normal file
128
crypto/x509/x509_akeya.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/* $OpenBSD: x509_akeya.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_AUTHORITY_KEYID);
|
||||
|
||||
int
|
||||
i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_KEYID_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_AUTHORITY_KEYID);
|
||||
|
||||
AUTHORITY_KEYID *
|
||||
AUTHORITY_KEYID_new(void)
|
||||
{
|
||||
return (AUTHORITY_KEYID *)ASN1_item_new(&AUTHORITY_KEYID_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(AUTHORITY_KEYID_new);
|
||||
|
||||
void
|
||||
AUTHORITY_KEYID_free(AUTHORITY_KEYID *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_KEYID_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(AUTHORITY_KEYID_free);
|
||||
782
crypto/x509/x509_alt.c
Normal file
782
crypto/x509/x509_alt.c
Normal file
@@ -0,0 +1,782 @@
|
||||
/* $OpenBSD: x509_alt.c,v 1.16 2023/08/30 00:49:32 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(i2v_GENERAL_NAMES);
|
||||
|
||||
STACK_OF(CONF_VALUE) *
|
||||
i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen,
|
||||
STACK_OF(CONF_VALUE) *ret)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *free_ret = NULL;
|
||||
unsigned char *p;
|
||||
char oline[256], htmp[5];
|
||||
int i;
|
||||
|
||||
if (ret == NULL) {
|
||||
if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (gen->type) {
|
||||
case GEN_OTHERNAME:
|
||||
if (!X509V3_add_value("othername", "<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;
|
||||
}
|
||||
LCRYPTO_ALIAS(i2v_GENERAL_NAME);
|
||||
|
||||
int
|
||||
GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
|
||||
{
|
||||
unsigned char *p;
|
||||
int i;
|
||||
|
||||
switch (gen->type) {
|
||||
case GEN_OTHERNAME:
|
||||
BIO_printf(out, "othername:<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->length,
|
||||
gen->d.ia5->data);
|
||||
break;
|
||||
|
||||
case GEN_DNS:
|
||||
BIO_printf(out, "DNS:%.*s", gen->d.ia5->length,
|
||||
gen->d.ia5->data);
|
||||
break;
|
||||
|
||||
case GEN_URI:
|
||||
BIO_printf(out, "URI:%.*s", gen->d.ia5->length,
|
||||
gen->d.ia5->data);
|
||||
break;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
BIO_printf(out, "DirName: ");
|
||||
X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
|
||||
break;
|
||||
|
||||
case GEN_IPADD:
|
||||
p = gen->d.ip->data;
|
||||
if (gen->d.ip->length == 4)
|
||||
BIO_printf(out, "IP Address:%d.%d.%d.%d",
|
||||
p[0], p[1], p[2], p[3]);
|
||||
else if (gen->d.ip->length == 16) {
|
||||
BIO_printf(out, "IP Address");
|
||||
for (i = 0; i < 8; i++) {
|
||||
BIO_printf(out, ":%X", p[0] << 8 | p[1]);
|
||||
p += 2;
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
} else {
|
||||
BIO_printf(out, "IP Address:<invalid>");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
BIO_printf(out, "Registered ID");
|
||||
i2a_ASN1_OBJECT(out, gen->d.rid);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_print);
|
||||
|
||||
static GENERAL_NAMES *
|
||||
v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
int i;
|
||||
|
||||
if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL &&
|
||||
strcmp(cnf->value, "copy") == 0) {
|
||||
if (!copy_issuer(ctx, gens))
|
||||
goto err;
|
||||
} else {
|
||||
GENERAL_NAME *gen;
|
||||
if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
|
||||
goto err;
|
||||
if (sk_GENERAL_NAME_push(gens, gen) == 0) {
|
||||
GENERAL_NAME_free(gen);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return gens;
|
||||
|
||||
err:
|
||||
sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Append subject altname of issuer to issuer alt name of subject */
|
||||
|
||||
static int
|
||||
copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
|
||||
{
|
||||
GENERAL_NAMES *ialt = NULL;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
X509_EXTENSION *ext;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if (ctx && (ctx->flags == CTX_TEST))
|
||||
return 1;
|
||||
if (!ctx || !ctx->issuer_cert) {
|
||||
X509V3error(X509V3_R_NO_ISSUER_DETAILS);
|
||||
goto err;
|
||||
}
|
||||
i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
|
||||
if (i < 0)
|
||||
return 1;
|
||||
if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
|
||||
!(ialt = X509V3_EXT_d2i(ext))) {
|
||||
X509V3error(X509V3_R_ISSUER_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
|
||||
GENERAL_NAME *val = sk_GENERAL_NAME_value(ialt, i);
|
||||
|
||||
if ((gen = GENERAL_NAME_dup(val)) == NULL)
|
||||
goto err;
|
||||
if (!sk_GENERAL_NAME_push(gens, gen)) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
gen = NULL;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
|
||||
GENERAL_NAME_free(gen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GENERAL_NAMES *
|
||||
v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
int i;
|
||||
|
||||
if (!(gens = sk_GENERAL_NAME_new_null())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (!name_cmp(cnf->name, "email") && cnf->value &&
|
||||
!strcmp(cnf->value, "copy")) {
|
||||
if (!copy_email(ctx, gens, 0))
|
||||
goto err;
|
||||
} else if (!name_cmp(cnf->name, "email") && cnf->value &&
|
||||
!strcmp(cnf->value, "move")) {
|
||||
if (!copy_email(ctx, gens, 1))
|
||||
goto err;
|
||||
} else {
|
||||
GENERAL_NAME *gen;
|
||||
if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
|
||||
goto err;
|
||||
if (sk_GENERAL_NAME_push(gens, gen) == 0) {
|
||||
GENERAL_NAME_free(gen);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return gens;
|
||||
|
||||
err:
|
||||
sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copy any email addresses in a certificate or request to
|
||||
* GENERAL_NAMES
|
||||
*/
|
||||
|
||||
static int
|
||||
copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
|
||||
{
|
||||
X509_NAME *nm;
|
||||
ASN1_IA5STRING *email = NULL;
|
||||
X509_NAME_ENTRY *ne;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
int i;
|
||||
|
||||
if (ctx != NULL && ctx->flags == CTX_TEST)
|
||||
return 1;
|
||||
if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
|
||||
X509V3error(X509V3_R_NO_SUBJECT_DETAILS);
|
||||
goto err;
|
||||
}
|
||||
/* Find the subject name */
|
||||
if (ctx->subject_cert)
|
||||
nm = X509_get_subject_name(ctx->subject_cert);
|
||||
else
|
||||
nm = X509_REQ_get_subject_name(ctx->subject_req);
|
||||
|
||||
/* Now add any email address(es) to STACK */
|
||||
i = -1;
|
||||
while ((i = X509_NAME_get_index_by_NID(nm,
|
||||
NID_pkcs9_emailAddress, i)) >= 0) {
|
||||
ne = X509_NAME_get_entry(nm, i);
|
||||
email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
|
||||
if (move_p) {
|
||||
X509_NAME_delete_entry(nm, i);
|
||||
X509_NAME_ENTRY_free(ne);
|
||||
i--;
|
||||
}
|
||||
if (!email || !(gen = GENERAL_NAME_new())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
gen->d.ia5 = email;
|
||||
email = NULL;
|
||||
gen->type = GEN_EMAIL;
|
||||
if (!sk_GENERAL_NAME_push(gens, gen)) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
gen = NULL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
GENERAL_NAME_free(gen);
|
||||
ASN1_IA5STRING_free(email);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GENERAL_NAMES *
|
||||
v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
GENERAL_NAME *gen;
|
||||
GENERAL_NAMES *gens = NULL;
|
||||
CONF_VALUE *cnf;
|
||||
int i;
|
||||
|
||||
if (!(gens = sk_GENERAL_NAME_new_null())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
|
||||
goto err;
|
||||
if (sk_GENERAL_NAME_push(gens, gen) == 0) {
|
||||
GENERAL_NAME_free(gen);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return gens;
|
||||
|
||||
err:
|
||||
sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(v2i_GENERAL_NAMES);
|
||||
|
||||
GENERAL_NAME *
|
||||
v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
CONF_VALUE *cnf)
|
||||
{
|
||||
return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
|
||||
}
|
||||
LCRYPTO_ALIAS(v2i_GENERAL_NAME);
|
||||
|
||||
GENERAL_NAME *
|
||||
a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, int gen_type, const char *value, int is_nc)
|
||||
{
|
||||
char is_string = 0;
|
||||
GENERAL_NAME *gen = NULL;
|
||||
|
||||
if (!value) {
|
||||
X509V3error(X509V3_R_MISSING_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (out)
|
||||
gen = out;
|
||||
else {
|
||||
gen = GENERAL_NAME_new();
|
||||
if (gen == NULL) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (gen_type) {
|
||||
case GEN_URI:
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
is_string = 1;
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
if (!(obj = OBJ_txt2obj(value, 0))) {
|
||||
X509V3error(X509V3_R_BAD_OBJECT);
|
||||
ERR_asprintf_error_data("value=%s", value);
|
||||
goto err;
|
||||
}
|
||||
gen->d.rid = obj;
|
||||
}
|
||||
break;
|
||||
|
||||
case GEN_IPADD:
|
||||
if (is_nc)
|
||||
gen->d.ip = a2i_IPADDRESS_NC(value);
|
||||
else
|
||||
gen->d.ip = a2i_IPADDRESS(value);
|
||||
if (gen->d.ip == NULL) {
|
||||
X509V3error(X509V3_R_BAD_IP_ADDRESS);
|
||||
ERR_asprintf_error_data("value=%s", value);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
if (!do_dirname(gen, value, ctx)) {
|
||||
X509V3error(X509V3_R_DIRNAME_ERROR);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
if (!do_othername(gen, value, ctx)) {
|
||||
X509V3error(X509V3_R_OTHERNAME_ERROR);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
X509V3error(X509V3_R_UNSUPPORTED_TYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_string) {
|
||||
if (!(gen->d.ia5 = ASN1_IA5STRING_new()) ||
|
||||
!ASN1_STRING_set(gen->d.ia5, value, strlen(value))) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
gen->type = gen_type;
|
||||
|
||||
return gen;
|
||||
|
||||
err:
|
||||
if (out == NULL)
|
||||
GENERAL_NAME_free(gen);
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(a2i_GENERAL_NAME);
|
||||
|
||||
GENERAL_NAME *
|
||||
v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
|
||||
{
|
||||
uint8_t *bytes = NULL;
|
||||
char *name, *value;
|
||||
GENERAL_NAME *ret;
|
||||
size_t len = 0;
|
||||
int type;
|
||||
CBS cbs;
|
||||
|
||||
name = cnf->name;
|
||||
value = cnf->value;
|
||||
|
||||
if (!value) {
|
||||
X509V3error(X509V3_R_MISSING_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!name_cmp(name, "email"))
|
||||
type = GEN_EMAIL;
|
||||
else if (!name_cmp(name, "URI"))
|
||||
type = GEN_URI;
|
||||
else if (!name_cmp(name, "DNS"))
|
||||
type = GEN_DNS;
|
||||
else if (!name_cmp(name, "RID"))
|
||||
type = GEN_RID;
|
||||
else if (!name_cmp(name, "IP"))
|
||||
type = GEN_IPADD;
|
||||
else if (!name_cmp(name, "dirName"))
|
||||
type = GEN_DIRNAME;
|
||||
else if (!name_cmp(name, "otherName"))
|
||||
type = GEN_OTHERNAME;
|
||||
else {
|
||||
X509V3error(X509V3_R_UNSUPPORTED_OPTION);
|
||||
ERR_asprintf_error_data("name=%s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Validate what we have for sanity.
|
||||
*/
|
||||
|
||||
if (is_nc) {
|
||||
struct x509_constraints_name *constraints_name = NULL;
|
||||
|
||||
if (!x509_constraints_validate(ret, &constraints_name, NULL)) {
|
||||
X509V3error(X509V3_R_BAD_OBJECT);
|
||||
ERR_asprintf_error_data("name=%s", name);
|
||||
goto err;
|
||||
}
|
||||
x509_constraints_name_free(constraints_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
type = x509_constraints_general_to_bytes(ret, &bytes, &len);
|
||||
CBS_init(&cbs, bytes, len);
|
||||
switch (type) {
|
||||
case GEN_DNS:
|
||||
if (!x509_constraints_valid_sandns(&cbs)) {
|
||||
X509V3error(X509V3_R_BAD_OBJECT);
|
||||
ERR_asprintf_error_data("name=%s value='%.*s'", name,
|
||||
(int)len, bytes);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case GEN_URI:
|
||||
if (!x509_constraints_uri_host(bytes, len, NULL)) {
|
||||
X509V3error(X509V3_R_BAD_OBJECT);
|
||||
ERR_asprintf_error_data("name=%s value='%.*s'", name,
|
||||
(int)len, bytes);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case GEN_EMAIL:
|
||||
if (!x509_constraints_parse_mailbox(&cbs, NULL)) {
|
||||
X509V3error(X509V3_R_BAD_OBJECT);
|
||||
ERR_asprintf_error_data("name=%s value='%.*s'", name,
|
||||
(int)len, bytes);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case GEN_IPADD:
|
||||
if (len != 4 && len != 16) {
|
||||
X509V3error(X509V3_R_BAD_IP_ADDRESS);
|
||||
ERR_asprintf_error_data("name=%s len=%zu", name, len);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
err:
|
||||
if (out == NULL)
|
||||
GENERAL_NAME_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(v2i_GENERAL_NAME_ex);
|
||||
|
||||
static int
|
||||
do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
|
||||
{
|
||||
char *objtmp = NULL, *p;
|
||||
int objlen;
|
||||
|
||||
if (!(p = strchr(value, ';')))
|
||||
return 0;
|
||||
if (!(gen->d.otherName = OTHERNAME_new()))
|
||||
return 0;
|
||||
/* Free this up because we will overwrite it.
|
||||
* no need to free type_id because it is static
|
||||
*/
|
||||
ASN1_TYPE_free(gen->d.otherName->value);
|
||||
if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
|
||||
return 0;
|
||||
objlen = p - value;
|
||||
objtmp = malloc(objlen + 1);
|
||||
if (objtmp) {
|
||||
strlcpy(objtmp, value, objlen + 1);
|
||||
gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
|
||||
free(objtmp);
|
||||
} else
|
||||
gen->d.otherName->type_id = NULL;
|
||||
if (!gen->d.otherName->type_id)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
STACK_OF(CONF_VALUE) *sk;
|
||||
X509_NAME *nm;
|
||||
|
||||
if (!(nm = X509_NAME_new()))
|
||||
return 0;
|
||||
sk = X509V3_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;
|
||||
}
|
||||
1203
crypto/x509/x509_asid.c
Normal file
1203
crypto/x509/x509_asid.c
Normal file
File diff suppressed because it is too large
Load Diff
413
crypto/x509/x509_att.c
Normal file
413
crypto/x509/x509_att.c
Normal file
@@ -0,0 +1,413 @@
|
||||
/* $OpenBSD: x509_att.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
|
||||
{
|
||||
return sk_X509_ATTRIBUTE_num(x);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_get_attr_count);
|
||||
|
||||
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));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_get_attr_by_NID);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_get_attr_by_OBJ);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_get_attr);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_delete_attr);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_add1_attr);
|
||||
|
||||
STACK_OF(X509_ATTRIBUTE) *
|
||||
X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj,
|
||||
int type, const unsigned char *bytes, int len)
|
||||
{
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_add1_attr_by_OBJ);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_add1_attr_by_NID);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_add1_attr_by_txt);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509at_get0_data_by_OBJ);
|
||||
|
||||
X509_ATTRIBUTE *
|
||||
X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype,
|
||||
const void *data, int len)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
X509_ATTRIBUTE *ret;
|
||||
|
||||
obj = OBJ_nid2obj(nid);
|
||||
if (obj == NULL) {
|
||||
X509error(X509_R_UNKNOWN_NID);
|
||||
return (NULL);
|
||||
}
|
||||
ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
|
||||
if (ret == NULL)
|
||||
ASN1_OBJECT_free(obj);
|
||||
return (ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_NID);
|
||||
|
||||
X509_ATTRIBUTE *
|
||||
X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj,
|
||||
int atrtype, const void *data, int len)
|
||||
{
|
||||
X509_ATTRIBUTE *ret;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL)) {
|
||||
if ((ret = X509_ATTRIBUTE_new()) == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
} else
|
||||
ret= *attr;
|
||||
|
||||
if (!X509_ATTRIBUTE_set1_object(ret, obj))
|
||||
goto err;
|
||||
if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
|
||||
goto err;
|
||||
|
||||
if ((attr != NULL) && (*attr == NULL))
|
||||
*attr = ret;
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
if ((attr == NULL) || (ret != *attr))
|
||||
X509_ATTRIBUTE_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_OBJ);
|
||||
|
||||
X509_ATTRIBUTE *
|
||||
X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const char *atrname,
|
||||
int type, const unsigned char *bytes, int len)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
X509_ATTRIBUTE *nattr;
|
||||
|
||||
obj = OBJ_txt2obj(atrname, 0);
|
||||
if (obj == NULL) {
|
||||
X509error(X509_R_INVALID_FIELD_NAME);
|
||||
ERR_asprintf_error_data("name=%s", atrname);
|
||||
return (NULL);
|
||||
}
|
||||
nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
|
||||
ASN1_OBJECT_free(obj);
|
||||
return nattr;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_txt);
|
||||
|
||||
int
|
||||
X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
|
||||
{
|
||||
if ((attr == NULL) || (obj == NULL))
|
||||
return (0);
|
||||
ASN1_OBJECT_free(attr->object);
|
||||
attr->object = OBJ_dup(obj);
|
||||
return attr->object != NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_object);
|
||||
|
||||
int
|
||||
X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data,
|
||||
int len)
|
||||
{
|
||||
ASN1_TYPE *ttmp = NULL;
|
||||
ASN1_STRING *stmp = NULL;
|
||||
int atype = 0;
|
||||
|
||||
if (!attr)
|
||||
return 0;
|
||||
if (attrtype & MBSTRING_FLAG) {
|
||||
stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
|
||||
OBJ_obj2nid(attr->object));
|
||||
if (!stmp) {
|
||||
X509error(ERR_R_ASN1_LIB);
|
||||
return 0;
|
||||
}
|
||||
atype = stmp->type;
|
||||
} else if (len != -1){
|
||||
if (!(stmp = ASN1_STRING_type_new(attrtype)))
|
||||
goto err;
|
||||
if (!ASN1_STRING_set(stmp, data, len))
|
||||
goto err;
|
||||
atype = attrtype;
|
||||
}
|
||||
/*
|
||||
* This is a bit naughty because the attribute should really have
|
||||
* at least one value but some types use and zero length SET and
|
||||
* require this.
|
||||
*/
|
||||
if (attrtype == 0) {
|
||||
ASN1_STRING_free(stmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(ttmp = ASN1_TYPE_new()))
|
||||
goto err;
|
||||
if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
|
||||
if (!ASN1_TYPE_set1(ttmp, attrtype, data))
|
||||
goto err;
|
||||
} else
|
||||
ASN1_TYPE_set(ttmp, atype, stmp);
|
||||
if (!sk_ASN1_TYPE_push(attr->set, ttmp))
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ASN1_TYPE_free(ttmp);
|
||||
ASN1_STRING_free(stmp);
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_data);
|
||||
|
||||
int
|
||||
X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return 0;
|
||||
|
||||
return sk_ASN1_TYPE_num(attr->set);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_count);
|
||||
|
||||
ASN1_OBJECT *
|
||||
X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return (NULL);
|
||||
return (attr->object);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_object);
|
||||
|
||||
void *
|
||||
X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data)
|
||||
{
|
||||
ASN1_TYPE *ttmp;
|
||||
|
||||
ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
|
||||
if (!ttmp)
|
||||
return NULL;
|
||||
if (atrtype != ASN1_TYPE_get(ttmp)){
|
||||
X509error(X509_R_WRONG_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
return ttmp->value.ptr;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_data);
|
||||
|
||||
ASN1_TYPE *
|
||||
X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return (NULL);
|
||||
|
||||
return sk_ASN1_TYPE_value(attr->set, idx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_type);
|
||||
203
crypto/x509/x509_bcons.c
Normal file
203
crypto/x509/x509_bcons.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/* $OpenBSD: x509_bcons.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_BASIC_CONSTRAINTS);
|
||||
|
||||
int
|
||||
i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &BASIC_CONSTRAINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_BASIC_CONSTRAINTS);
|
||||
|
||||
BASIC_CONSTRAINTS *
|
||||
BASIC_CONSTRAINTS_new(void)
|
||||
{
|
||||
return (BASIC_CONSTRAINTS *)ASN1_item_new(&BASIC_CONSTRAINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(BASIC_CONSTRAINTS_new);
|
||||
|
||||
void
|
||||
BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &BASIC_CONSTRAINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(BASIC_CONSTRAINTS_free);
|
||||
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons,
|
||||
STACK_OF(CONF_VALUE) *extlist)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *free_extlist = NULL;
|
||||
|
||||
if (extlist == NULL) {
|
||||
if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value_bool("CA", bcons->ca, &extlist))
|
||||
goto err;
|
||||
if (!X509V3_add_value_int("pathlen", bcons->pathlen, &extlist))
|
||||
goto err;
|
||||
|
||||
return extlist;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BASIC_CONSTRAINTS *
|
||||
v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values)
|
||||
{
|
||||
BASIC_CONSTRAINTS *bcons = NULL;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
|
||||
if (!(bcons = BASIC_CONSTRAINTS_new())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
val = sk_CONF_VALUE_value(values, i);
|
||||
if (!strcmp(val->name, "CA")) {
|
||||
if (!X509V3_get_value_bool(val, &bcons->ca))
|
||||
goto err;
|
||||
} else if (!strcmp(val->name, "pathlen")) {
|
||||
if (!X509V3_get_value_int(val, &bcons->pathlen))
|
||||
goto err;
|
||||
} else {
|
||||
X509V3error(X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return bcons;
|
||||
|
||||
err:
|
||||
BASIC_CONSTRAINTS_free(bcons);
|
||||
return NULL;
|
||||
}
|
||||
220
crypto/x509/x509_bitst.c
Normal file
220
crypto/x509/x509_bitst.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/* $OpenBSD: x509_bitst.c,v 1.4 2023/04/21 06:11:56 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/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}
|
||||
};
|
||||
|
||||
static BIT_STRING_BITNAME crl_reasons[] = {
|
||||
{CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
|
||||
{CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
|
||||
{CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
|
||||
{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
|
||||
{CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
|
||||
{CRL_REASON_CESSATION_OF_OPERATION, "Cessation Of Operation", "cessationOfOperation"},
|
||||
{CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
|
||||
{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
|
||||
{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
|
||||
{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
|
||||
{-1, NULL, NULL}
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(i2v_ASN1_BIT_STRING);
|
||||
|
||||
ASN1_BIT_STRING *
|
||||
v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
CONF_VALUE *val;
|
||||
ASN1_BIT_STRING *bs;
|
||||
int i;
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
|
||||
if (!(bs = ASN1_BIT_STRING_new())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
for (bnam = method->usr_data; bnam->lname; bnam++) {
|
||||
if (!strcmp(bnam->sname, val->name) ||
|
||||
!strcmp(bnam->lname, val->name) ) {
|
||||
if (!ASN1_BIT_STRING_set_bit(bs,
|
||||
bnam->bitnum, 1)) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
ASN1_BIT_STRING_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bnam->lname) {
|
||||
X509V3error(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
|
||||
X509V3_conf_err(val);
|
||||
ASN1_BIT_STRING_free(bs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
LCRYPTO_ALIAS(v2i_ASN1_BIT_STRING);
|
||||
425
crypto/x509/x509_cmp.c
Normal file
425
crypto/x509/x509_cmp.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/* $OpenBSD: x509_cmp.c,v 1.42 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "evp_local.h"
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
|
||||
{
|
||||
int i;
|
||||
X509_CINF *ai, *bi;
|
||||
|
||||
ai = a->cert_info;
|
||||
bi = b->cert_info;
|
||||
i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
|
||||
if (i)
|
||||
return (i);
|
||||
return (X509_NAME_cmp(ai->issuer, bi->issuer));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_issuer_and_serial_cmp);
|
||||
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
unsigned long
|
||||
X509_issuer_and_serial_hash(X509 *a)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
EVP_MD_CTX 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_issuer_and_serial_hash);
|
||||
#endif
|
||||
|
||||
int
|
||||
X509_issuer_name_cmp(const X509 *a, const X509 *b)
|
||||
{
|
||||
return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_issuer_name_cmp);
|
||||
|
||||
int
|
||||
X509_subject_name_cmp(const X509 *a, const X509 *b)
|
||||
{
|
||||
return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_subject_name_cmp);
|
||||
|
||||
int
|
||||
X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
|
||||
{
|
||||
return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_cmp);
|
||||
|
||||
#ifndef OPENSSL_NO_SHA
|
||||
int
|
||||
X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
|
||||
{
|
||||
return memcmp(a->hash, b->hash, X509_CRL_HASH_LEN);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_match);
|
||||
#endif
|
||||
|
||||
X509_NAME *
|
||||
X509_get_issuer_name(const X509 *a)
|
||||
{
|
||||
return (a->cert_info->issuer);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_issuer_name);
|
||||
|
||||
unsigned long
|
||||
X509_issuer_name_hash(X509 *x)
|
||||
{
|
||||
return (X509_NAME_hash(x->cert_info->issuer));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_issuer_name_hash);
|
||||
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
unsigned long
|
||||
X509_issuer_name_hash_old(X509 *x)
|
||||
{
|
||||
return (X509_NAME_hash_old(x->cert_info->issuer));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_issuer_name_hash_old);
|
||||
#endif
|
||||
|
||||
X509_NAME *
|
||||
X509_get_subject_name(const X509 *a)
|
||||
{
|
||||
return (a->cert_info->subject);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_subject_name);
|
||||
|
||||
ASN1_INTEGER *
|
||||
X509_get_serialNumber(X509 *a)
|
||||
{
|
||||
return (a->cert_info->serialNumber);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_serialNumber);
|
||||
|
||||
const ASN1_INTEGER *
|
||||
X509_get0_serialNumber(const X509 *a)
|
||||
{
|
||||
return (a->cert_info->serialNumber);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_serialNumber);
|
||||
|
||||
unsigned long
|
||||
X509_subject_name_hash(X509 *x)
|
||||
{
|
||||
return (X509_NAME_hash(x->cert_info->subject));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_subject_name_hash);
|
||||
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
unsigned long
|
||||
X509_subject_name_hash_old(X509 *x)
|
||||
{
|
||||
return (X509_NAME_hash_old(x->cert_info->subject));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_subject_name_hash_old);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SHA
|
||||
/* Compare two certificates: they must be identical for
|
||||
* this to work. NB: Although "cmp" operations are generally
|
||||
* prototyped to take "const" arguments (eg. for use in
|
||||
* STACKs), the way X509 handling is - these operations may
|
||||
* involve ensuring the hashes are up-to-date and ensuring
|
||||
* certain cert information is cached. So this is the point
|
||||
* where the "depth-first" constification tree has to halt
|
||||
* with an evil cast.
|
||||
*/
|
||||
int
|
||||
X509_cmp(const X509 *a, const X509 *b)
|
||||
{
|
||||
/* ensure hash is valid */
|
||||
X509_check_purpose((X509 *)a, -1, 0);
|
||||
X509_check_purpose((X509 *)b, -1, 0);
|
||||
|
||||
return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_cmp);
|
||||
#endif
|
||||
|
||||
int
|
||||
X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Ensure canonical encoding is present and up to date */
|
||||
if (!a->canon_enc || a->modified) {
|
||||
ret = i2d_X509_NAME((X509_NAME *)a, NULL);
|
||||
if (ret < 0)
|
||||
return -2;
|
||||
}
|
||||
if (!b->canon_enc || b->modified) {
|
||||
ret = i2d_X509_NAME((X509_NAME *)b, NULL);
|
||||
if (ret < 0)
|
||||
return -2;
|
||||
}
|
||||
ret = a->canon_enclen - b->canon_enclen;
|
||||
if (ret)
|
||||
return ret;
|
||||
return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_cmp);
|
||||
|
||||
unsigned long
|
||||
X509_NAME_hash(X509_NAME *x)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
unsigned char md[SHA_DIGEST_LENGTH];
|
||||
|
||||
/* Make sure X509_NAME structure contains valid cached encoding */
|
||||
i2d_X509_NAME(x, NULL);
|
||||
if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
|
||||
NULL))
|
||||
return 0;
|
||||
|
||||
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
|
||||
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) &
|
||||
0xffffffffL;
|
||||
return (ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_hash);
|
||||
|
||||
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
/* I now DER encode the name and hash it. Since I cache the DER encoding,
|
||||
* this is reasonably efficient. */
|
||||
|
||||
unsigned long
|
||||
X509_NAME_hash_old(X509_NAME *x)
|
||||
{
|
||||
EVP_MD_CTX md_ctx;
|
||||
unsigned long ret = 0;
|
||||
unsigned char md[16];
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_hash_old);
|
||||
#endif
|
||||
|
||||
/* Search a stack of X509 for a match */
|
||||
X509 *
|
||||
X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
|
||||
ASN1_INTEGER *serial)
|
||||
{
|
||||
int i;
|
||||
X509_CINF cinf;
|
||||
X509 x, *x509 = NULL;
|
||||
|
||||
if (!sk)
|
||||
return NULL;
|
||||
|
||||
x.cert_info = &cinf;
|
||||
cinf.serialNumber = serial;
|
||||
cinf.issuer = name;
|
||||
|
||||
for (i = 0; i < sk_X509_num(sk); i++) {
|
||||
x509 = sk_X509_value(sk, i);
|
||||
if (X509_issuer_and_serial_cmp(x509, &x) == 0)
|
||||
return (x509);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_find_by_issuer_and_serial);
|
||||
|
||||
X509 *
|
||||
X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
|
||||
{
|
||||
X509 *x509;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sk_X509_num(sk); i++) {
|
||||
x509 = sk_X509_value(sk, i);
|
||||
if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
|
||||
return (x509);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_find_by_subject);
|
||||
|
||||
EVP_PKEY *
|
||||
X509_get_pubkey(X509 *x)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL)
|
||||
return (NULL);
|
||||
return (X509_PUBKEY_get(x->cert_info->key));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_pubkey);
|
||||
|
||||
EVP_PKEY *
|
||||
X509_get0_pubkey(const X509 *x)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL)
|
||||
return (NULL);
|
||||
return (X509_PUBKEY_get0(x->cert_info->key));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_pubkey);
|
||||
|
||||
ASN1_BIT_STRING *
|
||||
X509_get0_pubkey_bitstr(const X509 *x)
|
||||
{
|
||||
if (!x)
|
||||
return NULL;
|
||||
return x->cert_info->key->public_key;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_pubkey_bitstr);
|
||||
|
||||
int
|
||||
X509_check_private_key(const X509 *x, const EVP_PKEY *k)
|
||||
{
|
||||
const EVP_PKEY *xk;
|
||||
int ret;
|
||||
|
||||
xk = X509_get0_pubkey(x);
|
||||
|
||||
if (xk)
|
||||
ret = EVP_PKEY_cmp(xk, k);
|
||||
else
|
||||
ret = -2;
|
||||
|
||||
switch (ret) {
|
||||
case 1:
|
||||
break;
|
||||
case 0:
|
||||
X509error(X509_R_KEY_VALUES_MISMATCH);
|
||||
break;
|
||||
case -1:
|
||||
X509error(X509_R_KEY_TYPE_MISMATCH);
|
||||
break;
|
||||
case -2:
|
||||
X509error(X509_R_UNKNOWN_KEY_TYPE);
|
||||
}
|
||||
if (ret > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_check_private_key);
|
||||
|
||||
/*
|
||||
* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
|
||||
* count but it has the same effect by duping the STACK and upping the ref of
|
||||
* each X509 structure.
|
||||
*/
|
||||
STACK_OF(X509) *
|
||||
X509_chain_up_ref(STACK_OF(X509) *chain)
|
||||
{
|
||||
STACK_OF(X509) *ret;
|
||||
size_t i;
|
||||
|
||||
ret = sk_X509_dup(chain);
|
||||
for (i = 0; i < sk_X509_num(ret); i++)
|
||||
X509_up_ref(sk_X509_value(ret, i));
|
||||
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_chain_up_ref);
|
||||
591
crypto/x509/x509_conf.c
Normal file
591
crypto/x509/x509_conf.c
Normal file
@@ -0,0 +1,591 @@
|
||||
/* $OpenBSD: x509_conf.c,v 1.5 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
static int v3_check_critical(const char **value);
|
||||
static int v3_check_generic(const char **value);
|
||||
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int 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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_nconf);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_nconf_nid);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_i2d);
|
||||
|
||||
/* Check the extension string for critical flag */
|
||||
static int
|
||||
v3_check_critical(const char **value)
|
||||
{
|
||||
const char *p = *value;
|
||||
|
||||
if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
|
||||
return 0;
|
||||
p += 9;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
*value = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check extension string for generic extension and return the type */
|
||||
static int
|
||||
v3_check_generic(const char **value)
|
||||
{
|
||||
int gen_type = 0;
|
||||
const char *p = *value;
|
||||
|
||||
if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
|
||||
p += 4;
|
||||
gen_type = 1;
|
||||
} else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
|
||||
p += 5;
|
||||
gen_type = 2;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
*value = p;
|
||||
return gen_type;
|
||||
}
|
||||
|
||||
/* Create a generic extension: for now just handle DER type */
|
||||
static X509_EXTENSION *
|
||||
v3_generic_extension(const char *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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_add_nconf_sk);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_add_nconf);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_CRL_add_nconf);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_REQ_add_nconf);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_get_string);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_get_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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_string_free);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_section_free);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_set_nconf);
|
||||
|
||||
void
|
||||
X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
|
||||
X509_CRL *crl, int flags)
|
||||
{
|
||||
ctx->issuer_cert = issuer;
|
||||
ctx->subject_cert = subj;
|
||||
ctx->crl = crl;
|
||||
ctx->subject_req = req;
|
||||
ctx->flags = flags;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_set_ctx);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_conf);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_conf_nid);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_set_conf_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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_add_conf);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_CRL_add_conf);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_REQ_add_conf);
|
||||
1289
crypto/x509/x509_constraints.c
Normal file
1289
crypto/x509/x509_constraints.c
Normal file
File diff suppressed because it is too large
Load Diff
764
crypto/x509/x509_cpols.c
Normal file
764
crypto/x509/x509_cpols.c
Normal file
@@ -0,0 +1,764 @@
|
||||
/* $OpenBSD: x509_cpols.c,v 1.11 2023/04/26 20:54:21 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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 "x509_local.h"
|
||||
|
||||
/* Certificate policies extension support: this one is a bit complex... */
|
||||
|
||||
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
|
||||
BIO *out, int indent);
|
||||
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, char *value);
|
||||
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
|
||||
int indent);
|
||||
static void print_notice(BIO *out, USERNOTICE *notice, int indent);
|
||||
static POLICYINFO *policy_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *polstrs, int ia5org);
|
||||
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *unot, int ia5org);
|
||||
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_CERTIFICATEPOLICIES);
|
||||
|
||||
int
|
||||
i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_CERTIFICATEPOLICIES);
|
||||
|
||||
CERTIFICATEPOLICIES *
|
||||
CERTIFICATEPOLICIES_new(void)
|
||||
{
|
||||
return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(CERTIFICATEPOLICIES_new);
|
||||
|
||||
void
|
||||
CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(CERTIFICATEPOLICIES_free);
|
||||
|
||||
static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = {
|
||||
{
|
||||
.flags = 0,
|
||||
.tag = 0,
|
||||
.offset = offsetof(POLICYINFO, policyid),
|
||||
.field_name = "policyid",
|
||||
.item = &ASN1_OBJECT_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 0,
|
||||
.offset = offsetof(POLICYINFO, qualifiers),
|
||||
.field_name = "qualifiers",
|
||||
.item = &POLICYQUALINFO_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM POLICYINFO_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = POLICYINFO_seq_tt,
|
||||
.tcount = sizeof(POLICYINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(POLICYINFO),
|
||||
.sname = "POLICYINFO",
|
||||
};
|
||||
|
||||
|
||||
POLICYINFO *
|
||||
d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&POLICYINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_POLICYINFO);
|
||||
|
||||
int
|
||||
i2d_POLICYINFO(POLICYINFO *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_POLICYINFO);
|
||||
|
||||
POLICYINFO *
|
||||
POLICYINFO_new(void)
|
||||
{
|
||||
return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICYINFO_new);
|
||||
|
||||
void
|
||||
POLICYINFO_free(POLICYINFO *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICYINFO_free);
|
||||
|
||||
static const ASN1_TEMPLATE policydefault_tt = {
|
||||
.flags = 0,
|
||||
.tag = 0,
|
||||
.offset = offsetof(POLICYQUALINFO, d.other),
|
||||
.field_name = "d.other",
|
||||
.item = &ASN1_ANY_it,
|
||||
};
|
||||
|
||||
static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = {
|
||||
{
|
||||
.value = NID_id_qt_cps,
|
||||
.tt = {
|
||||
.flags = 0,
|
||||
.tag = 0,
|
||||
.offset = offsetof(POLICYQUALINFO, d.cpsuri),
|
||||
.field_name = "d.cpsuri",
|
||||
.item = &ASN1_IA5STRING_it,
|
||||
},
|
||||
},
|
||||
{
|
||||
.value = NID_id_qt_unotice,
|
||||
.tt = {
|
||||
.flags = 0,
|
||||
.tag = 0,
|
||||
.offset = offsetof(POLICYQUALINFO, d.usernotice),
|
||||
.field_name = "d.usernotice",
|
||||
.item = &USERNOTICE_it,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const ASN1_ADB POLICYQUALINFO_adb = {
|
||||
.flags = 0,
|
||||
.offset = offsetof(POLICYQUALINFO, pqualid),
|
||||
.tbl = POLICYQUALINFO_adbtbl,
|
||||
.tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE),
|
||||
.default_tt = &policydefault_tt,
|
||||
.null_tt = NULL,
|
||||
};
|
||||
|
||||
static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = {
|
||||
{
|
||||
.flags = 0,
|
||||
.tag = 0,
|
||||
.offset = offsetof(POLICYQUALINFO, pqualid),
|
||||
.field_name = "pqualid",
|
||||
.item = &ASN1_OBJECT_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_ADB_OID,
|
||||
.tag = -1,
|
||||
.offset = 0,
|
||||
.field_name = "POLICYQUALINFO",
|
||||
.item = (const ASN1_ITEM *)&POLICYQUALINFO_adb,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM POLICYQUALINFO_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = POLICYQUALINFO_seq_tt,
|
||||
.tcount = sizeof(POLICYQUALINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(POLICYQUALINFO),
|
||||
.sname = "POLICYQUALINFO",
|
||||
};
|
||||
|
||||
|
||||
POLICYQUALINFO *
|
||||
d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&POLICYQUALINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_POLICYQUALINFO);
|
||||
|
||||
int
|
||||
i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_POLICYQUALINFO);
|
||||
|
||||
POLICYQUALINFO *
|
||||
POLICYQUALINFO_new(void)
|
||||
{
|
||||
return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICYQUALINFO_new);
|
||||
|
||||
void
|
||||
POLICYQUALINFO_free(POLICYQUALINFO *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICYQUALINFO_free);
|
||||
|
||||
static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = {
|
||||
{
|
||||
.flags = ASN1_TFLG_OPTIONAL,
|
||||
.tag = 0,
|
||||
.offset = offsetof(USERNOTICE, noticeref),
|
||||
.field_name = "noticeref",
|
||||
.item = &NOTICEREF_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_OPTIONAL,
|
||||
.tag = 0,
|
||||
.offset = offsetof(USERNOTICE, exptext),
|
||||
.field_name = "exptext",
|
||||
.item = &DISPLAYTEXT_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM USERNOTICE_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = USERNOTICE_seq_tt,
|
||||
.tcount = sizeof(USERNOTICE_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(USERNOTICE),
|
||||
.sname = "USERNOTICE",
|
||||
};
|
||||
|
||||
|
||||
USERNOTICE *
|
||||
d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&USERNOTICE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_USERNOTICE);
|
||||
|
||||
int
|
||||
i2d_USERNOTICE(USERNOTICE *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_USERNOTICE);
|
||||
|
||||
USERNOTICE *
|
||||
USERNOTICE_new(void)
|
||||
{
|
||||
return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(USERNOTICE_new);
|
||||
|
||||
void
|
||||
USERNOTICE_free(USERNOTICE *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(USERNOTICE_free);
|
||||
|
||||
static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = {
|
||||
{
|
||||
.flags = 0,
|
||||
.tag = 0,
|
||||
.offset = offsetof(NOTICEREF, organization),
|
||||
.field_name = "organization",
|
||||
.item = &DISPLAYTEXT_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_SEQUENCE_OF,
|
||||
.tag = 0,
|
||||
.offset = offsetof(NOTICEREF, noticenos),
|
||||
.field_name = "noticenos",
|
||||
.item = &ASN1_INTEGER_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM NOTICEREF_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = NOTICEREF_seq_tt,
|
||||
.tcount = sizeof(NOTICEREF_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(NOTICEREF),
|
||||
.sname = "NOTICEREF",
|
||||
};
|
||||
|
||||
|
||||
NOTICEREF *
|
||||
d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&NOTICEREF_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_NOTICEREF);
|
||||
|
||||
int
|
||||
i2d_NOTICEREF(NOTICEREF *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_NOTICEREF);
|
||||
|
||||
NOTICEREF *
|
||||
NOTICEREF_new(void)
|
||||
{
|
||||
return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(NOTICEREF_new);
|
||||
|
||||
void
|
||||
NOTICEREF_free(NOTICEREF *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(NOTICEREF_free);
|
||||
|
||||
static STACK_OF(POLICYINFO) *
|
||||
r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value)
|
||||
{
|
||||
STACK_OF(POLICYINFO) *pols = NULL;
|
||||
char *pstr;
|
||||
POLICYINFO *pol;
|
||||
ASN1_OBJECT *pobj;
|
||||
STACK_OF(CONF_VALUE) *vals;
|
||||
CONF_VALUE *cnf;
|
||||
int i, ia5org;
|
||||
|
||||
pols = sk_POLICYINFO_new_null();
|
||||
if (pols == NULL) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
vals = X509V3_parse_list(value);
|
||||
if (vals == NULL) {
|
||||
X509V3error(ERR_R_X509V3_LIB);
|
||||
goto err;
|
||||
}
|
||||
ia5org = 0;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
|
||||
cnf = sk_CONF_VALUE_value(vals, i);
|
||||
if (cnf->value || !cnf->name) {
|
||||
X509V3error(X509V3_R_INVALID_POLICY_IDENTIFIER);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
pstr = cnf->name;
|
||||
if (!strcmp(pstr, "ia5org")) {
|
||||
ia5org = 1;
|
||||
continue;
|
||||
} else if (*pstr == '@') {
|
||||
STACK_OF(CONF_VALUE) *polsect;
|
||||
polsect = X509V3_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_UTF8STRING_new();
|
||||
if (not->exptext == NULL)
|
||||
goto merr;
|
||||
}
|
||||
if (!ASN1_STRING_set(not->exptext, cnf->value,
|
||||
strlen(cnf->value)))
|
||||
goto merr;
|
||||
} else if (!strcmp(cnf->name, "organization")) {
|
||||
NOTICEREF *nref;
|
||||
if (!not->noticeref) {
|
||||
if (!(nref = NOTICEREF_new()))
|
||||
goto merr;
|
||||
not->noticeref = nref;
|
||||
} else
|
||||
nref = not->noticeref;
|
||||
if (ia5org)
|
||||
nref->organization->type = V_ASN1_IA5STRING;
|
||||
else
|
||||
nref->organization->type = V_ASN1_VISIBLESTRING;
|
||||
if (!ASN1_STRING_set(nref->organization, cnf->value,
|
||||
strlen(cnf->value)))
|
||||
goto merr;
|
||||
} else if (!strcmp(cnf->name, "noticeNumbers")) {
|
||||
NOTICEREF *nref;
|
||||
STACK_OF(CONF_VALUE) *nos;
|
||||
if (!not->noticeref) {
|
||||
if (!(nref = NOTICEREF_new()))
|
||||
goto merr;
|
||||
not->noticeref = nref;
|
||||
} else
|
||||
nref = not->noticeref;
|
||||
nos = X509V3_parse_list(cnf->value);
|
||||
if (!nos || !sk_CONF_VALUE_num(nos)) {
|
||||
X509V3error(X509V3_R_INVALID_NUMBERS);
|
||||
X509V3_conf_err(cnf);
|
||||
if (nos != NULL)
|
||||
sk_CONF_VALUE_pop_free(nos,
|
||||
X509V3_conf_free);
|
||||
goto err;
|
||||
}
|
||||
ret = nref_nos(nref->noticenos, nos);
|
||||
sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
|
||||
if (!ret)
|
||||
goto err;
|
||||
} else {
|
||||
X509V3error(X509V3_R_INVALID_OPTION);
|
||||
X509V3_conf_err(cnf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (not->noticeref &&
|
||||
(!not->noticeref->noticenos || !not->noticeref->organization)) {
|
||||
X509V3error(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return qual;
|
||||
|
||||
merr:
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
POLICYQUALINFO_free(qual);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
|
||||
{
|
||||
CONF_VALUE *cnf;
|
||||
ASN1_INTEGER *aint;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nos, i);
|
||||
if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
|
||||
X509V3error(X509V3_R_INVALID_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
if (!sk_ASN1_INTEGER_push(nnums, aint))
|
||||
goto merr;
|
||||
}
|
||||
return 1;
|
||||
|
||||
merr:
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out,
|
||||
int indent)
|
||||
{
|
||||
int i;
|
||||
POLICYINFO *pinfo;
|
||||
|
||||
/* First print out the policy OIDs */
|
||||
for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
|
||||
pinfo = sk_POLICYINFO_value(pol, i);
|
||||
BIO_printf(out, "%*sPolicy: ", indent, "");
|
||||
i2a_ASN1_OBJECT(out, pinfo->policyid);
|
||||
BIO_puts(out, "\n");
|
||||
if (pinfo->qualifiers)
|
||||
print_qualifiers(out, pinfo->qualifiers, indent + 2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent)
|
||||
{
|
||||
POLICYQUALINFO *qualinfo;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
|
||||
qualinfo = sk_POLICYQUALINFO_value(quals, i);
|
||||
switch (OBJ_obj2nid(qualinfo->pqualid)) {
|
||||
case NID_id_qt_cps:
|
||||
BIO_printf(out, "%*sCPS: %.*s\n", indent, "",
|
||||
qualinfo->d.cpsuri->length,
|
||||
qualinfo->d.cpsuri->data);
|
||||
break;
|
||||
|
||||
case NID_id_qt_unotice:
|
||||
BIO_printf(out, "%*sUser Notice:\n", indent, "");
|
||||
print_notice(out, qualinfo->d.usernotice, indent + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
BIO_printf(out, "%*sUnknown Qualifier: ",
|
||||
indent + 2, "");
|
||||
|
||||
i2a_ASN1_OBJECT(out, qualinfo->pqualid);
|
||||
BIO_puts(out, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_notice(BIO *out, USERNOTICE *notice, int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (notice->noticeref) {
|
||||
NOTICEREF *ref;
|
||||
ref = notice->noticeref;
|
||||
BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
|
||||
ref->organization->length, ref->organization->data);
|
||||
BIO_printf(out, "%*sNumber%s: ", indent, "",
|
||||
sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
|
||||
for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
|
||||
ASN1_INTEGER *num;
|
||||
char *tmp;
|
||||
num = sk_ASN1_INTEGER_value(ref->noticenos, i);
|
||||
if (i)
|
||||
BIO_puts(out, ", ");
|
||||
tmp = i2s_ASN1_INTEGER(NULL, num);
|
||||
BIO_puts(out, tmp);
|
||||
free(tmp);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
if (notice->exptext)
|
||||
BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "",
|
||||
notice->exptext->length, notice->exptext->data);
|
||||
}
|
||||
828
crypto/x509/x509_crld.c
Normal file
828
crypto/x509/x509_crld.c
Normal file
@@ -0,0 +1,828 @@
|
||||
/* $OpenBSD: x509_crld.c,v 1.5 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
static void *v2i_crld(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
|
||||
int indent);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_DIST_POINT_NAME);
|
||||
|
||||
int
|
||||
i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_DIST_POINT_NAME);
|
||||
|
||||
DIST_POINT_NAME *
|
||||
DIST_POINT_NAME_new(void)
|
||||
{
|
||||
return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(DIST_POINT_NAME_new);
|
||||
|
||||
void
|
||||
DIST_POINT_NAME_free(DIST_POINT_NAME *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(DIST_POINT_NAME_free);
|
||||
|
||||
static const ASN1_TEMPLATE DIST_POINT_seq_tt[] = {
|
||||
{
|
||||
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 0,
|
||||
.offset = offsetof(DIST_POINT, distpoint),
|
||||
.field_name = "distpoint",
|
||||
.item = &DIST_POINT_NAME_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 1,
|
||||
.offset = offsetof(DIST_POINT, reasons),
|
||||
.field_name = "reasons",
|
||||
.item = &ASN1_BIT_STRING_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 2,
|
||||
.offset = offsetof(DIST_POINT, CRLissuer),
|
||||
.field_name = "CRLissuer",
|
||||
.item = &GENERAL_NAME_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM DIST_POINT_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = DIST_POINT_seq_tt,
|
||||
.tcount = sizeof(DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(DIST_POINT),
|
||||
.sname = "DIST_POINT",
|
||||
};
|
||||
|
||||
|
||||
DIST_POINT *
|
||||
d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_DIST_POINT);
|
||||
|
||||
int
|
||||
i2d_DIST_POINT(DIST_POINT *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_DIST_POINT);
|
||||
|
||||
DIST_POINT *
|
||||
DIST_POINT_new(void)
|
||||
{
|
||||
return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(DIST_POINT_new);
|
||||
|
||||
void
|
||||
DIST_POINT_free(DIST_POINT *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(DIST_POINT_free);
|
||||
|
||||
static const ASN1_TEMPLATE CRL_DIST_POINTS_item_tt = {
|
||||
.flags = ASN1_TFLG_SEQUENCE_OF,
|
||||
.tag = 0,
|
||||
.offset = 0,
|
||||
.field_name = "CRLDistributionPoints",
|
||||
.item = &DIST_POINT_it,
|
||||
};
|
||||
|
||||
const ASN1_ITEM CRL_DIST_POINTS_it = {
|
||||
.itype = ASN1_ITYPE_PRIMITIVE,
|
||||
.utype = -1,
|
||||
.templates = &CRL_DIST_POINTS_item_tt,
|
||||
.tcount = 0,
|
||||
.funcs = NULL,
|
||||
.size = 0,
|
||||
.sname = "CRL_DIST_POINTS",
|
||||
};
|
||||
|
||||
|
||||
CRL_DIST_POINTS *
|
||||
d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (CRL_DIST_POINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&CRL_DIST_POINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_CRL_DIST_POINTS);
|
||||
|
||||
int
|
||||
i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_CRL_DIST_POINTS);
|
||||
|
||||
CRL_DIST_POINTS *
|
||||
CRL_DIST_POINTS_new(void)
|
||||
{
|
||||
return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(CRL_DIST_POINTS_new);
|
||||
|
||||
void
|
||||
CRL_DIST_POINTS_free(CRL_DIST_POINTS *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(CRL_DIST_POINTS_free);
|
||||
|
||||
static const ASN1_TEMPLATE ISSUING_DIST_POINT_seq_tt[] = {
|
||||
{
|
||||
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 0,
|
||||
.offset = offsetof(ISSUING_DIST_POINT, distpoint),
|
||||
.field_name = "distpoint",
|
||||
.item = &DIST_POINT_NAME_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 1,
|
||||
.offset = offsetof(ISSUING_DIST_POINT, onlyuser),
|
||||
.field_name = "onlyuser",
|
||||
.item = &ASN1_FBOOLEAN_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 2,
|
||||
.offset = offsetof(ISSUING_DIST_POINT, onlyCA),
|
||||
.field_name = "onlyCA",
|
||||
.item = &ASN1_FBOOLEAN_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 3,
|
||||
.offset = offsetof(ISSUING_DIST_POINT, onlysomereasons),
|
||||
.field_name = "onlysomereasons",
|
||||
.item = &ASN1_BIT_STRING_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 4,
|
||||
.offset = offsetof(ISSUING_DIST_POINT, indirectCRL),
|
||||
.field_name = "indirectCRL",
|
||||
.item = &ASN1_FBOOLEAN_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 5,
|
||||
.offset = offsetof(ISSUING_DIST_POINT, onlyattr),
|
||||
.field_name = "onlyattr",
|
||||
.item = &ASN1_FBOOLEAN_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM ISSUING_DIST_POINT_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = ISSUING_DIST_POINT_seq_tt,
|
||||
.tcount = sizeof(ISSUING_DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(ISSUING_DIST_POINT),
|
||||
.sname = "ISSUING_DIST_POINT",
|
||||
};
|
||||
|
||||
|
||||
ISSUING_DIST_POINT *
|
||||
d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (ISSUING_DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&ISSUING_DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_ISSUING_DIST_POINT);
|
||||
|
||||
int
|
||||
i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_ISSUING_DIST_POINT);
|
||||
|
||||
ISSUING_DIST_POINT *
|
||||
ISSUING_DIST_POINT_new(void)
|
||||
{
|
||||
return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(ISSUING_DIST_POINT_new);
|
||||
|
||||
void
|
||||
ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(ISSUING_DIST_POINT_free);
|
||||
|
||||
static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
|
||||
int indent);
|
||||
static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(DIST_POINT_set_dpname);
|
||||
131
crypto/x509/x509_d2.c
Normal file
131
crypto/x509/x509_d2.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* $OpenBSD: x509_d2.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_default_paths);
|
||||
|
||||
int
|
||||
X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path)
|
||||
{
|
||||
X509_LOOKUP *lookup;
|
||||
|
||||
if (file != NULL) {
|
||||
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
|
||||
if (lookup == NULL)
|
||||
return (0);
|
||||
if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
|
||||
return (0);
|
||||
}
|
||||
if (path != NULL) {
|
||||
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
|
||||
if (lookup == NULL)
|
||||
return (0);
|
||||
if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
|
||||
return (0);
|
||||
}
|
||||
if ((path == NULL) && (file == NULL))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_load_locations);
|
||||
|
||||
int
|
||||
X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len)
|
||||
{
|
||||
X509_LOOKUP *lookup;
|
||||
struct iovec iov;
|
||||
|
||||
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_mem());
|
||||
if (lookup == NULL)
|
||||
return (0);
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = len;
|
||||
|
||||
if (X509_LOOKUP_add_mem(lookup, &iov, X509_FILETYPE_PEM) != 1)
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_load_mem);
|
||||
104
crypto/x509/x509_def.c
Normal file
104
crypto/x509/x509_def.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/* $OpenBSD: x509_def.c,v 1.7 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_default_private_dir);
|
||||
|
||||
const char *
|
||||
X509_get_default_cert_area(void)
|
||||
{
|
||||
return (X509_CERT_AREA);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_default_cert_area);
|
||||
|
||||
const char *
|
||||
X509_get_default_cert_dir(void)
|
||||
{
|
||||
return (X509_CERT_DIR);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_default_cert_dir);
|
||||
|
||||
const char *
|
||||
X509_get_default_cert_file(void)
|
||||
{
|
||||
return (X509_CERT_FILE);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_default_cert_file);
|
||||
|
||||
const char *
|
||||
X509_get_default_cert_dir_env(void)
|
||||
{
|
||||
return (X509_CERT_DIR_EVP);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_default_cert_dir_env);
|
||||
|
||||
const char *
|
||||
X509_get_default_cert_file_env(void)
|
||||
{
|
||||
return (X509_CERT_FILE_EVP);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_default_cert_file_env);
|
||||
213
crypto/x509/x509_err.c
Normal file
213
crypto/x509/x509_err.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/* $OpenBSD: x509_err.c,v 1.22 2023/05/14 17:20:26 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
|
||||
|
||||
static ERR_STRING_DATA X509_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_INVALID_VERSION) , "invalid x509 version"},
|
||||
{ERR_REASON(X509_R_KEY_TYPE_MISMATCH) , "key type mismatch"},
|
||||
{ERR_REASON(X509_R_KEY_VALUES_MISMATCH) , "key values mismatch"},
|
||||
{ERR_REASON(X509_R_LOADING_CERT_DIR) , "loading cert dir"},
|
||||
{ERR_REASON(X509_R_LOADING_DEFAULTS) , "loading defaults"},
|
||||
{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) , "method not supported"},
|
||||
{ERR_REASON(X509_R_NO_CERTIFICATE_OR_CRL_FOUND), "no certificate or crl found"},
|
||||
{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), "no cert set for us to verify"},
|
||||
{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"},
|
||||
{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"},
|
||||
{ERR_REASON(X509_R_SHOULD_RETRY) , "should retry"},
|
||||
{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), "unable to find parameters in chain"},
|
||||
{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), "unable to get certs public key"},
|
||||
{ERR_REASON(X509_R_UNKNOWN_KEY_TYPE) , "unknown key type"},
|
||||
{ERR_REASON(X509_R_UNKNOWN_NID) , "unknown nid"},
|
||||
{ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID) , "unknown purpose id"},
|
||||
{ERR_REASON(X509_R_UNKNOWN_TRUST_ID) , "unknown trust id"},
|
||||
{ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
|
||||
{ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) , "wrong lookup type"},
|
||||
{ERR_REASON(X509_R_WRONG_TYPE) , "wrong type"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#undef ERR_FUNC
|
||||
#undef ERR_REASON
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
|
||||
|
||||
static ERR_STRING_DATA X509V3_str_functs[] = {
|
||||
{ERR_FUNC(0xfff), "CRYPTO_internal"},
|
||||
{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
|
||||
}
|
||||
LCRYPTO_ALIAS(ERR_load_X509_strings);
|
||||
|
||||
|
||||
void
|
||||
ERR_load_X509V3_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, X509V3_str_functs);
|
||||
ERR_load_strings(0, X509V3_str_reasons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
LCRYPTO_ALIAS(ERR_load_X509V3_strings);
|
||||
262
crypto/x509/x509_ext.c
Normal file
262
crypto/x509/x509_ext.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/* $OpenBSD: x509_ext.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509_CRL_get_ext_count(const X509_CRL *x)
|
||||
{
|
||||
return (X509v3_get_ext_count(x->crl->extensions));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_get_ext_count);
|
||||
|
||||
int
|
||||
X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_get_ext_by_NID);
|
||||
|
||||
int
|
||||
X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_get_ext_by_OBJ);
|
||||
|
||||
int
|
||||
X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_get_ext_by_critical);
|
||||
|
||||
X509_EXTENSION *
|
||||
X509_CRL_get_ext(const X509_CRL *x, int loc)
|
||||
{
|
||||
return (X509v3_get_ext(x->crl->extensions, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_get_ext);
|
||||
|
||||
X509_EXTENSION *
|
||||
X509_CRL_delete_ext(X509_CRL *x, int loc)
|
||||
{
|
||||
return (X509v3_delete_ext(x->crl->extensions, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_delete_ext);
|
||||
|
||||
void *
|
||||
X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx)
|
||||
{
|
||||
return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_get_ext_d2i);
|
||||
|
||||
int
|
||||
X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
|
||||
unsigned long flags)
|
||||
{
|
||||
return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_add1_ext_i2d);
|
||||
|
||||
int
|
||||
X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
|
||||
{
|
||||
return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_add_ext);
|
||||
|
||||
int
|
||||
X509_get_ext_count(const X509 *x)
|
||||
{
|
||||
return (X509v3_get_ext_count(x->cert_info->extensions));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_ext_count);
|
||||
|
||||
int
|
||||
X509_get_ext_by_NID(const X509 *x, int nid, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_ext_by_NID);
|
||||
|
||||
int
|
||||
X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_ext_by_OBJ);
|
||||
|
||||
int
|
||||
X509_get_ext_by_critical(const X509 *x, int crit, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_critical(x->cert_info->extensions, crit,
|
||||
lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_ext_by_critical);
|
||||
|
||||
X509_EXTENSION *
|
||||
X509_get_ext(const X509 *x, int loc)
|
||||
{
|
||||
return (X509v3_get_ext(x->cert_info->extensions, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_ext);
|
||||
|
||||
X509_EXTENSION *
|
||||
X509_delete_ext(X509 *x, int loc)
|
||||
{
|
||||
return (X509v3_delete_ext(x->cert_info->extensions, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_delete_ext);
|
||||
|
||||
int
|
||||
X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
|
||||
{
|
||||
return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_add_ext);
|
||||
|
||||
void *
|
||||
X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx)
|
||||
{
|
||||
return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_ext_d2i);
|
||||
|
||||
int
|
||||
X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags)
|
||||
{
|
||||
return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
|
||||
flags);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_add1_ext_i2d);
|
||||
|
||||
int
|
||||
X509_REVOKED_get_ext_count(const X509_REVOKED *x)
|
||||
{
|
||||
return (X509v3_get_ext_count(x->extensions));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get_ext_count);
|
||||
|
||||
int
|
||||
X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_NID);
|
||||
|
||||
int
|
||||
X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
|
||||
int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_OBJ);
|
||||
|
||||
int
|
||||
X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos)
|
||||
{
|
||||
return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_critical);
|
||||
|
||||
X509_EXTENSION *
|
||||
X509_REVOKED_get_ext(const X509_REVOKED *x, int loc)
|
||||
{
|
||||
return (X509v3_get_ext(x->extensions, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get_ext);
|
||||
|
||||
X509_EXTENSION *
|
||||
X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
|
||||
{
|
||||
return (X509v3_delete_ext(x->extensions, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_delete_ext);
|
||||
|
||||
int
|
||||
X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
|
||||
{
|
||||
return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_add_ext);
|
||||
|
||||
void *
|
||||
X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx)
|
||||
{
|
||||
return X509V3_get_d2i(x->extensions, nid, crit, idx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get_ext_d2i);
|
||||
|
||||
int
|
||||
X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
|
||||
unsigned long flags)
|
||||
{
|
||||
return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_add1_ext_i2d);
|
||||
221
crypto/x509/x509_extku.c
Normal file
221
crypto/x509/x509_extku.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/* $OpenBSD: x509_extku.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_EXTENDED_KEY_USAGE);
|
||||
|
||||
int
|
||||
i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &EXTENDED_KEY_USAGE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_EXTENDED_KEY_USAGE);
|
||||
|
||||
EXTENDED_KEY_USAGE *
|
||||
EXTENDED_KEY_USAGE_new(void)
|
||||
{
|
||||
return (EXTENDED_KEY_USAGE *)ASN1_item_new(&EXTENDED_KEY_USAGE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_new);
|
||||
|
||||
void
|
||||
EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &EXTENDED_KEY_USAGE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_free);
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
|
||||
STACK_OF(CONF_VALUE) *extlist)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
EXTENDED_KEY_USAGE *eku = a;
|
||||
STACK_OF(CONF_VALUE) *free_extlist = NULL;
|
||||
char obj_tmp[80];
|
||||
int i;
|
||||
|
||||
if (extlist == NULL) {
|
||||
if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
|
||||
if ((obj = sk_ASN1_OBJECT_value(eku, i)) == NULL)
|
||||
goto err;
|
||||
if (!i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, obj))
|
||||
goto err;
|
||||
if (!X509V3_add_value(NULL, obj_tmp, &extlist))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return extlist;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
EXTENDED_KEY_USAGE *extku;
|
||||
char *extval;
|
||||
ASN1_OBJECT *objtmp;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
|
||||
if (!(extku = sk_ASN1_OBJECT_new_null())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (val->value)
|
||||
extval = val->value;
|
||||
else
|
||||
extval = val->name;
|
||||
if (!(objtmp = OBJ_txt2obj(extval, 0))) {
|
||||
sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
|
||||
X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
|
||||
X509V3_conf_err(val);
|
||||
return NULL;
|
||||
}
|
||||
if (sk_ASN1_OBJECT_push(extku, objtmp) == 0) {
|
||||
ASN1_OBJECT_free(objtmp);
|
||||
sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return extku;
|
||||
}
|
||||
537
crypto/x509/x509_genn.c
Normal file
537
crypto/x509/x509_genn.c
Normal file
@@ -0,0 +1,537 @@
|
||||
/* $OpenBSD: x509_genn.c,v 1.6 2023/04/25 15:51:04 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_OTHERNAME);
|
||||
|
||||
int
|
||||
i2d_OTHERNAME(OTHERNAME *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_OTHERNAME);
|
||||
|
||||
OTHERNAME *
|
||||
OTHERNAME_new(void)
|
||||
{
|
||||
return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(OTHERNAME_new);
|
||||
|
||||
void
|
||||
OTHERNAME_free(OTHERNAME *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(OTHERNAME_free);
|
||||
|
||||
/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */
|
||||
static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = {
|
||||
{
|
||||
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
|
||||
.tag = 0,
|
||||
.offset = offsetof(EDIPARTYNAME, nameAssigner),
|
||||
.field_name = "nameAssigner",
|
||||
.item = &DIRECTORYSTRING_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_EXPLICIT,
|
||||
.tag = 1,
|
||||
.offset = offsetof(EDIPARTYNAME, partyName),
|
||||
.field_name = "partyName",
|
||||
.item = &DIRECTORYSTRING_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM EDIPARTYNAME_it = {
|
||||
.itype = ASN1_ITYPE_SEQUENCE,
|
||||
.utype = V_ASN1_SEQUENCE,
|
||||
.templates = EDIPARTYNAME_seq_tt,
|
||||
.tcount = sizeof(EDIPARTYNAME_seq_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(EDIPARTYNAME),
|
||||
.sname = "EDIPARTYNAME",
|
||||
};
|
||||
|
||||
|
||||
EDIPARTYNAME *
|
||||
d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&EDIPARTYNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_EDIPARTYNAME);
|
||||
|
||||
int
|
||||
i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_EDIPARTYNAME);
|
||||
|
||||
EDIPARTYNAME *
|
||||
EDIPARTYNAME_new(void)
|
||||
{
|
||||
return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(EDIPARTYNAME_new);
|
||||
|
||||
void
|
||||
EDIPARTYNAME_free(EDIPARTYNAME *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(EDIPARTYNAME_free);
|
||||
|
||||
static const ASN1_TEMPLATE GENERAL_NAME_ch_tt[] = {
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_OTHERNAME,
|
||||
.offset = offsetof(GENERAL_NAME, d.otherName),
|
||||
.field_name = "d.otherName",
|
||||
.item = &OTHERNAME_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_EMAIL,
|
||||
.offset = offsetof(GENERAL_NAME, d.rfc822Name),
|
||||
.field_name = "d.rfc822Name",
|
||||
.item = &ASN1_IA5STRING_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_DNS,
|
||||
.offset = offsetof(GENERAL_NAME, d.dNSName),
|
||||
.field_name = "d.dNSName",
|
||||
.item = &ASN1_IA5STRING_it,
|
||||
},
|
||||
/* Don't decode this */
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_X400,
|
||||
.offset = offsetof(GENERAL_NAME, d.x400Address),
|
||||
.field_name = "d.x400Address",
|
||||
.item = &ASN1_SEQUENCE_it,
|
||||
},
|
||||
/* X509_NAME is a CHOICE type so use EXPLICIT */
|
||||
{
|
||||
.flags = ASN1_TFLG_EXPLICIT,
|
||||
.tag = GEN_DIRNAME,
|
||||
.offset = offsetof(GENERAL_NAME, d.directoryName),
|
||||
.field_name = "d.directoryName",
|
||||
.item = &X509_NAME_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_EDIPARTY,
|
||||
.offset = offsetof(GENERAL_NAME, d.ediPartyName),
|
||||
.field_name = "d.ediPartyName",
|
||||
.item = &EDIPARTYNAME_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_URI,
|
||||
.offset = offsetof(GENERAL_NAME, d.uniformResourceIdentifier),
|
||||
.field_name = "d.uniformResourceIdentifier",
|
||||
.item = &ASN1_IA5STRING_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_IPADD,
|
||||
.offset = offsetof(GENERAL_NAME, d.iPAddress),
|
||||
.field_name = "d.iPAddress",
|
||||
.item = &ASN1_OCTET_STRING_it,
|
||||
},
|
||||
{
|
||||
.flags = ASN1_TFLG_IMPLICIT,
|
||||
.tag = GEN_RID,
|
||||
.offset = offsetof(GENERAL_NAME, d.registeredID),
|
||||
.field_name = "d.registeredID",
|
||||
.item = &ASN1_OBJECT_it,
|
||||
},
|
||||
};
|
||||
|
||||
const ASN1_ITEM GENERAL_NAME_it = {
|
||||
.itype = ASN1_ITYPE_CHOICE,
|
||||
.utype = offsetof(GENERAL_NAME, type),
|
||||
.templates = GENERAL_NAME_ch_tt,
|
||||
.tcount = sizeof(GENERAL_NAME_ch_tt) / sizeof(ASN1_TEMPLATE),
|
||||
.funcs = NULL,
|
||||
.size = sizeof(GENERAL_NAME),
|
||||
.sname = "GENERAL_NAME",
|
||||
};
|
||||
|
||||
|
||||
GENERAL_NAME *
|
||||
d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (GENERAL_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&GENERAL_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_GENERAL_NAME);
|
||||
|
||||
int
|
||||
i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_GENERAL_NAME);
|
||||
|
||||
GENERAL_NAME *
|
||||
GENERAL_NAME_new(void)
|
||||
{
|
||||
return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_new);
|
||||
|
||||
void
|
||||
GENERAL_NAME_free(GENERAL_NAME *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_free);
|
||||
|
||||
static const ASN1_TEMPLATE GENERAL_NAMES_item_tt = {
|
||||
.flags = ASN1_TFLG_SEQUENCE_OF,
|
||||
.tag = 0,
|
||||
.offset = 0,
|
||||
.field_name = "GeneralNames",
|
||||
.item = &GENERAL_NAME_it,
|
||||
};
|
||||
|
||||
const ASN1_ITEM GENERAL_NAMES_it = {
|
||||
.itype = ASN1_ITYPE_PRIMITIVE,
|
||||
.utype = -1,
|
||||
.templates = &GENERAL_NAMES_item_tt,
|
||||
.tcount = 0,
|
||||
.funcs = NULL,
|
||||
.size = 0,
|
||||
.sname = "GENERAL_NAMES",
|
||||
};
|
||||
|
||||
|
||||
GENERAL_NAMES *
|
||||
d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (GENERAL_NAMES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&GENERAL_NAMES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_GENERAL_NAMES);
|
||||
|
||||
int
|
||||
i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_GENERAL_NAMES);
|
||||
|
||||
GENERAL_NAMES *
|
||||
GENERAL_NAMES_new(void)
|
||||
{
|
||||
return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAMES_new);
|
||||
|
||||
void
|
||||
GENERAL_NAMES_free(GENERAL_NAMES *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAMES_free);
|
||||
|
||||
GENERAL_NAME *
|
||||
GENERAL_NAME_dup(GENERAL_NAME *a)
|
||||
{
|
||||
return ASN1_item_dup(&GENERAL_NAME_it, a);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_dup);
|
||||
|
||||
static int
|
||||
EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
|
||||
{
|
||||
int res;
|
||||
|
||||
/*
|
||||
* Shouldn't be possible in a valid GENERAL_NAME, but we handle it
|
||||
* anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here.
|
||||
*/
|
||||
if (a == NULL || b == NULL)
|
||||
return -1;
|
||||
if (a->nameAssigner == NULL && b->nameAssigner != NULL)
|
||||
return -1;
|
||||
if (a->nameAssigner != NULL && b->nameAssigner == NULL)
|
||||
return 1;
|
||||
/* If we get here, both have nameAssigner set or both unset. */
|
||||
if (a->nameAssigner != NULL) {
|
||||
res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
* partyName is required, so these should never be NULL. We treat it in
|
||||
* the same way as the a == NULL || b == NULL case above.
|
||||
*/
|
||||
if (a->partyName == NULL || b->partyName == NULL)
|
||||
return -1;
|
||||
|
||||
return ASN1_STRING_cmp(a->partyName, b->partyName);
|
||||
}
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int
|
||||
GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (!a || !b || a->type != b->type)
|
||||
return -1;
|
||||
switch (a->type) {
|
||||
case GEN_X400:
|
||||
result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
|
||||
break;
|
||||
|
||||
case GEN_EDIPARTY:
|
||||
result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName);
|
||||
break;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
|
||||
break;
|
||||
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
|
||||
break;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
|
||||
break;
|
||||
|
||||
case GEN_IPADD:
|
||||
result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
result = OBJ_cmp(a->d.rid, b->d.rid);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_cmp);
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int
|
||||
OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (!a || !b)
|
||||
return -1;
|
||||
/* Check their type first. */
|
||||
if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
|
||||
return result;
|
||||
/* Check the value. */
|
||||
result = ASN1_TYPE_cmp(a->value, b->value);
|
||||
return result;
|
||||
}
|
||||
LCRYPTO_ALIAS(OTHERNAME_cmp);
|
||||
|
||||
void
|
||||
GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
|
||||
{
|
||||
switch (type) {
|
||||
case GEN_X400:
|
||||
a->d.x400Address = value;
|
||||
break;
|
||||
|
||||
case GEN_EDIPARTY:
|
||||
a->d.ediPartyName = value;
|
||||
break;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
a->d.otherName = value;
|
||||
break;
|
||||
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
a->d.ia5 = value;
|
||||
break;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
a->d.dirn = value;
|
||||
break;
|
||||
|
||||
case GEN_IPADD:
|
||||
a->d.ip = value;
|
||||
break;
|
||||
|
||||
case GEN_RID:
|
||||
a->d.rid = value;
|
||||
break;
|
||||
}
|
||||
a->type = type;
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_set0_value);
|
||||
|
||||
void *
|
||||
GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
|
||||
{
|
||||
if (ptype)
|
||||
*ptype = a->type;
|
||||
switch (a->type) {
|
||||
case GEN_X400:
|
||||
return a->d.x400Address;
|
||||
|
||||
case GEN_EDIPARTY:
|
||||
return a->d.ediPartyName;
|
||||
|
||||
case GEN_OTHERNAME:
|
||||
return a->d.otherName;
|
||||
|
||||
case GEN_EMAIL:
|
||||
case GEN_DNS:
|
||||
case GEN_URI:
|
||||
return a->d.ia5;
|
||||
|
||||
case GEN_DIRNAME:
|
||||
return a->d.dirn;
|
||||
|
||||
case GEN_IPADD:
|
||||
return a->d.ip;
|
||||
|
||||
case GEN_RID:
|
||||
return a->d.rid;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_get0_value);
|
||||
|
||||
int
|
||||
GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid,
|
||||
ASN1_TYPE *value)
|
||||
{
|
||||
OTHERNAME *oth;
|
||||
|
||||
oth = OTHERNAME_new();
|
||||
if (!oth)
|
||||
return 0;
|
||||
oth->type_id = oid;
|
||||
oth->value = value;
|
||||
GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_set0_othername);
|
||||
|
||||
int
|
||||
GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, ASN1_OBJECT **poid,
|
||||
ASN1_TYPE **pvalue)
|
||||
{
|
||||
if (gen->type != GEN_OTHERNAME)
|
||||
return 0;
|
||||
if (poid)
|
||||
*poid = gen->d.otherName->type_id;
|
||||
if (pvalue)
|
||||
*pvalue = gen->d.otherName->value;
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_NAME_get0_otherName);
|
||||
238
crypto/x509/x509_ia5.c
Normal file
238
crypto/x509/x509_ia5.c
Normal 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;
|
||||
}
|
||||
317
crypto/x509/x509_info.c
Normal file
317
crypto/x509/x509_info.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/* $OpenBSD: x509_info.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_ACCESS_DESCRIPTION);
|
||||
|
||||
int
|
||||
i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ACCESS_DESCRIPTION_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_ACCESS_DESCRIPTION);
|
||||
|
||||
ACCESS_DESCRIPTION *
|
||||
ACCESS_DESCRIPTION_new(void)
|
||||
{
|
||||
return (ACCESS_DESCRIPTION *)ASN1_item_new(&ACCESS_DESCRIPTION_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(ACCESS_DESCRIPTION_new);
|
||||
|
||||
void
|
||||
ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &ACCESS_DESCRIPTION_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(ACCESS_DESCRIPTION_free);
|
||||
|
||||
static const ASN1_TEMPLATE AUTHORITY_INFO_ACCESS_item_tt = {
|
||||
.flags = ASN1_TFLG_SEQUENCE_OF,
|
||||
.tag = 0,
|
||||
.offset = 0,
|
||||
.field_name = "GeneralNames",
|
||||
.item = &ACCESS_DESCRIPTION_it,
|
||||
};
|
||||
|
||||
const ASN1_ITEM AUTHORITY_INFO_ACCESS_it = {
|
||||
.itype = ASN1_ITYPE_PRIMITIVE,
|
||||
.utype = -1,
|
||||
.templates = &AUTHORITY_INFO_ACCESS_item_tt,
|
||||
.tcount = 0,
|
||||
.funcs = NULL,
|
||||
.size = 0,
|
||||
.sname = "AUTHORITY_INFO_ACCESS",
|
||||
};
|
||||
|
||||
|
||||
AUTHORITY_INFO_ACCESS *
|
||||
d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len)
|
||||
{
|
||||
return (AUTHORITY_INFO_ACCESS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
&AUTHORITY_INFO_ACCESS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_AUTHORITY_INFO_ACCESS);
|
||||
|
||||
int
|
||||
i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_INFO_ACCESS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_AUTHORITY_INFO_ACCESS);
|
||||
|
||||
AUTHORITY_INFO_ACCESS *
|
||||
AUTHORITY_INFO_ACCESS_new(void)
|
||||
{
|
||||
return (AUTHORITY_INFO_ACCESS *)ASN1_item_new(&AUTHORITY_INFO_ACCESS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_new);
|
||||
|
||||
void
|
||||
AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_INFO_ACCESS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_free);
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
|
||||
AUTHORITY_INFO_ACCESS *ainfo, STACK_OF(CONF_VALUE) *ret)
|
||||
{
|
||||
ACCESS_DESCRIPTION *desc;
|
||||
CONF_VALUE *vtmp;
|
||||
STACK_OF(CONF_VALUE) *free_ret = NULL;
|
||||
char objtmp[80], *ntmp;
|
||||
int i;
|
||||
|
||||
if (ret == NULL) {
|
||||
if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
|
||||
if ((desc = sk_ACCESS_DESCRIPTION_value(ainfo, i)) == NULL)
|
||||
goto err;
|
||||
if ((ret = i2v_GENERAL_NAME(method, desc->location,
|
||||
ret)) == NULL)
|
||||
goto err;
|
||||
if ((vtmp = sk_CONF_VALUE_value(ret, i)) == NULL)
|
||||
goto err;
|
||||
if (!i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method))
|
||||
goto err;
|
||||
if (asprintf(&ntmp, "%s - %s", objtmp, vtmp->name) == -1) {
|
||||
ntmp = NULL;
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
free(vtmp->name);
|
||||
vtmp->name = ntmp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static AUTHORITY_INFO_ACCESS *
|
||||
v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
AUTHORITY_INFO_ACCESS *ainfo = NULL;
|
||||
CONF_VALUE *cnf, ctmp;
|
||||
ACCESS_DESCRIPTION *acc;
|
||||
int i, objlen;
|
||||
char *objtmp, *ptmp;
|
||||
|
||||
if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
cnf = sk_CONF_VALUE_value(nval, i);
|
||||
if ((acc = ACCESS_DESCRIPTION_new()) == NULL) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (sk_ACCESS_DESCRIPTION_push(ainfo, acc) == 0) {
|
||||
ACCESS_DESCRIPTION_free(acc);
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ptmp = strchr(cnf->name, ';');
|
||||
if (!ptmp) {
|
||||
X509V3error(X509V3_R_INVALID_SYNTAX);
|
||||
goto err;
|
||||
}
|
||||
objlen = ptmp - cnf->name;
|
||||
ctmp.name = ptmp + 1;
|
||||
ctmp.value = cnf->value;
|
||||
if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
|
||||
goto err;
|
||||
if (!(objtmp = malloc(objlen + 1))) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
strlcpy(objtmp, cnf->name, objlen + 1);
|
||||
acc->method = OBJ_txt2obj(objtmp, 0);
|
||||
if (!acc->method) {
|
||||
X509V3error(X509V3_R_BAD_OBJECT);
|
||||
ERR_asprintf_error_data("value=%s", objtmp);
|
||||
free(objtmp);
|
||||
goto err;
|
||||
}
|
||||
free(objtmp);
|
||||
}
|
||||
return ainfo;
|
||||
|
||||
err:
|
||||
sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a)
|
||||
{
|
||||
i2a_ASN1_OBJECT(bp, a->method);
|
||||
return 2;
|
||||
}
|
||||
LCRYPTO_ALIAS(i2a_ACCESS_DESCRIPTION);
|
||||
110
crypto/x509/x509_int.c
Normal file
110
crypto/x509/x509_int.c
Normal 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
|
||||
};
|
||||
141
crypto/x509/x509_internal.h
Normal file
141
crypto/x509/x509_internal.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/* $OpenBSD: x509_internal.h,v 1.25 2023/01/28 19:08:09 tb 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 "bytestring.h"
|
||||
#include "x509_local.h"
|
||||
#include "x509_verify.h"
|
||||
|
||||
/* Hard limits on structure size and number of signature checks. */
|
||||
#define X509_VERIFY_MAX_CHAINS 8 /* Max validated chains */
|
||||
#define X509_VERIFY_MAX_CHAIN_CERTS 32 /* Max depth of a chain */
|
||||
#define X509_VERIFY_MAX_SIGCHECKS 256 /* Max signature checks */
|
||||
|
||||
/*
|
||||
* Limit the number of names and constraints we will check in a chain
|
||||
* to avoid a hostile input DOS
|
||||
*/
|
||||
#define X509_VERIFY_MAX_CHAIN_NAMES 512
|
||||
#define X509_VERIFY_MAX_CHAIN_CONSTRAINTS 512
|
||||
|
||||
/*
|
||||
* Hold the parsed and validated result of names from a certificate.
|
||||
* these typically come from a GENERALNAME, but we store the parsed
|
||||
* and validated results, not the ASN1 bytes.
|
||||
*/
|
||||
struct x509_constraints_name {
|
||||
int type; /* GEN_* types from GENERAL_NAME */
|
||||
char *name; /* Name to check */
|
||||
char *local; /* holds the local part of GEN_EMAIL */
|
||||
uint8_t *der; /* DER encoded value or NULL*/
|
||||
size_t der_len;
|
||||
int af; /* INET and INET6 are supported */
|
||||
uint8_t address[32]; /* Must hold ipv6 + mask */
|
||||
};
|
||||
|
||||
struct x509_constraints_names {
|
||||
struct x509_constraints_name **names;
|
||||
size_t names_count;
|
||||
size_t names_len;
|
||||
size_t names_max;
|
||||
};
|
||||
|
||||
struct x509_verify_chain {
|
||||
STACK_OF(X509) *certs; /* Kept in chain order, includes leaf */
|
||||
int *cert_errors; /* Verify error for each cert in chain. */
|
||||
struct x509_constraints_names *names; /* All names from all certs */
|
||||
};
|
||||
|
||||
struct x509_verify_ctx {
|
||||
X509_STORE_CTX *xsc;
|
||||
struct x509_verify_chain **chains; /* Validated chains */
|
||||
STACK_OF(X509) *saved_error_chain;
|
||||
int saved_error;
|
||||
int saved_error_depth;
|
||||
size_t chains_count;
|
||||
STACK_OF(X509) *roots; /* Trusted roots for this validation */
|
||||
STACK_OF(X509) *intermediates; /* Intermediates provided by peer */
|
||||
time_t *check_time; /* Time for validity checks */
|
||||
int purpose; /* Cert purpose we are validating */
|
||||
size_t max_chains; /* Max chains to return */
|
||||
size_t max_depth; /* Max chain depth for validation */
|
||||
size_t max_sigs; /* Max number of signature checks */
|
||||
size_t sig_checks; /* Number of signature checks done */
|
||||
size_t error_depth; /* Depth of last error seen */
|
||||
int error; /* Last error seen */
|
||||
};
|
||||
|
||||
int ASN1_time_tm_clamp_notafter(struct tm *tm);
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
int x509_vfy_check_id(X509_STORE_CTX *ctx);
|
||||
int x509_vfy_check_revocation(X509_STORE_CTX *ctx);
|
||||
int x509_vfy_check_policy(X509_STORE_CTX *ctx);
|
||||
int x509_vfy_check_trust(X509_STORE_CTX *ctx);
|
||||
int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
|
||||
int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx);
|
||||
int x509v3_cache_extensions(X509 *x);
|
||||
X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
|
||||
|
||||
time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter);
|
||||
|
||||
struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc);
|
||||
|
||||
void x509_constraints_name_clear(struct x509_constraints_name *name);
|
||||
void x509_constraints_name_free(struct x509_constraints_name *name);
|
||||
int x509_constraints_names_add(struct x509_constraints_names *names,
|
||||
struct x509_constraints_name *name);
|
||||
struct x509_constraints_names *x509_constraints_names_dup(
|
||||
struct x509_constraints_names *names);
|
||||
void x509_constraints_names_clear(struct x509_constraints_names *names);
|
||||
struct x509_constraints_names *x509_constraints_names_new(size_t names_max);
|
||||
int x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes,
|
||||
size_t *len);
|
||||
void x509_constraints_names_free(struct x509_constraints_names *names);
|
||||
int x509_constraints_valid_host(CBS *cbs);
|
||||
int x509_constraints_valid_sandns(CBS *cbs);
|
||||
int x509_constraints_domain(char *domain, size_t dlen, char *constraint,
|
||||
size_t len);
|
||||
int x509_constraints_parse_mailbox(CBS *candidate,
|
||||
struct x509_constraints_name *name);
|
||||
int x509_constraints_valid_domain_constraint(CBS *cbs);
|
||||
int x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostp);
|
||||
int x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint,
|
||||
size_t len, int *error);
|
||||
int x509_constraints_extract_names(struct x509_constraints_names *names,
|
||||
X509 *cert, int include_cn, int *error);
|
||||
int x509_constraints_extract_constraints(X509 *cert,
|
||||
struct x509_constraints_names *permitted,
|
||||
struct x509_constraints_names *excluded, int *error);
|
||||
int x509_constraints_validate(GENERAL_NAME *constraint,
|
||||
struct x509_constraints_name **out_name, int *error);
|
||||
int x509_constraints_check(struct x509_constraints_names *names,
|
||||
struct x509_constraints_names *permitted,
|
||||
struct x509_constraints_names *excluded, int *error);
|
||||
int x509_constraints_chain(STACK_OF(X509) *chain, int *error,
|
||||
int *depth);
|
||||
void x509_verify_cert_info_populate(X509 *cert);
|
||||
int x509_vfy_check_security_level(X509_STORE_CTX *ctx);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
193
crypto/x509/x509_issuer_cache.c
Normal file
193
crypto/x509/x509_issuer_cache.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/* $OpenBSD: x509_issuer_cache.c,v 1.4 2022/12/26 07:18:53 jmc 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the oldest entry in the issuer cache. Returns 1
|
||||
* if an entry was successfully freed, 0 otherwise. Must
|
||||
* be called with x509_issuer_tree_mutex held.
|
||||
*/
|
||||
void
|
||||
x509_issuer_cache_free_oldest()
|
||||
{
|
||||
struct x509_issuer *old;
|
||||
|
||||
if (x509_issuer_cache_count == 0)
|
||||
return;
|
||||
old = TAILQ_LAST(&x509_issuer_lru, lruqueue);
|
||||
TAILQ_REMOVE(&x509_issuer_lru, old, queue);
|
||||
RB_REMOVE(x509_issuer_tree, &x509_issuer_cache, old);
|
||||
free(old->parent_md);
|
||||
free(old->child_md);
|
||||
free(old);
|
||||
x509_issuer_cache_count--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the entire issuer cache, discarding all entries.
|
||||
*/
|
||||
void
|
||||
x509_issuer_cache_free()
|
||||
{
|
||||
if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
|
||||
return;
|
||||
while (x509_issuer_cache_count > 0)
|
||||
x509_issuer_cache_free_oldest();
|
||||
(void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a previous result of checking if parent signed child
|
||||
*
|
||||
* Returns:
|
||||
* -1 : No entry exists in the cache. signature must be checked.
|
||||
* 0 : The signature of parent signing child is invalid.
|
||||
* 1 : The signature of parent signing child is valid.
|
||||
*/
|
||||
int
|
||||
x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md)
|
||||
{
|
||||
struct x509_issuer candidate, *found;
|
||||
int ret = -1;
|
||||
|
||||
memset(&candidate, 0, sizeof(candidate));
|
||||
candidate.parent_md = parent_md;
|
||||
candidate.child_md = child_md;
|
||||
|
||||
if (x509_issuer_cache_max == 0)
|
||||
return -1;
|
||||
|
||||
if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
|
||||
return -1;
|
||||
if ((found = RB_FIND(x509_issuer_tree, &x509_issuer_cache,
|
||||
&candidate)) != NULL) {
|
||||
TAILQ_REMOVE(&x509_issuer_lru, found, queue);
|
||||
TAILQ_INSERT_HEAD(&x509_issuer_lru, found, queue);
|
||||
ret = found->valid;
|
||||
}
|
||||
(void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to add a validation result to the cache.
|
||||
*
|
||||
* valid must be:
|
||||
* 0: The signature of parent signing child is invalid.
|
||||
* 1: The signature of parent signing child is valid.
|
||||
*
|
||||
* Previously added entries for the same parent and child are *not* replaced.
|
||||
*/
|
||||
void
|
||||
x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md,
|
||||
int valid)
|
||||
{
|
||||
struct x509_issuer *new;
|
||||
|
||||
if (x509_issuer_cache_max == 0)
|
||||
return;
|
||||
if (valid != 0 && valid != 1)
|
||||
return;
|
||||
|
||||
if ((new = calloc(1, sizeof(struct x509_issuer))) == NULL)
|
||||
return;
|
||||
if ((new->parent_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL)
|
||||
goto err;
|
||||
memcpy(new->parent_md, parent_md, EVP_MAX_MD_SIZE);
|
||||
if ((new->child_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL)
|
||||
goto err;
|
||||
memcpy(new->child_md, child_md, EVP_MAX_MD_SIZE);
|
||||
|
||||
new->valid = valid;
|
||||
|
||||
if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
|
||||
goto err;
|
||||
while (x509_issuer_cache_count >= x509_issuer_cache_max)
|
||||
x509_issuer_cache_free_oldest();
|
||||
if (RB_INSERT(x509_issuer_tree, &x509_issuer_cache, new) == NULL) {
|
||||
TAILQ_INSERT_HEAD(&x509_issuer_lru, new, queue);
|
||||
x509_issuer_cache_count++;
|
||||
new = NULL;
|
||||
}
|
||||
(void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
|
||||
|
||||
err:
|
||||
if (new != NULL) {
|
||||
free(new->parent_md);
|
||||
free(new->child_md);
|
||||
}
|
||||
free(new);
|
||||
return;
|
||||
}
|
||||
48
crypto/x509/x509_issuer_cache.h
Normal file
48
crypto/x509/x509_issuer_cache.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $OpenBSD: x509_issuer_cache.h,v 1.2 2022/09/03 17:47:47 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_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);
|
||||
void x509_issuer_cache_free();
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
436
crypto/x509/x509_lib.c
Normal file
436
crypto/x509/x509_lib.c
Normal file
@@ -0,0 +1,436 @@
|
||||
/* $OpenBSD: x509_lib.c,v 1.14 2023/04/25 10:56:58 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* X509 v3 extension utilities */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
|
||||
|
||||
extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
|
||||
extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_info, v3_sinfo;
|
||||
extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
|
||||
extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
|
||||
extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
|
||||
extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
|
||||
extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
|
||||
extern const X509V3_EXT_METHOD v3_crl_hold;
|
||||
extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
|
||||
extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
|
||||
extern const X509V3_EXT_METHOD v3_addr, v3_asid;
|
||||
extern const X509V3_EXT_METHOD v3_ct_scts[3];
|
||||
|
||||
/*
|
||||
* This table needs to be sorted by increasing ext_nid values for OBJ_bsearch_.
|
||||
*/
|
||||
|
||||
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_info,
|
||||
#ifndef OPENSSL_NO_RFC3779
|
||||
&v3_addr,
|
||||
&v3_asid,
|
||||
#endif
|
||||
#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_name_constraints,
|
||||
&v3_policy_mappings,
|
||||
&v3_inhibit_anyp,
|
||||
&v3_idp,
|
||||
&v3_alt[2],
|
||||
&v3_freshest_crl,
|
||||
#ifndef OPENSSL_NO_CT
|
||||
&v3_ct_scts[0],
|
||||
&v3_ct_scts[1],
|
||||
&v3_ct_scts[2],
|
||||
#endif
|
||||
};
|
||||
|
||||
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts) / sizeof(standard_exts[0]))
|
||||
|
||||
static int
|
||||
ext_cmp(const X509V3_EXT_METHOD * const *a, const X509V3_EXT_METHOD * const *b)
|
||||
{
|
||||
return ((*a)->ext_nid - (*b)->ext_nid);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_add);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_get_nid);
|
||||
|
||||
const X509V3_EXT_METHOD *
|
||||
X509V3_EXT_get(X509_EXTENSION *ext)
|
||||
{
|
||||
int nid;
|
||||
|
||||
if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
|
||||
return NULL;
|
||||
return X509V3_EXT_get_nid(nid);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_get);
|
||||
|
||||
int
|
||||
X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
|
||||
{
|
||||
for (; extlist->ext_nid!=-1; extlist++)
|
||||
if (!X509V3_EXT_add(extlist))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_add_list);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_add_alias);
|
||||
|
||||
static void
|
||||
ext_list_free(X509V3_EXT_METHOD *ext)
|
||||
{
|
||||
if (ext->ext_flags & X509V3_EXT_DYNAMIC)
|
||||
free(ext);
|
||||
}
|
||||
|
||||
void
|
||||
X509V3_EXT_cleanup(void)
|
||||
{
|
||||
sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
|
||||
ext_list = NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_cleanup);
|
||||
|
||||
int
|
||||
X509V3_add_standard_extensions(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_add_standard_extensions);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_d2i);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_get_d2i);
|
||||
|
||||
/* 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 ((extmp = sk_X509_EXTENSION_delete(*x, extidx)) == NULL)
|
||||
return -1;
|
||||
X509_EXTENSION_free(extmp);
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_add1_i2d);
|
||||
388
crypto/x509/x509_local.h
Normal file
388
crypto/x509/x509_local.h
Normal file
@@ -0,0 +1,388 @@
|
||||
/* $OpenBSD: x509_local.h,v 1.9 2023/05/28 05:25:24 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2013.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2013 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_X509_LOCAL_H
|
||||
#define HEADER_X509_LOCAL_H
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define TS_HASH_EVP EVP_sha1()
|
||||
#define TS_HASH_LEN SHA_DIGEST_LENGTH
|
||||
|
||||
#define X509_CERT_HASH_EVP EVP_sha512()
|
||||
#define X509_CERT_HASH_LEN SHA512_DIGEST_LENGTH
|
||||
#define X509_CRL_HASH_EVP EVP_sha512()
|
||||
#define X509_CRL_HASH_LEN SHA512_DIGEST_LENGTH
|
||||
|
||||
struct X509_pubkey_st {
|
||||
X509_ALGOR *algor;
|
||||
ASN1_BIT_STRING *public_key;
|
||||
EVP_PKEY *pkey;
|
||||
};
|
||||
|
||||
struct X509_sig_st {
|
||||
X509_ALGOR *algor;
|
||||
ASN1_OCTET_STRING *digest;
|
||||
} /* X509_SIG */;
|
||||
|
||||
struct X509_name_entry_st {
|
||||
ASN1_OBJECT *object;
|
||||
ASN1_STRING *value;
|
||||
int set;
|
||||
int size; /* temp variable */
|
||||
} /* X509_NAME_ENTRY */;
|
||||
|
||||
/* we always keep X509_NAMEs in 2 forms. */
|
||||
struct X509_name_st {
|
||||
STACK_OF(X509_NAME_ENTRY) *entries;
|
||||
int modified; /* true if 'bytes' needs to be built */
|
||||
#ifndef OPENSSL_NO_BUFFER
|
||||
BUF_MEM *bytes;
|
||||
#else
|
||||
char *bytes;
|
||||
#endif
|
||||
/* unsigned long hash; Keep the hash around for lookups */
|
||||
unsigned char *canon_enc;
|
||||
int canon_enclen;
|
||||
} /* X509_NAME */;
|
||||
|
||||
struct X509_extension_st {
|
||||
ASN1_OBJECT *object;
|
||||
ASN1_BOOLEAN critical;
|
||||
ASN1_OCTET_STRING *value;
|
||||
} /* X509_EXTENSION */;
|
||||
|
||||
struct x509_attributes_st {
|
||||
ASN1_OBJECT *object;
|
||||
STACK_OF(ASN1_TYPE) *set;
|
||||
} /* X509_ATTRIBUTE */;
|
||||
|
||||
struct X509_req_info_st {
|
||||
ASN1_ENCODING enc;
|
||||
ASN1_INTEGER *version;
|
||||
X509_NAME *subject;
|
||||
X509_PUBKEY *pubkey;
|
||||
/* d=2 hl=2 l= 0 cons: cont: 00 */
|
||||
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
|
||||
} /* X509_REQ_INFO */;
|
||||
|
||||
struct X509_req_st {
|
||||
X509_REQ_INFO *req_info;
|
||||
X509_ALGOR *sig_alg;
|
||||
ASN1_BIT_STRING *signature;
|
||||
int references;
|
||||
} /* X509_REQ */;
|
||||
|
||||
/*
|
||||
* This stuff is certificate "auxiliary info" it contains details which are
|
||||
* useful in certificate stores and databases. When used this is tagged onto
|
||||
* the end of the certificate itself.
|
||||
*/
|
||||
struct x509_cert_aux_st {
|
||||
STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
|
||||
STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
|
||||
ASN1_UTF8STRING *alias; /* "friendly name" */
|
||||
ASN1_OCTET_STRING *keyid; /* key id of private key */
|
||||
STACK_OF(X509_ALGOR) *other; /* other unspecified info */
|
||||
} /* X509_CERT_AUX */;
|
||||
|
||||
struct x509_cinf_st {
|
||||
ASN1_INTEGER *version; /* [ 0 ] default of v1 */
|
||||
ASN1_INTEGER *serialNumber;
|
||||
X509_ALGOR *signature;
|
||||
X509_NAME *issuer;
|
||||
X509_VAL *validity;
|
||||
X509_NAME *subject;
|
||||
X509_PUBKEY *key;
|
||||
ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
|
||||
ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
|
||||
STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
|
||||
ASN1_ENCODING enc;
|
||||
} /* X509_CINF */;
|
||||
|
||||
struct x509_st {
|
||||
X509_CINF *cert_info;
|
||||
X509_ALGOR *sig_alg;
|
||||
ASN1_BIT_STRING *signature;
|
||||
int valid;
|
||||
int references;
|
||||
char *name;
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
/* These contain copies of various extension values */
|
||||
long ex_pathlen;
|
||||
unsigned long ex_flags;
|
||||
unsigned long ex_kusage;
|
||||
unsigned long ex_xkusage;
|
||||
unsigned long ex_nscert;
|
||||
ASN1_OCTET_STRING *skid;
|
||||
AUTHORITY_KEYID *akid;
|
||||
STACK_OF(DIST_POINT) *crldp;
|
||||
STACK_OF(GENERAL_NAME) *altname;
|
||||
NAME_CONSTRAINTS *nc;
|
||||
#ifndef OPENSSL_NO_RFC3779
|
||||
STACK_OF(IPAddressFamily) *rfc3779_addr;
|
||||
struct ASIdentifiers_st *rfc3779_asid;
|
||||
#endif
|
||||
unsigned char hash[X509_CERT_HASH_LEN];
|
||||
time_t not_before;
|
||||
time_t not_after;
|
||||
X509_CERT_AUX *aux;
|
||||
} /* X509 */;
|
||||
|
||||
struct x509_revoked_st {
|
||||
ASN1_INTEGER *serialNumber;
|
||||
ASN1_TIME *revocationDate;
|
||||
STACK_OF(X509_EXTENSION) /* optional */ *extensions;
|
||||
/* Set up if indirect CRL */
|
||||
STACK_OF(GENERAL_NAME) *issuer;
|
||||
/* Revocation reason */
|
||||
int reason;
|
||||
int sequence; /* load sequence */
|
||||
};
|
||||
|
||||
struct X509_crl_info_st {
|
||||
ASN1_INTEGER *version;
|
||||
X509_ALGOR *sig_alg;
|
||||
X509_NAME *issuer;
|
||||
ASN1_TIME *lastUpdate;
|
||||
ASN1_TIME *nextUpdate;
|
||||
STACK_OF(X509_REVOKED) *revoked;
|
||||
STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
|
||||
ASN1_ENCODING enc;
|
||||
} /* X509_CRL_INFO */;
|
||||
|
||||
struct X509_crl_st {
|
||||
/* actual signature */
|
||||
X509_CRL_INFO *crl;
|
||||
X509_ALGOR *sig_alg;
|
||||
ASN1_BIT_STRING *signature;
|
||||
int references;
|
||||
int flags;
|
||||
/* Copies of various extensions */
|
||||
AUTHORITY_KEYID *akid;
|
||||
ISSUING_DIST_POINT *idp;
|
||||
/* Convenient breakdown of IDP */
|
||||
int idp_flags;
|
||||
int idp_reasons;
|
||||
/* CRL and base CRL numbers for delta processing */
|
||||
ASN1_INTEGER *crl_number;
|
||||
ASN1_INTEGER *base_crl_number;
|
||||
unsigned char hash[X509_CRL_HASH_LEN];
|
||||
STACK_OF(GENERAL_NAMES) *issuers;
|
||||
const X509_CRL_METHOD *meth;
|
||||
void *meth_data;
|
||||
} /* X509_CRL */;
|
||||
|
||||
struct pkcs8_priv_key_info_st {
|
||||
ASN1_INTEGER *version;
|
||||
X509_ALGOR *pkeyalg;
|
||||
ASN1_OCTET_STRING *pkey;
|
||||
STACK_OF(X509_ATTRIBUTE) *attributes;
|
||||
};
|
||||
|
||||
struct x509_object_st {
|
||||
/* one of the above types */
|
||||
int type;
|
||||
union {
|
||||
X509 *x509;
|
||||
X509_CRL *crl;
|
||||
} data;
|
||||
} /* X509_OBJECT */;
|
||||
|
||||
struct x509_lookup_method_st {
|
||||
const char *name;
|
||||
int (*new_item)(X509_LOOKUP *ctx);
|
||||
void (*free)(X509_LOOKUP *ctx);
|
||||
int (*init)(X509_LOOKUP *ctx);
|
||||
int (*shutdown)(X509_LOOKUP *ctx);
|
||||
int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
|
||||
char **ret);
|
||||
int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name,
|
||||
X509_OBJECT *ret);
|
||||
int (*get_by_issuer_serial)(X509_LOOKUP *ctx, int type, X509_NAME *name,
|
||||
ASN1_INTEGER *serial,X509_OBJECT *ret);
|
||||
int (*get_by_fingerprint)(X509_LOOKUP *ctx, int type,
|
||||
const unsigned char *bytes, int len, X509_OBJECT *ret);
|
||||
int (*get_by_alias)(X509_LOOKUP *ctx, int type, const char *str,
|
||||
int len, X509_OBJECT *ret);
|
||||
} /* X509_LOOKUP_METHOD */;
|
||||
|
||||
struct X509_VERIFY_PARAM_st {
|
||||
char *name;
|
||||
time_t check_time; /* Time to use */
|
||||
unsigned long inh_flags; /* Inheritance flags */
|
||||
unsigned long flags; /* Various verify flags */
|
||||
int purpose; /* purpose to check untrusted certificates */
|
||||
int trust; /* trust setting to check */
|
||||
int depth; /* Verify depth */
|
||||
int security_level; /* 'Security level', see SP800-57. */
|
||||
STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
|
||||
STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
|
||||
unsigned int hostflags; /* Flags to control matching features */
|
||||
char *peername; /* Matching hostname in peer certificate */
|
||||
char *email; /* If not NULL email address to match */
|
||||
size_t emaillen;
|
||||
unsigned char *ip; /* If not NULL IP address to match */
|
||||
size_t iplen; /* Length of IP address */
|
||||
int poisoned;
|
||||
} /* X509_VERIFY_PARAM */;
|
||||
|
||||
/*
|
||||
* This is used to hold everything. It is used for all certificate
|
||||
* validation. Once we have a certificate chain, the 'verify'
|
||||
* function is then called to actually check the cert chain.
|
||||
*/
|
||||
struct x509_store_st {
|
||||
/* The following is a cache of trusted certs */
|
||||
STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
|
||||
|
||||
/* These are external lookup methods */
|
||||
STACK_OF(X509_LOOKUP) *get_cert_methods;
|
||||
|
||||
X509_VERIFY_PARAM *param;
|
||||
|
||||
/* Callbacks for various operations */
|
||||
int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */
|
||||
int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */
|
||||
int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */
|
||||
int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
|
||||
int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
|
||||
int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
|
||||
int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
|
||||
int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
|
||||
STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
|
||||
STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
|
||||
int (*cleanup)(X509_STORE_CTX *ctx);
|
||||
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
int references;
|
||||
} /* X509_STORE */;
|
||||
|
||||
/* This is the functions plus an instance of the local variables. */
|
||||
struct x509_lookup_st {
|
||||
int init; /* have we been started */
|
||||
X509_LOOKUP_METHOD *method; /* the functions */
|
||||
char *method_data; /* method data */
|
||||
|
||||
X509_STORE *store_ctx; /* who owns us */
|
||||
} /* X509_LOOKUP */;
|
||||
|
||||
/*
|
||||
* This is used when verifying cert chains. Since the gathering of the cert
|
||||
* chain can take some time (and has to be 'retried'), this needs to be kept
|
||||
* and passed around.
|
||||
*/
|
||||
struct x509_store_ctx_st {
|
||||
X509_STORE *store;
|
||||
int current_method; /* used when looking up certs */
|
||||
|
||||
/* The following are set by the caller */
|
||||
X509 *cert; /* The cert to check */
|
||||
STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */
|
||||
STACK_OF(X509) *trusted; /* trusted stack for use with get_issuer() */
|
||||
STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */
|
||||
|
||||
X509_VERIFY_PARAM *param;
|
||||
|
||||
/* Callbacks for various operations */
|
||||
int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */
|
||||
int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */
|
||||
int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */
|
||||
int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
|
||||
int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
|
||||
int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
|
||||
int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
|
||||
int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
|
||||
int (*check_policy)(X509_STORE_CTX *ctx);
|
||||
STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
|
||||
STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
|
||||
int (*cleanup)(X509_STORE_CTX *ctx);
|
||||
|
||||
/* The following is built up */
|
||||
int valid; /* if 0, rebuild chain */
|
||||
int num_untrusted; /* number of untrusted certs in chain */
|
||||
STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */
|
||||
|
||||
int explicit_policy; /* Require explicit policy value */
|
||||
|
||||
/* When something goes wrong, this is why */
|
||||
int error_depth;
|
||||
int error;
|
||||
X509 *current_cert;
|
||||
X509 *current_issuer; /* cert currently being tested as valid issuer */
|
||||
X509_CRL *current_crl; /* current CRL */
|
||||
|
||||
int current_crl_score; /* score of current CRL */
|
||||
unsigned int current_reasons; /* Reason mask */
|
||||
|
||||
X509_STORE_CTX *parent; /* For CRL path validation: parent context */
|
||||
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
} /* X509_STORE_CTX */;
|
||||
|
||||
int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet);
|
||||
|
||||
int name_cmp(const char *name, const char *cmp);
|
||||
|
||||
int X509_policy_check(const STACK_OF(X509) *certs,
|
||||
const STACK_OF(ASN1_OBJECT) *user_policies, unsigned long flags,
|
||||
X509 **out_current_cert);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif /* !HEADER_X509_LOCAL_H */
|
||||
880
crypto/x509/x509_lu.c
Normal file
880
crypto/x509/x509_lu.c
Normal file
@@ -0,0 +1,880 @@
|
||||
/* $OpenBSD: x509_lu.c,v 1.60 2023/04/25 18:32:42 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/err.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "x509_local.h"
|
||||
|
||||
X509_LOOKUP *
|
||||
X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
|
||||
{
|
||||
X509_LOOKUP *lu;
|
||||
|
||||
if ((lu = calloc(1, sizeof(*lu))) == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lu->method = method;
|
||||
|
||||
if (method->new_item != NULL && !method->new_item(lu)) {
|
||||
free(lu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return lu;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_new);
|
||||
|
||||
void
|
||||
X509_LOOKUP_free(X509_LOOKUP *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
if (ctx->method != NULL && ctx->method->free != NULL)
|
||||
ctx->method->free(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_free);
|
||||
|
||||
int
|
||||
X509_LOOKUP_init(X509_LOOKUP *ctx)
|
||||
{
|
||||
if (ctx->method == NULL)
|
||||
return 0;
|
||||
if (ctx->method->init == NULL)
|
||||
return 1;
|
||||
return ctx->method->init(ctx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_init);
|
||||
|
||||
int
|
||||
X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
|
||||
{
|
||||
if (ctx->method == NULL)
|
||||
return 0;
|
||||
if (ctx->method->shutdown == NULL)
|
||||
return 1;
|
||||
return ctx->method->shutdown(ctx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_shutdown);
|
||||
|
||||
int
|
||||
X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
|
||||
char **ret)
|
||||
{
|
||||
if (ctx->method == NULL)
|
||||
return -1;
|
||||
if (ctx->method->ctrl == NULL)
|
||||
return 1;
|
||||
return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_ctrl);
|
||||
|
||||
int
|
||||
X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, X509_NAME *name,
|
||||
X509_OBJECT *ret)
|
||||
{
|
||||
if (ctx->method == NULL || ctx->method->get_by_subject == NULL)
|
||||
return 0;
|
||||
return ctx->method->get_by_subject(ctx, type, name, ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_by_subject);
|
||||
|
||||
int
|
||||
X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
|
||||
X509_NAME *name, ASN1_INTEGER *serial, X509_OBJECT *ret)
|
||||
{
|
||||
if (ctx->method == NULL || ctx->method->get_by_issuer_serial == NULL)
|
||||
return 0;
|
||||
return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_by_issuer_serial);
|
||||
|
||||
int
|
||||
X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
|
||||
const unsigned char *bytes, int len, X509_OBJECT *ret)
|
||||
{
|
||||
if (ctx->method == NULL || ctx->method->get_by_fingerprint == NULL)
|
||||
return 0;
|
||||
return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_by_fingerprint);
|
||||
|
||||
int
|
||||
X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str,
|
||||
int len, X509_OBJECT *ret)
|
||||
{
|
||||
if (ctx->method == NULL || ctx->method->get_by_alias == NULL)
|
||||
return 0;
|
||||
return ctx->method->get_by_alias(ctx, type, str, len, ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_LOOKUP_by_alias);
|
||||
|
||||
static int
|
||||
x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = (*a)->type - (*b)->type) != 0)
|
||||
return ret;
|
||||
|
||||
switch ((*a)->type) {
|
||||
case X509_LU_X509:
|
||||
return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
|
||||
case X509_LU_CRL:
|
||||
return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
X509_STORE *
|
||||
X509_STORE_new(void)
|
||||
{
|
||||
X509_STORE *store;
|
||||
|
||||
if ((store = calloc(1, sizeof(*store))) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((store->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
|
||||
goto err;
|
||||
if ((store->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
|
||||
goto err;
|
||||
if ((store->param = X509_VERIFY_PARAM_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, store,
|
||||
&store->ex_data))
|
||||
goto err;
|
||||
|
||||
store->references = 1;
|
||||
|
||||
return store;
|
||||
|
||||
err:
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
X509_STORE_free(store);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_new);
|
||||
|
||||
X509_OBJECT *
|
||||
X509_OBJECT_new(void)
|
||||
{
|
||||
X509_OBJECT *obj;
|
||||
|
||||
if ((obj = calloc(1, sizeof(*obj))) == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj->type = X509_LU_NONE;
|
||||
|
||||
return obj;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_new);
|
||||
|
||||
void
|
||||
X509_OBJECT_free(X509_OBJECT *a)
|
||||
{
|
||||
if (a == NULL)
|
||||
return;
|
||||
|
||||
switch (a->type) {
|
||||
case X509_LU_X509:
|
||||
X509_free(a->data.x509);
|
||||
break;
|
||||
case X509_LU_CRL:
|
||||
X509_CRL_free(a->data.crl);
|
||||
break;
|
||||
}
|
||||
|
||||
free(a);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_free);
|
||||
|
||||
void
|
||||
X509_STORE_free(X509_STORE *store)
|
||||
{
|
||||
STACK_OF(X509_LOOKUP) *sk;
|
||||
X509_LOOKUP *lu;
|
||||
int i;
|
||||
|
||||
if (store == NULL)
|
||||
return;
|
||||
|
||||
if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0)
|
||||
return;
|
||||
|
||||
sk = store->get_cert_methods;
|
||||
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
|
||||
lu = sk_X509_LOOKUP_value(sk, i);
|
||||
X509_LOOKUP_shutdown(lu);
|
||||
X509_LOOKUP_free(lu);
|
||||
}
|
||||
sk_X509_LOOKUP_free(sk);
|
||||
sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free);
|
||||
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data);
|
||||
X509_VERIFY_PARAM_free(store->param);
|
||||
free(store);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_free);
|
||||
|
||||
int
|
||||
X509_STORE_up_ref(X509_STORE *store)
|
||||
{
|
||||
return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_up_ref);
|
||||
|
||||
X509_LOOKUP *
|
||||
X509_STORE_add_lookup(X509_STORE *store, X509_LOOKUP_METHOD *method)
|
||||
{
|
||||
STACK_OF(X509_LOOKUP) *sk;
|
||||
X509_LOOKUP *lu;
|
||||
int i;
|
||||
|
||||
sk = store->get_cert_methods;
|
||||
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
|
||||
lu = sk_X509_LOOKUP_value(sk, i);
|
||||
if (method == lu->method) {
|
||||
return lu;
|
||||
}
|
||||
}
|
||||
|
||||
if ((lu = X509_LOOKUP_new(method)) == NULL)
|
||||
return NULL;
|
||||
|
||||
lu->store_ctx = store;
|
||||
if (sk_X509_LOOKUP_push(store->get_cert_methods, lu) <= 0) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
X509_LOOKUP_free(lu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return lu;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_add_lookup);
|
||||
|
||||
X509_OBJECT *
|
||||
X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
|
||||
X509_NAME *name)
|
||||
{
|
||||
X509_OBJECT *obj;
|
||||
|
||||
if ((obj = X509_OBJECT_new()) == NULL)
|
||||
return NULL;
|
||||
if (!X509_STORE_CTX_get_by_subject(vs, type, name, obj)) {
|
||||
X509_OBJECT_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_CTX_get_obj_by_subject);
|
||||
|
||||
int
|
||||
X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
|
||||
X509_NAME *name, X509_OBJECT *ret)
|
||||
{
|
||||
X509_STORE *ctx = vs->store;
|
||||
X509_LOOKUP *lu;
|
||||
X509_OBJECT stmp, *tmp;
|
||||
int i;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
memset(&stmp, 0, sizeof(stmp));
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
|
||||
if (tmp == NULL || type == X509_LU_CRL) {
|
||||
for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
|
||||
lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
|
||||
if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) {
|
||||
tmp = &stmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!X509_OBJECT_up_ref_count(tmp))
|
||||
return 0;
|
||||
|
||||
*ret = *tmp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_CTX_get_by_subject);
|
||||
|
||||
/* Add obj to the store. Takes ownership of obj. */
|
||||
static int
|
||||
X509_STORE_add_object(X509_STORE *store, X509_OBJECT *obj)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
|
||||
if (X509_OBJECT_retrieve_match(store->objs, obj) != NULL) {
|
||||
/* Object is already present in the store. That's fine. */
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sk_X509_OBJECT_push(store->objs, obj) <= 0) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
ret = 1;
|
||||
|
||||
out:
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
X509_OBJECT_free(obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
X509_STORE_add_cert(X509_STORE *store, X509 *x)
|
||||
{
|
||||
X509_OBJECT *obj;
|
||||
|
||||
if (x == NULL)
|
||||
return 0;
|
||||
|
||||
if ((obj = X509_OBJECT_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!X509_up_ref(x)) {
|
||||
X509_OBJECT_free(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
obj->type = X509_LU_X509;
|
||||
obj->data.x509 = x;
|
||||
|
||||
return X509_STORE_add_object(store, obj);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_add_cert);
|
||||
|
||||
int
|
||||
X509_STORE_add_crl(X509_STORE *store, X509_CRL *x)
|
||||
{
|
||||
X509_OBJECT *obj;
|
||||
|
||||
if (x == NULL)
|
||||
return 0;
|
||||
|
||||
if ((obj = X509_OBJECT_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!X509_CRL_up_ref(x)) {
|
||||
X509_OBJECT_free(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
obj->type = X509_LU_CRL;
|
||||
obj->data.crl = x;
|
||||
|
||||
return X509_STORE_add_object(store, obj);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_add_crl);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_up_ref_count);
|
||||
|
||||
X509_LOOKUP_TYPE
|
||||
X509_OBJECT_get_type(const X509_OBJECT *a)
|
||||
{
|
||||
return a->type;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_get_type);
|
||||
|
||||
static int
|
||||
x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
|
||||
X509_NAME *name, int *pnmatch)
|
||||
{
|
||||
X509_OBJECT stmp;
|
||||
X509 x509_s;
|
||||
X509_CINF cinf_s;
|
||||
X509_CRL crl_s;
|
||||
X509_CRL_INFO crl_info_s;
|
||||
int idx;
|
||||
|
||||
stmp.type = type;
|
||||
switch (type) {
|
||||
case X509_LU_X509:
|
||||
stmp.data.x509 = &x509_s;
|
||||
x509_s.cert_info = &cinf_s;
|
||||
cinf_s.subject = name;
|
||||
break;
|
||||
case X509_LU_CRL:
|
||||
stmp.data.crl = &crl_s;
|
||||
crl_s.crl = &crl_info_s;
|
||||
crl_info_s.issuer = name;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
idx = sk_X509_OBJECT_find(h, &stmp);
|
||||
if (idx >= 0 && pnmatch) {
|
||||
int tidx;
|
||||
const X509_OBJECT *tobj, *pstmp;
|
||||
|
||||
*pnmatch = 1;
|
||||
pstmp = &stmp;
|
||||
for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
|
||||
tobj = sk_X509_OBJECT_value(h, tidx);
|
||||
if (x509_object_cmp(&tobj, &pstmp))
|
||||
break;
|
||||
(*pnmatch)++;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
int
|
||||
X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
|
||||
X509_NAME *name)
|
||||
{
|
||||
return x509_object_idx_cnt(h, type, name, NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_idx_by_subject);
|
||||
|
||||
X509_OBJECT *
|
||||
X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
|
||||
X509_NAME *name)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = X509_OBJECT_idx_by_subject(h, type, name);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
return sk_X509_OBJECT_value(h, idx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_retrieve_by_subject);
|
||||
|
||||
X509 *
|
||||
X509_OBJECT_get0_X509(const X509_OBJECT *xo)
|
||||
{
|
||||
if (xo != NULL && xo->type == X509_LU_X509)
|
||||
return xo->data.x509;
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_get0_X509);
|
||||
|
||||
X509_CRL *
|
||||
X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo)
|
||||
{
|
||||
if (xo != NULL && xo->type == X509_LU_CRL)
|
||||
return xo->data.crl;
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_get0_X509_CRL);
|
||||
|
||||
static STACK_OF(X509) *
|
||||
X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name)
|
||||
{
|
||||
STACK_OF(X509) *sk = NULL;
|
||||
X509 *x = NULL;
|
||||
X509_OBJECT *obj;
|
||||
int i, idx, cnt;
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
|
||||
idx = x509_object_idx_cnt(store->objs, X509_LU_X509, name, &cnt);
|
||||
if (idx < 0)
|
||||
goto err;
|
||||
|
||||
if ((sk = sk_X509_new_null()) == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < cnt; i++, idx++) {
|
||||
obj = sk_X509_OBJECT_value(store->objs, idx);
|
||||
|
||||
x = obj->data.x509;
|
||||
if (!X509_up_ref(x)) {
|
||||
x = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (!sk_X509_push(sk, x))
|
||||
goto err;
|
||||
}
|
||||
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
|
||||
return sk;
|
||||
|
||||
err:
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
sk_X509_pop_free(sk, X509_free);
|
||||
X509_free(x);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STACK_OF(X509) *
|
||||
X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name)
|
||||
{
|
||||
X509_STORE *store = ctx->store;
|
||||
STACK_OF(X509) *sk;
|
||||
X509_OBJECT *obj;
|
||||
|
||||
if (store == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((sk = X509_get1_certs_from_cache(store, name)) != NULL)
|
||||
return sk;
|
||||
|
||||
/* Nothing found: do lookup to possibly add new objects to cache. */
|
||||
obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name);
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
X509_OBJECT_free(obj);
|
||||
|
||||
return X509_get1_certs_from_cache(store, name);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_CTX_get1_certs);
|
||||
|
||||
STACK_OF(X509_CRL) *
|
||||
X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name)
|
||||
{
|
||||
X509_STORE *store = ctx->store;
|
||||
STACK_OF(X509_CRL) *sk = NULL;
|
||||
X509_CRL *x = NULL;
|
||||
X509_OBJECT *obj = NULL;
|
||||
int i, idx, cnt;
|
||||
|
||||
if (store == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Always do lookup to possibly add new CRLs to cache */
|
||||
obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_CRL, name);
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
|
||||
X509_OBJECT_free(obj);
|
||||
obj = NULL;
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, name, &cnt);
|
||||
if (idx < 0)
|
||||
goto err;
|
||||
|
||||
if ((sk = sk_X509_CRL_new_null()) == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < cnt; i++, idx++) {
|
||||
obj = sk_X509_OBJECT_value(store->objs, idx);
|
||||
|
||||
x = obj->data.crl;
|
||||
if (!X509_CRL_up_ref(x)) {
|
||||
x = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (!sk_X509_CRL_push(sk, x))
|
||||
goto err;
|
||||
}
|
||||
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
return sk;
|
||||
|
||||
err:
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
X509_CRL_free(x);
|
||||
sk_X509_CRL_pop_free(sk, X509_CRL_free);
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_CTX_get1_crls);
|
||||
|
||||
X509_OBJECT *
|
||||
X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
|
||||
{
|
||||
int idx, i;
|
||||
X509_OBJECT *obj;
|
||||
|
||||
idx = sk_X509_OBJECT_find(h, x);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
|
||||
return sk_X509_OBJECT_value(h, idx);
|
||||
for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
|
||||
obj = sk_X509_OBJECT_value(h, i);
|
||||
if (x509_object_cmp((const X509_OBJECT **)&obj,
|
||||
(const X509_OBJECT **)&x))
|
||||
return NULL;
|
||||
if (x->type == X509_LU_X509) {
|
||||
if (!X509_cmp(obj->data.x509, x->data.x509))
|
||||
return obj;
|
||||
} else if (x->type == X509_LU_CRL) {
|
||||
if (!X509_CRL_match(obj->data.crl, x->data.crl))
|
||||
return obj;
|
||||
} else
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_OBJECT_retrieve_match);
|
||||
|
||||
/* Try to get issuer certificate from store. Due to limitations
|
||||
* of the API this can only retrieve a single certificate matching
|
||||
* a given subject name. However it will fill the cache with all
|
||||
* matching certificates, so we can examine the cache for all
|
||||
* matches.
|
||||
*
|
||||
* Return values are:
|
||||
* 1 lookup successful.
|
||||
* 0 certificate not found.
|
||||
* -1 some other error.
|
||||
*/
|
||||
int
|
||||
X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x)
|
||||
{
|
||||
X509_NAME *xn;
|
||||
X509_OBJECT *obj, *pobj;
|
||||
X509 *issuer = NULL;
|
||||
int i, idx, ret;
|
||||
|
||||
*out_issuer = NULL;
|
||||
|
||||
xn = X509_get_issuer_name(x);
|
||||
obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn);
|
||||
if (obj == NULL)
|
||||
return 0;
|
||||
|
||||
if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) {
|
||||
X509_OBJECT_free(obj);
|
||||
return 0;
|
||||
}
|
||||
if (!X509_up_ref(issuer)) {
|
||||
X509_OBJECT_free(obj);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If certificate matches all OK */
|
||||
if (ctx->check_issued(ctx, x, issuer)) {
|
||||
if (x509_check_cert_time(ctx, issuer, -1)) {
|
||||
*out_issuer = issuer;
|
||||
X509_OBJECT_free(obj);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
X509_free(issuer);
|
||||
issuer = NULL;
|
||||
X509_OBJECT_free(obj);
|
||||
obj = NULL;
|
||||
|
||||
if (ctx->store == NULL)
|
||||
return 0;
|
||||
|
||||
/* Else find index of first cert accepted by 'check_issued' */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
idx = X509_OBJECT_idx_by_subject(ctx->store->objs, X509_LU_X509, xn);
|
||||
if (idx != -1) /* should be true as we've had at least one match */ {
|
||||
/* Look through all matching certs for suitable issuer */
|
||||
for (i = idx; i < sk_X509_OBJECT_num(ctx->store->objs); i++) {
|
||||
pobj = sk_X509_OBJECT_value(ctx->store->objs, i);
|
||||
/* See if we've run past the matches */
|
||||
if (pobj->type != X509_LU_X509)
|
||||
break;
|
||||
if (X509_NAME_cmp(xn,
|
||||
X509_get_subject_name(pobj->data.x509)))
|
||||
break;
|
||||
if (ctx->check_issued(ctx, x, pobj->data.x509)) {
|
||||
issuer = pobj->data.x509;
|
||||
/*
|
||||
* If times check, exit with match,
|
||||
* otherwise keep looking. Leave last
|
||||
* match in issuer so we return nearest
|
||||
* match if no certificate time is OK.
|
||||
*/
|
||||
if (x509_check_cert_time(ctx, issuer, -1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
if (issuer != NULL) {
|
||||
if (!X509_up_ref(issuer)) {
|
||||
ret = -1;
|
||||
} else {
|
||||
*out_issuer = issuer;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_CTX_get1_issuer);
|
||||
|
||||
STACK_OF(X509_OBJECT) *
|
||||
X509_STORE_get0_objects(X509_STORE *xs)
|
||||
{
|
||||
return xs->objs;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_get0_objects);
|
||||
|
||||
void *
|
||||
X509_STORE_get_ex_data(X509_STORE *xs, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&xs->ex_data, idx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_get_ex_data);
|
||||
|
||||
int
|
||||
X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data)
|
||||
{
|
||||
return CRYPTO_set_ex_data(&xs->ex_data, idx, data);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_ex_data);
|
||||
|
||||
int
|
||||
X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
|
||||
{
|
||||
return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_flags);
|
||||
|
||||
int
|
||||
X509_STORE_set_depth(X509_STORE *ctx, int depth)
|
||||
{
|
||||
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_depth);
|
||||
|
||||
int
|
||||
X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
|
||||
{
|
||||
return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_purpose);
|
||||
|
||||
int
|
||||
X509_STORE_set_trust(X509_STORE *ctx, int trust)
|
||||
{
|
||||
return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_trust);
|
||||
|
||||
int
|
||||
X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return X509_VERIFY_PARAM_set1(ctx->param, param);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set1_param);
|
||||
|
||||
X509_VERIFY_PARAM *
|
||||
X509_STORE_get0_param(X509_STORE *ctx)
|
||||
{
|
||||
return ctx->param;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_get0_param);
|
||||
|
||||
void
|
||||
X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify)
|
||||
{
|
||||
store->verify = verify;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_verify);
|
||||
|
||||
X509_STORE_CTX_verify_fn
|
||||
X509_STORE_get_verify(X509_STORE *store)
|
||||
{
|
||||
return store->verify;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_get_verify);
|
||||
|
||||
void
|
||||
X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb)
|
||||
{
|
||||
store->verify_cb = verify_cb;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_set_verify_cb);
|
||||
|
||||
X509_STORE_CTX_verify_cb
|
||||
X509_STORE_get_verify_cb(X509_STORE *store)
|
||||
{
|
||||
return store->verify_cb;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_STORE_get_verify_cb);
|
||||
561
crypto/x509/x509_ncons.c
Normal file
561
crypto/x509/x509_ncons.c
Normal file
@@ -0,0 +1,561 @@
|
||||
/* $OpenBSD: x509_ncons.c,v 1.9 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
|
||||
static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
void *a, BIO *bp, int ind);
|
||||
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name);
|
||||
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
|
||||
|
||||
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
|
||||
static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
|
||||
static int nc_dn(X509_NAME *sub, X509_NAME *nm);
|
||||
static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
|
||||
static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
|
||||
static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_SUBTREE_new);
|
||||
|
||||
void
|
||||
GENERAL_SUBTREE_free(GENERAL_SUBTREE *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &GENERAL_SUBTREE_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(GENERAL_SUBTREE_free);
|
||||
|
||||
NAME_CONSTRAINTS *
|
||||
NAME_CONSTRAINTS_new(void)
|
||||
{
|
||||
return (NAME_CONSTRAINTS*)ASN1_item_new(&NAME_CONSTRAINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(NAME_CONSTRAINTS_new);
|
||||
|
||||
void
|
||||
NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &NAME_CONSTRAINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(NAME_CONSTRAINTS_free);
|
||||
|
||||
static void *
|
||||
v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE tval, *val;
|
||||
STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
|
||||
NAME_CONSTRAINTS *ncons = NULL;
|
||||
GENERAL_SUBTREE *sub = NULL;
|
||||
|
||||
ncons = NAME_CONSTRAINTS_new();
|
||||
if (!ncons)
|
||||
goto memerr;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
|
||||
ptree = &ncons->permittedSubtrees;
|
||||
tval.name = val->name + 10;
|
||||
} else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
|
||||
ptree = &ncons->excludedSubtrees;
|
||||
tval.name = val->name + 9;
|
||||
} else {
|
||||
X509V3error(X509V3_R_INVALID_SYNTAX);
|
||||
goto err;
|
||||
}
|
||||
tval.value = val->value;
|
||||
sub = GENERAL_SUBTREE_new();
|
||||
if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
|
||||
goto err;
|
||||
if (!*ptree)
|
||||
*ptree = sk_GENERAL_SUBTREE_new_null();
|
||||
if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
|
||||
goto memerr;
|
||||
sub = NULL;
|
||||
}
|
||||
|
||||
return ncons;
|
||||
|
||||
memerr:
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
NAME_CONSTRAINTS_free(ncons);
|
||||
GENERAL_SUBTREE_free(sub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind)
|
||||
{
|
||||
NAME_CONSTRAINTS *ncons = a;
|
||||
|
||||
do_i2r_name_constraints(method, ncons->permittedSubtrees,
|
||||
bp, ind, "Permitted");
|
||||
do_i2r_name_constraints(method, ncons->excludedSubtrees,
|
||||
bp, ind, "Excluded");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name)
|
||||
{
|
||||
GENERAL_SUBTREE *tree;
|
||||
int i;
|
||||
|
||||
if (sk_GENERAL_SUBTREE_num(trees) > 0)
|
||||
BIO_printf(bp, "%*s%s:\n", ind, "", name);
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
|
||||
tree = sk_GENERAL_SUBTREE_value(trees, i);
|
||||
BIO_printf(bp, "%*s", ind + 2, "");
|
||||
if (tree->base->type == GEN_IPADD)
|
||||
print_nc_ipadd(bp, tree->base->d.ip);
|
||||
else
|
||||
GENERAL_NAME_print(bp, tree->base);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
|
||||
{
|
||||
int i, len;
|
||||
unsigned char *p;
|
||||
|
||||
p = ip->data;
|
||||
len = ip->length;
|
||||
BIO_puts(bp, "IP:");
|
||||
if (len == 8) {
|
||||
BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
} else if (len == 32) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
BIO_printf(bp, "%X", p[0] << 8 | p[1]);
|
||||
p += 2;
|
||||
if (i == 7)
|
||||
BIO_puts(bp, "/");
|
||||
else if (i != 15)
|
||||
BIO_puts(bp, ":");
|
||||
}
|
||||
} else
|
||||
BIO_printf(bp, "IP Address:<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;
|
||||
}
|
||||
LCRYPTO_ALIAS(NAME_CONSTRAINTS_check);
|
||||
static int
|
||||
nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
|
||||
{
|
||||
GENERAL_SUBTREE *sub;
|
||||
int i, r, match = 0;
|
||||
|
||||
/* Permitted subtrees: if any subtrees exist of matching the type
|
||||
* at least one subtree must match.
|
||||
*/
|
||||
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
|
||||
sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
/* If we already have a match don't bother trying any more */
|
||||
if (match == 2)
|
||||
continue;
|
||||
if (match == 0)
|
||||
match = 1;
|
||||
r = nc_match_single(gen, sub->base);
|
||||
if (r == X509_V_OK)
|
||||
match = 2;
|
||||
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (match == 1)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
/* Excluded subtrees: must not match any of these */
|
||||
|
||||
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
|
||||
sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
|
||||
r = nc_match_single(gen, sub->base);
|
||||
if (r == X509_V_OK)
|
||||
return X509_V_ERR_EXCLUDED_VIOLATION;
|
||||
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
|
||||
{
|
||||
switch (base->type) {
|
||||
case GEN_DIRNAME:
|
||||
return nc_dn(gen->d.directoryName, base->d.directoryName);
|
||||
|
||||
case GEN_DNS:
|
||||
return nc_dns(gen->d.dNSName, base->d.dNSName);
|
||||
|
||||
case GEN_EMAIL:
|
||||
return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
|
||||
|
||||
case GEN_URI:
|
||||
return nc_uri(gen->d.uniformResourceIdentifier,
|
||||
base->d.uniformResourceIdentifier);
|
||||
|
||||
default:
|
||||
return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
/* directoryName name constraint matching.
|
||||
* The canonical encoding of X509_NAME makes this comparison easy. It is
|
||||
* matched if the subtree is a subset of the name.
|
||||
*/
|
||||
|
||||
static int
|
||||
nc_dn(X509_NAME *nm, X509_NAME *base)
|
||||
{
|
||||
/* Ensure canonical encodings are up to date. */
|
||||
if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
if (base->modified && i2d_X509_NAME(base, NULL) < 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
if (base->canon_enclen > nm->canon_enclen)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
|
||||
{
|
||||
char *baseptr = (char *)base->data;
|
||||
char *dnsptr = (char *)dns->data;
|
||||
|
||||
/* Empty matches everything */
|
||||
if (!*baseptr)
|
||||
return X509_V_OK;
|
||||
/* Otherwise can add zero or more components on the left so
|
||||
* compare RHS and if dns is longer and expect '.' as preceding
|
||||
* character.
|
||||
*/
|
||||
if (dns->length > base->length) {
|
||||
dnsptr += dns->length - base->length;
|
||||
if (baseptr[0] != '.' && dnsptr[-1] != '.')
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
|
||||
if (strcasecmp(baseptr, dnsptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
|
||||
{
|
||||
const char *baseptr = (char *)base->data;
|
||||
const char *emlptr = (char *)eml->data;
|
||||
const char *baseat = strchr(baseptr, '@');
|
||||
const char *emlat = strchr(emlptr, '@');
|
||||
|
||||
if (!emlat)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
/* Special case: initial '.' is RHS match */
|
||||
if (!baseat && (*baseptr == '.')) {
|
||||
if (eml->length > base->length) {
|
||||
emlptr += eml->length - base->length;
|
||||
if (!strcasecmp(baseptr, emlptr))
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
|
||||
/* If we have anything before '@' match local part */
|
||||
|
||||
if (baseat) {
|
||||
if (baseat != baseptr) {
|
||||
if ((baseat - baseptr) != (emlat - emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
/* Case sensitive match of local part */
|
||||
if (strncmp(baseptr, emlptr, emlat - emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
/* Position base after '@' */
|
||||
baseptr = baseat + 1;
|
||||
}
|
||||
emlptr = emlat + 1;
|
||||
/* Just have hostname left to match: case insensitive */
|
||||
if (strcasecmp(baseptr, emlptr))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
|
||||
{
|
||||
const char *baseptr = (char *)base->data;
|
||||
const char *hostptr = (char *)uri->data;
|
||||
const char *p = strchr(hostptr, ':');
|
||||
int hostlen;
|
||||
|
||||
/* Check for foo:// and skip past it */
|
||||
if (!p || (p[1] != '/') || (p[2] != '/'))
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
hostptr = p + 3;
|
||||
|
||||
/* Determine length of hostname part of URI */
|
||||
|
||||
/* Look for a port indicator as end of hostname first */
|
||||
|
||||
p = strchr(hostptr, ':');
|
||||
/* Otherwise look for trailing slash */
|
||||
if (!p)
|
||||
p = strchr(hostptr, '/');
|
||||
|
||||
if (!p)
|
||||
hostlen = strlen(hostptr);
|
||||
else
|
||||
hostlen = p - hostptr;
|
||||
|
||||
if (hostlen == 0)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
|
||||
/* Special case: initial '.' is RHS match */
|
||||
if (*baseptr == '.') {
|
||||
if (hostlen > base->length) {
|
||||
p = hostptr + hostlen - base->length;
|
||||
if (!strncasecmp(p, baseptr, base->length))
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
}
|
||||
|
||||
if ((base->length != (int)hostlen) ||
|
||||
strncasecmp(hostptr, baseptr, hostlen))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
}
|
||||
182
crypto/x509/x509_obj.c
Normal file
182
crypto/x509/x509_obj.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/* $OpenBSD: x509_obj.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "x509_local.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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_oneline);
|
||||
382
crypto/x509/x509_ocsp.c
Normal file
382
crypto/x509/x509_ocsp.c
Normal file
@@ -0,0 +1,382 @@
|
||||
/* $OpenBSD: x509_ocsp.c,v 1.2 2022/01/07 09:45:52 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* 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>
|
||||
|
||||
#include "ocsp_local.h"
|
||||
|
||||
/* OCSP extensions and a couple of CRL entry extensions
|
||||
*/
|
||||
|
||||
static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent);
|
||||
static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent);
|
||||
static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
|
||||
int indent);
|
||||
|
||||
static void *ocsp_nonce_new(void);
|
||||
static int i2d_ocsp_nonce(void *a, unsigned char **pp);
|
||||
static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
|
||||
static void ocsp_nonce_free(void *a);
|
||||
static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
|
||||
BIO *out, int indent);
|
||||
|
||||
static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
|
||||
void *nocheck, BIO *out, int indent);
|
||||
static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
const char *str);
|
||||
static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
|
||||
BIO *bp, int ind);
|
||||
|
||||
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
|
||||
196
crypto/x509/x509_pcons.c
Normal file
196
crypto/x509/x509_pcons.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/* $OpenBSD: x509_pcons.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICY_CONSTRAINTS_new);
|
||||
|
||||
void
|
||||
POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &POLICY_CONSTRAINTS_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICY_CONSTRAINTS_free);
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
|
||||
STACK_OF(CONF_VALUE) *extlist)
|
||||
{
|
||||
POLICY_CONSTRAINTS *pcons = a;
|
||||
STACK_OF(CONF_VALUE) *free_extlist = NULL;
|
||||
|
||||
if (extlist == NULL) {
|
||||
if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value_int("Require Explicit Policy",
|
||||
pcons->requireExplicitPolicy, &extlist))
|
||||
goto err;
|
||||
if (!X509V3_add_value_int("Inhibit Policy Mapping",
|
||||
pcons->inhibitPolicyMapping, &extlist))
|
||||
goto err;
|
||||
|
||||
return extlist;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *values)
|
||||
{
|
||||
POLICY_CONSTRAINTS *pcons = NULL;
|
||||
CONF_VALUE *val;
|
||||
int i;
|
||||
|
||||
if (!(pcons = POLICY_CONSTRAINTS_new())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
|
||||
val = sk_CONF_VALUE_value(values, i);
|
||||
if (!strcmp(val->name, "requireExplicitPolicy")) {
|
||||
if (!X509V3_get_value_int(val,
|
||||
&pcons->requireExplicitPolicy)) goto err;
|
||||
} else if (!strcmp(val->name, "inhibitPolicyMapping")) {
|
||||
if (!X509V3_get_value_int(val,
|
||||
&pcons->inhibitPolicyMapping)) goto err;
|
||||
} else {
|
||||
X509V3error(X509V3_R_INVALID_NAME);
|
||||
X509V3_conf_err(val);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
|
||||
X509V3error(X509V3_R_ILLEGAL_EMPTY_EXTENSION);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return pcons;
|
||||
|
||||
err:
|
||||
POLICY_CONSTRAINTS_free(pcons);
|
||||
return NULL;
|
||||
}
|
||||
158
crypto/x509/x509_pku.c
Normal file
158
crypto/x509/x509_pku.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* $OpenBSD: x509_pku.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PKEY_USAGE_PERIOD);
|
||||
|
||||
int
|
||||
i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKEY_USAGE_PERIOD_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKEY_USAGE_PERIOD);
|
||||
|
||||
PKEY_USAGE_PERIOD *
|
||||
PKEY_USAGE_PERIOD_new(void)
|
||||
{
|
||||
return (PKEY_USAGE_PERIOD *)ASN1_item_new(&PKEY_USAGE_PERIOD_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_new);
|
||||
|
||||
void
|
||||
PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &PKEY_USAGE_PERIOD_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_free);
|
||||
|
||||
static int
|
||||
i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage,
|
||||
BIO *out, int indent)
|
||||
{
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
if (usage->notBefore) {
|
||||
BIO_write(out, "Not Before: ", 12);
|
||||
ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
|
||||
if (usage->notAfter)
|
||||
BIO_write(out, ", ", 2);
|
||||
}
|
||||
if (usage->notAfter) {
|
||||
BIO_write(out, "Not After: ", 11);
|
||||
ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
237
crypto/x509/x509_pmaps.c
Normal file
237
crypto/x509/x509_pmaps.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/* $OpenBSD: x509_pmaps.c,v 1.3 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <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);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICY_MAPPING_new);
|
||||
|
||||
void
|
||||
POLICY_MAPPING_free(POLICY_MAPPING *a)
|
||||
{
|
||||
ASN1_item_free((ASN1_VALUE *)a, &POLICY_MAPPING_it);
|
||||
}
|
||||
LCRYPTO_ALIAS(POLICY_MAPPING_free);
|
||||
|
||||
static STACK_OF(CONF_VALUE) *
|
||||
i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
|
||||
STACK_OF(CONF_VALUE) *extlist)
|
||||
{
|
||||
STACK_OF(CONF_VALUE) *free_extlist = NULL;
|
||||
POLICY_MAPPINGS *pmaps = a;
|
||||
POLICY_MAPPING *pmap;
|
||||
char issuer[80], subject[80];
|
||||
int i;
|
||||
|
||||
if (extlist == NULL) {
|
||||
if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
|
||||
if ((pmap = sk_POLICY_MAPPING_value(pmaps, i)) == NULL)
|
||||
goto err;
|
||||
if (!i2t_ASN1_OBJECT(issuer, sizeof issuer,
|
||||
pmap->issuerDomainPolicy))
|
||||
goto err;
|
||||
if (!i2t_ASN1_OBJECT(subject, sizeof subject,
|
||||
pmap->subjectDomainPolicy))
|
||||
goto err;
|
||||
if (!X509V3_add_value(issuer, subject, &extlist))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return extlist;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval)
|
||||
{
|
||||
POLICY_MAPPINGS *pmaps = NULL;
|
||||
POLICY_MAPPING *pmap = NULL;
|
||||
ASN1_OBJECT *obj1 = NULL, *obj2 = NULL;
|
||||
CONF_VALUE *val;
|
||||
int i, rc;
|
||||
|
||||
if (!(pmaps = sk_POLICY_MAPPING_new_null())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!val->value || !val->name) {
|
||||
rc = X509V3_R_INVALID_OBJECT_IDENTIFIER;
|
||||
goto err;
|
||||
}
|
||||
obj1 = OBJ_txt2obj(val->name, 0);
|
||||
obj2 = OBJ_txt2obj(val->value, 0);
|
||||
if (!obj1 || !obj2) {
|
||||
rc = X509V3_R_INVALID_OBJECT_IDENTIFIER;
|
||||
goto err;
|
||||
}
|
||||
pmap = POLICY_MAPPING_new();
|
||||
if (!pmap) {
|
||||
rc = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
pmap->issuerDomainPolicy = obj1;
|
||||
pmap->subjectDomainPolicy = obj2;
|
||||
obj1 = obj2 = NULL;
|
||||
if (sk_POLICY_MAPPING_push(pmaps, pmap) == 0) {
|
||||
rc = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
pmap = NULL;
|
||||
}
|
||||
return pmaps;
|
||||
|
||||
err:
|
||||
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
|
||||
X509V3error(rc);
|
||||
if (rc == X509V3_R_INVALID_OBJECT_IDENTIFIER)
|
||||
X509V3_conf_err(val);
|
||||
ASN1_OBJECT_free(obj1);
|
||||
ASN1_OBJECT_free(obj2);
|
||||
POLICY_MAPPING_free(pmap);
|
||||
return NULL;
|
||||
}
|
||||
1019
crypto/x509/x509_policy.c
Normal file
1019
crypto/x509/x509_policy.c
Normal file
File diff suppressed because it is too large
Load Diff
231
crypto/x509/x509_prn.c
Normal file
231
crypto/x509/x509_prn.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/* $OpenBSD: x509_prn.c,v 1.6 2023/05/08 05:30:38 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* X509 v3 extension utilities */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
/* Extension printing routines */
|
||||
|
||||
static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
|
||||
int indent, int supported);
|
||||
|
||||
/* Print out a name+value stack */
|
||||
|
||||
void
|
||||
X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
|
||||
{
|
||||
int i;
|
||||
CONF_VALUE *nval;
|
||||
|
||||
if (!val)
|
||||
return;
|
||||
if (!ml || !sk_CONF_VALUE_num(val)) {
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
if (!sk_CONF_VALUE_num(val))
|
||||
BIO_puts(out, "<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");
|
||||
}
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_val_prn);
|
||||
|
||||
/* Main routine: print out a general extension */
|
||||
|
||||
int
|
||||
X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
|
||||
{
|
||||
void *ext_str = NULL;
|
||||
char *value = NULL;
|
||||
const unsigned char *p;
|
||||
const X509V3_EXT_METHOD *method;
|
||||
STACK_OF(CONF_VALUE) *nval = NULL;
|
||||
int ok = 1;
|
||||
|
||||
if (!(method = X509V3_EXT_get(ext)))
|
||||
return unknown_ext_print(out, ext, flag, indent, 0);
|
||||
p = ext->value->data;
|
||||
if (method->it)
|
||||
ext_str = ASN1_item_d2i(NULL, &p, ext->value->length,
|
||||
method->it);
|
||||
else
|
||||
ext_str = method->d2i(NULL, &p, ext->value->length);
|
||||
|
||||
if (!ext_str)
|
||||
return unknown_ext_print(out, ext, flag, indent, 1);
|
||||
|
||||
if (method->i2s) {
|
||||
if (!(value = method->i2s(method, ext_str))) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
BIO_printf(out, "%*s%s", indent, "", value);
|
||||
} else if (method->i2v) {
|
||||
if (!(nval = method->i2v(method, ext_str, NULL))) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
X509V3_EXT_val_prn(out, nval, indent,
|
||||
method->ext_flags & X509V3_EXT_MULTILINE);
|
||||
} else if (method->i2r) {
|
||||
if (!method->i2r(method, ext_str, out, indent))
|
||||
ok = 0;
|
||||
} else
|
||||
ok = 0;
|
||||
|
||||
err:
|
||||
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
|
||||
free(value);
|
||||
if (method->it)
|
||||
ASN1_item_free(ext_str, method->it);
|
||||
else
|
||||
method->ext_free(ext_str);
|
||||
return ok;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_print);
|
||||
|
||||
int
|
||||
X509V3_extensions_print(BIO *bp, const char *title,
|
||||
const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (sk_X509_EXTENSION_num(exts) <= 0)
|
||||
return 1;
|
||||
|
||||
if (title) {
|
||||
BIO_printf(bp, "%*s%s:\n",indent, "", title);
|
||||
indent += 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
|
||||
ASN1_OBJECT *obj;
|
||||
X509_EXTENSION *ex;
|
||||
ex = sk_X509_EXTENSION_value(exts, i);
|
||||
if (indent && BIO_printf(bp, "%*s",indent, "") <= 0)
|
||||
return 0;
|
||||
obj = X509_EXTENSION_get_object(ex);
|
||||
i2a_ASN1_OBJECT(bp, obj);
|
||||
j = X509_EXTENSION_get_critical(ex);
|
||||
if (BIO_printf(bp, ":%s\n", j ? " critical" : "") <= 0)
|
||||
return 0;
|
||||
if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
|
||||
BIO_printf(bp, "%*s", indent + 4, "");
|
||||
ASN1_STRING_print(bp, ex->value);
|
||||
}
|
||||
if (BIO_write(bp, "\n",1) <= 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_extensions_print);
|
||||
|
||||
static int
|
||||
unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
|
||||
int indent, int supported)
|
||||
{
|
||||
switch (flag & X509V3_EXT_UNKNOWN_MASK) {
|
||||
case X509V3_EXT_DEFAULT:
|
||||
return 0;
|
||||
case X509V3_EXT_ERROR_UNKNOWN:
|
||||
if (supported)
|
||||
BIO_printf(out, "%*s<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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509V3_EXT_print_fp);
|
||||
1077
crypto/x509/x509_purp.c
Normal file
1077
crypto/x509/x509_purp.c
Normal file
File diff suppressed because it is too large
Load Diff
117
crypto/x509/x509_r2x.c
Normal file
117
crypto/x509/x509_r2x.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* $OpenBSD: x509_r2x.c,v 1.17 2023/04/25 09:46:36 job Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
X509 *
|
||||
X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
|
||||
{
|
||||
X509 *ret = NULL;
|
||||
X509_CINF *xi = NULL;
|
||||
X509_NAME *xn;
|
||||
EVP_PKEY *pubkey;
|
||||
|
||||
if ((ret = X509_new()) == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* duplicate the request */
|
||||
xi = ret->cert_info;
|
||||
|
||||
if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
|
||||
if (!X509_set_version(ret, 2))
|
||||
goto err;
|
||||
}
|
||||
|
||||
xn = X509_REQ_get_subject_name(r);
|
||||
if (X509_set_subject_name(ret, xn) == 0)
|
||||
goto err;
|
||||
if (X509_set_issuer_name(ret, xn) == 0)
|
||||
goto err;
|
||||
|
||||
if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
|
||||
goto err;
|
||||
if (X509_gmtime_adj(xi->validity->notAfter,
|
||||
(long)60 * 60 * 24 * days) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((pubkey = X509_REQ_get0_pubkey(r)) == NULL)
|
||||
goto err;
|
||||
if (!X509_set_pubkey(ret, pubkey))
|
||||
goto err;
|
||||
|
||||
if (!X509_sign(ret, pkey, EVP_md5()))
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
X509_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_to_X509);
|
||||
356
crypto/x509/x509_req.c
Normal file
356
crypto/x509/x509_req.c
Normal file
@@ -0,0 +1,356 @@
|
||||
/* $OpenBSD: x509_req.c,v 1.33 2023/04/25 09:46:36 job Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "evp_local.h"
|
||||
#include "x509_local.h"
|
||||
|
||||
X509_REQ *
|
||||
X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
{
|
||||
X509_REQ *ret;
|
||||
int i;
|
||||
EVP_PKEY *pktmp;
|
||||
|
||||
ret = X509_REQ_new();
|
||||
if (ret == NULL) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!X509_REQ_set_version(ret, 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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_to_X509_REQ);
|
||||
|
||||
EVP_PKEY *
|
||||
X509_REQ_get_pubkey(X509_REQ *req)
|
||||
{
|
||||
if ((req == NULL) || (req->req_info == NULL))
|
||||
return (NULL);
|
||||
return (X509_PUBKEY_get(req->req_info->pubkey));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_pubkey);
|
||||
|
||||
EVP_PKEY *
|
||||
X509_REQ_get0_pubkey(X509_REQ *req)
|
||||
{
|
||||
if (req == NULL || req->req_info == NULL)
|
||||
return NULL;
|
||||
return X509_PUBKEY_get0(req->req_info->pubkey);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get0_pubkey);
|
||||
|
||||
int
|
||||
X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
|
||||
{
|
||||
EVP_PKEY *xk = NULL;
|
||||
int ok = 0;
|
||||
|
||||
if ((xk = X509_REQ_get0_pubkey(x)) == NULL)
|
||||
return 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return (ok);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_check_private_key);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_extension_nid);
|
||||
|
||||
int *
|
||||
X509_REQ_get_extension_nids(void)
|
||||
{
|
||||
return ext_nids;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_extension_nids);
|
||||
|
||||
void
|
||||
X509_REQ_set_extension_nids(int *nids)
|
||||
{
|
||||
ext_nids = nids;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_set_extension_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 == NULL)
|
||||
return NULL;
|
||||
for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
|
||||
idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
|
||||
if (idx == -1)
|
||||
continue;
|
||||
attr = X509_REQ_get_attr(req, idx);
|
||||
ext = X509_ATTRIBUTE_get0_type(attr, 0);
|
||||
break;
|
||||
}
|
||||
if (ext == NULL)
|
||||
return sk_X509_EXTENSION_new_null();
|
||||
if (ext->type != V_ASN1_SEQUENCE)
|
||||
return NULL;
|
||||
p = ext->value.sequence->data;
|
||||
return d2i_X509_EXTENSIONS(NULL, &p, ext->value.sequence->length);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_extensions);
|
||||
|
||||
/*
|
||||
* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
|
||||
* in case we want to create a non-standard one.
|
||||
*/
|
||||
|
||||
int
|
||||
X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
|
||||
int nid)
|
||||
{
|
||||
unsigned char *ext = NULL;
|
||||
int extlen;
|
||||
int rv;
|
||||
|
||||
extlen = i2d_X509_EXTENSIONS(exts, &ext);
|
||||
if (extlen <= 0)
|
||||
return 0;
|
||||
|
||||
rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen);
|
||||
free(ext);
|
||||
|
||||
return rv;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_add_extensions_nid);
|
||||
|
||||
/* This is the normal usage: use the "official" OID */
|
||||
int
|
||||
X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
|
||||
{
|
||||
return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_add_extensions);
|
||||
|
||||
/* Request attribute functions */
|
||||
|
||||
int
|
||||
X509_REQ_get_attr_count(const X509_REQ *req)
|
||||
{
|
||||
return X509at_get_attr_count(req->req_info->attributes);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_attr_count);
|
||||
|
||||
int
|
||||
X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
|
||||
{
|
||||
return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_attr_by_NID);
|
||||
|
||||
int
|
||||
X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
|
||||
int lastpos)
|
||||
{
|
||||
return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_attr_by_OBJ);
|
||||
|
||||
X509_ATTRIBUTE *
|
||||
X509_REQ_get_attr(const X509_REQ *req, int loc)
|
||||
{
|
||||
return X509at_get_attr(req->req_info->attributes, loc);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_attr);
|
||||
|
||||
X509_ATTRIBUTE *
|
||||
X509_REQ_delete_attr(X509_REQ *req, int loc)
|
||||
{
|
||||
return X509at_delete_attr(req->req_info->attributes, loc);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_delete_attr);
|
||||
|
||||
int
|
||||
X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
|
||||
{
|
||||
if (X509at_add1_attr(&req->req_info->attributes, attr))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_add1_attr);
|
||||
|
||||
int
|
||||
X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type,
|
||||
const unsigned char *bytes, int len)
|
||||
{
|
||||
if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
|
||||
type, bytes, len))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_add1_attr_by_OBJ);
|
||||
|
||||
int
|
||||
X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type,
|
||||
const unsigned char *bytes, int len)
|
||||
{
|
||||
if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
|
||||
type, bytes, len))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_add1_attr_by_NID);
|
||||
|
||||
int
|
||||
X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type,
|
||||
const unsigned char *bytes, int len)
|
||||
{
|
||||
if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
|
||||
type, bytes, len))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_add1_attr_by_txt);
|
||||
|
||||
int
|
||||
i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
|
||||
{
|
||||
req->req_info->enc.modified = 1;
|
||||
return i2d_X509_REQ_INFO(req->req_info, pp);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_re_X509_REQ_tbs);
|
||||
262
crypto/x509/x509_set.c
Normal file
262
crypto/x509/x509_set.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/* $OpenBSD: x509_set.c,v 1.26 2023/06/23 08:00:28 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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
const STACK_OF(X509_EXTENSION) *
|
||||
X509_get0_extensions(const X509 *x)
|
||||
{
|
||||
return x->cert_info->extensions;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_extensions);
|
||||
|
||||
const X509_ALGOR *
|
||||
X509_get0_tbs_sigalg(const X509 *x)
|
||||
{
|
||||
return x->cert_info->signature;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_tbs_sigalg);
|
||||
|
||||
int
|
||||
X509_set_version(X509 *x, long version)
|
||||
{
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
if (x->cert_info->version == NULL) {
|
||||
if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL)
|
||||
return (0);
|
||||
}
|
||||
x->cert_info->enc.modified = 1;
|
||||
return (ASN1_INTEGER_set(x->cert_info->version, version));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_version);
|
||||
|
||||
long
|
||||
X509_get_version(const X509 *x)
|
||||
{
|
||||
return ASN1_INTEGER_get(x->cert_info->version);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_version);
|
||||
|
||||
int
|
||||
X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
|
||||
{
|
||||
ASN1_INTEGER *in;
|
||||
|
||||
if (x == NULL)
|
||||
return 0;
|
||||
in = x->cert_info->serialNumber;
|
||||
if (in != serial) {
|
||||
in = ASN1_INTEGER_dup(serial);
|
||||
if (in != NULL) {
|
||||
x->cert_info->enc.modified = 1;
|
||||
ASN1_INTEGER_free(x->cert_info->serialNumber);
|
||||
x->cert_info->serialNumber = in;
|
||||
}
|
||||
}
|
||||
return in != NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_serialNumber);
|
||||
|
||||
int
|
||||
X509_set_issuer_name(X509 *x, X509_NAME *name)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL)
|
||||
return 0;
|
||||
x->cert_info->enc.modified = 1;
|
||||
return X509_NAME_set(&x->cert_info->issuer, name);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_issuer_name);
|
||||
|
||||
int
|
||||
X509_set_subject_name(X509 *x, X509_NAME *name)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL)
|
||||
return 0;
|
||||
x->cert_info->enc.modified = 1;
|
||||
return X509_NAME_set(&x->cert_info->subject, name);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_subject_name);
|
||||
|
||||
const ASN1_TIME *
|
||||
X509_get0_notBefore(const X509 *x)
|
||||
{
|
||||
return X509_getm_notBefore(x);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_notBefore);
|
||||
|
||||
ASN1_TIME *
|
||||
X509_getm_notBefore(const X509 *x)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL)
|
||||
return NULL;
|
||||
return x->cert_info->validity->notBefore;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_getm_notBefore);
|
||||
|
||||
int
|
||||
X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
|
||||
{
|
||||
ASN1_TIME *in;
|
||||
|
||||
if (x == NULL || x->cert_info->validity == NULL)
|
||||
return 0;
|
||||
in = x->cert_info->validity->notBefore;
|
||||
if (in != tm) {
|
||||
in = ASN1_STRING_dup(tm);
|
||||
if (in != NULL) {
|
||||
x->cert_info->enc.modified = 1;
|
||||
ASN1_TIME_free(x->cert_info->validity->notBefore);
|
||||
x->cert_info->validity->notBefore = in;
|
||||
}
|
||||
}
|
||||
return in != NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_notBefore);
|
||||
|
||||
int
|
||||
X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
|
||||
{
|
||||
return X509_set_notBefore(x, tm);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set1_notBefore);
|
||||
|
||||
const ASN1_TIME *
|
||||
X509_get0_notAfter(const X509 *x)
|
||||
{
|
||||
return X509_getm_notAfter(x);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_notAfter);
|
||||
|
||||
ASN1_TIME *
|
||||
X509_getm_notAfter(const X509 *x)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL)
|
||||
return NULL;
|
||||
return x->cert_info->validity->notAfter;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_getm_notAfter);
|
||||
|
||||
int
|
||||
X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
|
||||
{
|
||||
ASN1_TIME *in;
|
||||
|
||||
if (x == NULL || x->cert_info->validity == NULL)
|
||||
return 0;
|
||||
in = x->cert_info->validity->notAfter;
|
||||
if (in != tm) {
|
||||
in = ASN1_STRING_dup(tm);
|
||||
if (in != NULL) {
|
||||
x->cert_info->enc.modified = 1;
|
||||
ASN1_TIME_free(x->cert_info->validity->notAfter);
|
||||
x->cert_info->validity->notAfter = in;
|
||||
}
|
||||
}
|
||||
return in != NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_notAfter);
|
||||
|
||||
int
|
||||
X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
|
||||
{
|
||||
return X509_set_notAfter(x, tm);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set1_notAfter);
|
||||
|
||||
int
|
||||
X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
|
||||
{
|
||||
if (x == NULL || x->cert_info == NULL)
|
||||
return 0;
|
||||
x->cert_info->enc.modified = 1;
|
||||
return X509_PUBKEY_set(&x->cert_info->key, pkey);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_set_pubkey);
|
||||
|
||||
int
|
||||
X509_get_signature_type(const X509 *x)
|
||||
{
|
||||
return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_signature_type);
|
||||
|
||||
X509_PUBKEY *
|
||||
X509_get_X509_PUBKEY(const X509 *x)
|
||||
{
|
||||
return x->cert_info->key;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get_X509_PUBKEY);
|
||||
|
||||
void
|
||||
X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
|
||||
const ASN1_BIT_STRING **psuid)
|
||||
{
|
||||
if (piuid != NULL)
|
||||
*piuid = x->cert_info->issuerUID;
|
||||
if (psuid != NULL)
|
||||
*psuid = x->cert_info->subjectUID;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_get0_uids);
|
||||
165
crypto/x509/x509_skey.c
Normal file
165
crypto/x509/x509_skey.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/* $OpenBSD: x509_skey.c,v 1.5 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "x509_local.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);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2s_ASN1_OCTET_STRING);
|
||||
|
||||
ASN1_OCTET_STRING *
|
||||
s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
|
||||
const char *str)
|
||||
{
|
||||
ASN1_OCTET_STRING *oct;
|
||||
long length;
|
||||
|
||||
if (!(oct = ASN1_OCTET_STRING_new())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(oct->data = string_to_hex(str, &length))) {
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oct->length = length;
|
||||
|
||||
return oct;
|
||||
}
|
||||
LCRYPTO_ALIAS(s2i_ASN1_OCTET_STRING);
|
||||
|
||||
static ASN1_OCTET_STRING *
|
||||
s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str)
|
||||
{
|
||||
ASN1_OCTET_STRING *oct;
|
||||
ASN1_BIT_STRING *pk;
|
||||
unsigned char pkey_dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int diglen;
|
||||
|
||||
if (strcmp(str, "hash"))
|
||||
return s2i_ASN1_OCTET_STRING(method, ctx, str);
|
||||
|
||||
if (!(oct = ASN1_OCTET_STRING_new())) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx && (ctx->flags == CTX_TEST))
|
||||
return oct;
|
||||
|
||||
if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
|
||||
X509V3error(X509V3_R_NO_PUBLIC_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx->subject_req)
|
||||
pk = ctx->subject_req->req_info->pubkey->public_key;
|
||||
else
|
||||
pk = ctx->subject_cert->cert_info->key->public_key;
|
||||
|
||||
if (!pk) {
|
||||
X509V3error(X509V3_R_NO_PUBLIC_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen,
|
||||
EVP_sha1(), NULL))
|
||||
goto err;
|
||||
|
||||
if (!ASN1_STRING_set(oct, pkey_dig, diglen)) {
|
||||
X509V3error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return oct;
|
||||
|
||||
err:
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
return NULL;
|
||||
}
|
||||
398
crypto/x509/x509_trs.c
Normal file
398
crypto/x509/x509_trs.c
Normal file
@@ -0,0 +1,398 @@
|
||||
/* $OpenBSD: x509_trs.c,v 1.32 2023/07/02 17:12:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "x509_local.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[] = {
|
||||
{
|
||||
.trust = X509_TRUST_COMPAT,
|
||||
.check_trust = trust_compat,
|
||||
.name = "compatible",
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_SSL_CLIENT,
|
||||
.check_trust = trust_1oidany,
|
||||
.name = "SSL Client",
|
||||
.arg1 = NID_client_auth,
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_SSL_SERVER,
|
||||
.check_trust = trust_1oidany,
|
||||
.name = "SSL Server",
|
||||
.arg1 = NID_server_auth,
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_EMAIL,
|
||||
.check_trust = trust_1oidany,
|
||||
.name = "S/MIME email",
|
||||
.arg1 = NID_email_protect,
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_OBJECT_SIGN,
|
||||
.check_trust = trust_1oidany,
|
||||
.name = "Object Signer",
|
||||
.arg1 = NID_code_sign,
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_OCSP_SIGN,
|
||||
.check_trust = trust_1oid,
|
||||
.name = "OCSP responder",
|
||||
.arg1 = NID_OCSP_sign,
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_OCSP_REQUEST,
|
||||
.check_trust = trust_1oid,
|
||||
.name = "OCSP request",
|
||||
.arg1 = NID_ad_OCSP,
|
||||
},
|
||||
{
|
||||
.trust = X509_TRUST_TSA,
|
||||
.check_trust = trust_1oidany,
|
||||
.name = "TSA server",
|
||||
.arg1 = NID_time_stamp,
|
||||
},
|
||||
};
|
||||
|
||||
#define X509_TRUST_COUNT (sizeof(trstandard) / sizeof(trstandard[0]))
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_set_default);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_check_trust);
|
||||
|
||||
int
|
||||
X509_TRUST_get_count(void)
|
||||
{
|
||||
if (!trtable)
|
||||
return X509_TRUST_COUNT;
|
||||
return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_get_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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_get0);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_get_by_id);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_set);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_add);
|
||||
|
||||
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)
|
||||
{
|
||||
sk_X509_TRUST_pop_free(trtable, trtable_free);
|
||||
trtable = NULL;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_cleanup);
|
||||
|
||||
int
|
||||
X509_TRUST_get_flags(const X509_TRUST *xp)
|
||||
{
|
||||
return xp->flags;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_get_flags);
|
||||
|
||||
char *
|
||||
X509_TRUST_get0_name(const X509_TRUST *xp)
|
||||
{
|
||||
return xp->name;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_get0_name);
|
||||
|
||||
int
|
||||
X509_TRUST_get_trust(const X509_TRUST *xp)
|
||||
{
|
||||
return xp->trust;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_TRUST_get_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, nid;
|
||||
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);
|
||||
nid = OBJ_obj2nid(obj);
|
||||
if (nid == id || nid == NID_anyExtendedKeyUsage)
|
||||
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);
|
||||
nid = OBJ_obj2nid(obj);
|
||||
if (nid == id || nid == NID_anyExtendedKeyUsage)
|
||||
return X509_TRUST_TRUSTED;
|
||||
}
|
||||
}
|
||||
return X509_TRUST_UNTRUSTED;
|
||||
}
|
||||
196
crypto/x509/x509_txt.c
Normal file
196
crypto/x509/x509_txt.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/* $OpenBSD: x509_txt.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
const char *
|
||||
X509_verify_cert_error_string(long n)
|
||||
{
|
||||
switch ((int)n) {
|
||||
case X509_V_OK:
|
||||
return "ok";
|
||||
case X509_V_ERR_UNSPECIFIED:
|
||||
return "Unspecified certificate verification error";
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
|
||||
return "unable to get issuer certificate";
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL:
|
||||
return "unable to get certificate CRL";
|
||||
case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
|
||||
return "unable to decrypt certificate's signature";
|
||||
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
|
||||
return "unable to decrypt CRL's signature";
|
||||
case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
|
||||
return "unable to decode issuer public key";
|
||||
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
|
||||
return "certificate signature failure";
|
||||
case X509_V_ERR_CRL_SIGNATURE_FAILURE:
|
||||
return "CRL signature failure";
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
return "certificate is not yet valid";
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
return "certificate has expired";
|
||||
case X509_V_ERR_CRL_NOT_YET_VALID:
|
||||
return "CRL is not yet valid";
|
||||
case X509_V_ERR_CRL_HAS_EXPIRED:
|
||||
return "CRL has expired";
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
|
||||
return "format error in certificate's notBefore field";
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
|
||||
return "format error in certificate's notAfter field";
|
||||
case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
|
||||
return "format error in CRL's lastUpdate field";
|
||||
case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
|
||||
return "format error in CRL's nextUpdate field";
|
||||
case X509_V_ERR_OUT_OF_MEM:
|
||||
return "out of memory";
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
return "self signed certificate";
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
return "self signed certificate in certificate chain";
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
return "unable to get local issuer certificate";
|
||||
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
|
||||
return "unable to verify the first certificate";
|
||||
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
|
||||
return "certificate chain too long";
|
||||
case X509_V_ERR_CERT_REVOKED:
|
||||
return "certificate revoked";
|
||||
case X509_V_ERR_INVALID_CA:
|
||||
return "invalid CA certificate";
|
||||
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
|
||||
return "path length constraint exceeded";
|
||||
case X509_V_ERR_INVALID_PURPOSE:
|
||||
return "unsupported certificate purpose";
|
||||
case X509_V_ERR_CERT_UNTRUSTED:
|
||||
return "certificate not trusted";
|
||||
case X509_V_ERR_CERT_REJECTED:
|
||||
return "certificate rejected";
|
||||
case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
|
||||
return "subject issuer mismatch";
|
||||
case X509_V_ERR_AKID_SKID_MISMATCH:
|
||||
return "authority and subject key identifier mismatch";
|
||||
case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
|
||||
return "authority and issuer serial number mismatch";
|
||||
case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
|
||||
return "key usage does not include certificate signing";
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
|
||||
return "unable to get CRL issuer certificate";
|
||||
case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
|
||||
return "unhandled critical extension";
|
||||
case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
|
||||
return "key usage does not include CRL signing";
|
||||
case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
|
||||
return "unhandled critical CRL extension";
|
||||
case X509_V_ERR_INVALID_NON_CA:
|
||||
return "invalid non-CA certificate (has CA markings)";
|
||||
case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
|
||||
return "proxy path length constraint exceeded";
|
||||
case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
|
||||
return "key usage does not include digital signature";
|
||||
case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
|
||||
return "proxy certificates not allowed, "
|
||||
"please set the appropriate flag";
|
||||
case X509_V_ERR_INVALID_EXTENSION:
|
||||
return "invalid or inconsistent certificate extension";
|
||||
case X509_V_ERR_INVALID_POLICY_EXTENSION:
|
||||
return "invalid or inconsistent certificate policy extension";
|
||||
case X509_V_ERR_NO_EXPLICIT_POLICY:
|
||||
return "no explicit policy";
|
||||
case X509_V_ERR_DIFFERENT_CRL_SCOPE:
|
||||
return "Different CRL scope";
|
||||
case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
|
||||
return "Unsupported extension feature";
|
||||
case X509_V_ERR_UNNESTED_RESOURCE:
|
||||
return "RFC 3779 resource not subset of parent's resources";
|
||||
case X509_V_ERR_PERMITTED_VIOLATION:
|
||||
return "permitted subtree violation";
|
||||
case X509_V_ERR_EXCLUDED_VIOLATION:
|
||||
return "excluded subtree violation";
|
||||
case X509_V_ERR_SUBTREE_MINMAX:
|
||||
return "name constraints minimum and maximum not supported";
|
||||
case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
|
||||
return "unsupported name constraint type";
|
||||
case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
|
||||
return "unsupported or invalid name constraint syntax";
|
||||
case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
|
||||
return "unsupported or invalid name syntax";
|
||||
case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
|
||||
return "CRL path validation error";
|
||||
case X509_V_ERR_APPLICATION_VERIFICATION:
|
||||
return "application verification failure";
|
||||
case X509_V_ERR_HOSTNAME_MISMATCH:
|
||||
return "Hostname mismatch";
|
||||
case X509_V_ERR_EMAIL_MISMATCH:
|
||||
return "Email address mismatch";
|
||||
case X509_V_ERR_IP_ADDRESS_MISMATCH:
|
||||
return "IP address mismatch";
|
||||
case X509_V_ERR_INVALID_CALL:
|
||||
return "Invalid certificate verification context";
|
||||
case X509_V_ERR_STORE_LOOKUP:
|
||||
return "Issuer certificate lookup error";
|
||||
case X509_V_ERR_EE_KEY_TOO_SMALL:
|
||||
return "EE certificate key too weak";
|
||||
case X509_V_ERR_CA_KEY_TOO_SMALL:
|
||||
return "CA certificate key too weak";
|
||||
case X509_V_ERR_CA_MD_TOO_WEAK:
|
||||
return "CA signature digest algorithm too weak";
|
||||
default:
|
||||
return "Unknown certificate verification error";
|
||||
}
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_verify_cert_error_string);
|
||||
1486
crypto/x509/x509_utl.c
Normal file
1486
crypto/x509/x509_utl.c
Normal file
File diff suppressed because it is too large
Load Diff
315
crypto/x509/x509_v3.c
Normal file
315
crypto/x509/x509_v3.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/* $OpenBSD: x509_v3.c,v 1.21 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
|
||||
{
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
return (sk_X509_EXTENSION_num(x));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_get_ext_count);
|
||||
|
||||
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));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_get_ext_by_NID);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_get_ext_by_OBJ);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_get_ext_by_critical);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_get_ext);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_delete_ext);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509v3_add_ext);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_create_by_NID);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_create_by_OBJ);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_set_object);
|
||||
|
||||
int
|
||||
X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
|
||||
{
|
||||
if (ex == NULL)
|
||||
return (0);
|
||||
ex->critical = (crit) ? 0xFF : -1;
|
||||
return (1);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_set_critical);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_set_data);
|
||||
|
||||
ASN1_OBJECT *
|
||||
X509_EXTENSION_get_object(X509_EXTENSION *ex)
|
||||
{
|
||||
if (ex == NULL)
|
||||
return (NULL);
|
||||
return (ex->object);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_get_object);
|
||||
|
||||
ASN1_OCTET_STRING *
|
||||
X509_EXTENSION_get_data(X509_EXTENSION *ex)
|
||||
{
|
||||
if (ex == NULL)
|
||||
return (NULL);
|
||||
return (ex->value);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_get_data);
|
||||
|
||||
int
|
||||
X509_EXTENSION_get_critical(const X509_EXTENSION *ex)
|
||||
{
|
||||
if (ex == NULL)
|
||||
return (0);
|
||||
if (ex->critical > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_EXTENSION_get_critical);
|
||||
1282
crypto/x509/x509_verify.c
Normal file
1282
crypto/x509/x509_verify.c
Normal file
File diff suppressed because it is too large
Load Diff
43
crypto/x509/x509_verify.h
Normal file
43
crypto/x509/x509_verify.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $OpenBSD: x509_verify.h,v 1.2 2021/11/04 23:52:34 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_VERIFY_H
|
||||
#define HEADER_X509_VERIFY_H
|
||||
|
||||
#ifdef LIBRESSL_INTERNAL
|
||||
struct x509_verify_ctx;
|
||||
struct x509_verify_cert_info;
|
||||
typedef struct x509_verify_ctx X509_VERIFY_CTX;
|
||||
|
||||
X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots);
|
||||
void x509_verify_ctx_free(struct x509_verify_ctx *ctx);
|
||||
|
||||
int x509_verify_ctx_set_max_depth(X509_VERIFY_CTX *ctx, size_t max);
|
||||
int x509_verify_ctx_set_max_chains(X509_VERIFY_CTX *ctx, size_t max);
|
||||
int x509_verify_ctx_set_max_signatures(X509_VERIFY_CTX *ctx, size_t max);
|
||||
int x509_verify_ctx_set_purpose(X509_VERIFY_CTX *ctx, int purpose_id);
|
||||
int x509_verify_ctx_set_intermediates(X509_VERIFY_CTX *ctx,
|
||||
STACK_OF(X509) *intermediates);
|
||||
|
||||
const char *x509_verify_ctx_error_string(X509_VERIFY_CTX *ctx);
|
||||
size_t x509_verify_ctx_error_depth(X509_VERIFY_CTX *ctx);
|
||||
|
||||
STACK_OF(X509) *x509_verify_ctx_chain(X509_VERIFY_CTX *ctx, size_t chain);
|
||||
|
||||
size_t x509_verify(X509_VERIFY_CTX *ctx, X509 *leaf, char *name);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2719
crypto/x509/x509_vfy.c
Normal file
2719
crypto/x509/x509_vfy.c
Normal file
File diff suppressed because it is too large
Load Diff
729
crypto/x509/x509_vpm.c
Normal file
729
crypto/x509/x509_vpm.c
Normal file
@@ -0,0 +1,729 @@
|
||||
/* $OpenBSD: x509_vpm.c,v 1.40 2023/05/28 05:25:24 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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 "x509_local.h"
|
||||
|
||||
/* X509_VERIFY_PARAM functions */
|
||||
|
||||
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
|
||||
size_t emaillen);
|
||||
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
|
||||
size_t iplen);
|
||||
|
||||
#define SET_HOST 0
|
||||
#define ADD_HOST 1
|
||||
|
||||
static void
|
||||
str_free(char *s)
|
||||
{
|
||||
free(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 *vpm, 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 && vpm->hosts) {
|
||||
sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
|
||||
vpm->hosts = NULL;
|
||||
}
|
||||
if (name == NULL || namelen == 0)
|
||||
return 1;
|
||||
copy = strndup(name, namelen);
|
||||
if (copy == NULL)
|
||||
return 0;
|
||||
|
||||
if (vpm->hosts == NULL &&
|
||||
(vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
|
||||
free(copy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
|
||||
free(copy);
|
||||
if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
|
||||
sk_OPENSSL_STRING_free(vpm->hosts);
|
||||
vpm->hosts = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
x509_verify_param_zero(X509_VERIFY_PARAM *param)
|
||||
{
|
||||
if (!param)
|
||||
return;
|
||||
|
||||
free(param->name);
|
||||
param->name = NULL;
|
||||
param->purpose = 0;
|
||||
param->trust = 0;
|
||||
/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
|
||||
param->inh_flags = 0;
|
||||
param->flags = 0;
|
||||
param->depth = -1;
|
||||
sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
|
||||
param->policies = NULL;
|
||||
sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
|
||||
param->hosts = NULL;
|
||||
free(param->peername);
|
||||
param->peername = NULL;
|
||||
free(param->email);
|
||||
param->email = NULL;
|
||||
param->emaillen = 0;
|
||||
free(param->ip);
|
||||
param->ip = NULL;
|
||||
param->iplen = 0;
|
||||
param->poisoned = 0;
|
||||
}
|
||||
|
||||
X509_VERIFY_PARAM *
|
||||
X509_VERIFY_PARAM_new(void)
|
||||
{
|
||||
X509_VERIFY_PARAM *param;
|
||||
|
||||
param = calloc(1, sizeof(X509_VERIFY_PARAM));
|
||||
if (param == NULL)
|
||||
return NULL;
|
||||
x509_verify_param_zero(param);
|
||||
return param;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_new);
|
||||
|
||||
void
|
||||
X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
|
||||
{
|
||||
if (param == NULL)
|
||||
return;
|
||||
x509_verify_param_zero(param);
|
||||
free(param);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_free);
|
||||
|
||||
/*
|
||||
* This function determines how parameters are "inherited" from one structure
|
||||
* to another. There are several different ways this can happen.
|
||||
*
|
||||
* 1. If a child structure needs to have its values initialized from a parent
|
||||
* they are simply copied across. For example SSL_CTX copied to SSL.
|
||||
* 2. If the structure should take on values only if they are currently unset.
|
||||
* For example the values in an SSL structure will take appropriate value
|
||||
* for SSL servers or clients but only if the application has not set new
|
||||
* ones.
|
||||
*
|
||||
* The "inh_flags" field determines how this function behaves.
|
||||
*
|
||||
* Normally any values which are set in the default are not copied from the
|
||||
* destination and verify flags are ORed together.
|
||||
*
|
||||
* If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
|
||||
* to the destination. Effectively the values in "to" become default values
|
||||
* which will be used only if nothing new is set in "from".
|
||||
*
|
||||
* If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
|
||||
* they are set or not. Flags is still Ored though.
|
||||
*
|
||||
* If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
|
||||
* of ORed.
|
||||
*
|
||||
* If X509_VP_FLAG_LOCKED is set then no values are copied.
|
||||
*
|
||||
* If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
|
||||
* after the next call.
|
||||
*/
|
||||
|
||||
/* Macro to test if a field should be copied from src to dest */
|
||||
#define test_x509_verify_param_copy(field, def) \
|
||||
(to_overwrite || \
|
||||
((src->field != def) && (to_default || (dest->field == def))))
|
||||
|
||||
/* Macro to test and copy a field if necessary */
|
||||
#define x509_verify_param_copy(field, def) \
|
||||
if (test_x509_verify_param_copy(field, def)) \
|
||||
dest->field = src->field
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src)
|
||||
{
|
||||
unsigned long inh_flags;
|
||||
int to_default, to_overwrite;
|
||||
|
||||
if (!src)
|
||||
return 1;
|
||||
inh_flags = dest->inh_flags | src->inh_flags;
|
||||
|
||||
if (inh_flags & X509_VP_FLAG_ONCE)
|
||||
dest->inh_flags = 0;
|
||||
|
||||
if (inh_flags & X509_VP_FLAG_LOCKED)
|
||||
return 1;
|
||||
|
||||
if (inh_flags & X509_VP_FLAG_DEFAULT)
|
||||
to_default = 1;
|
||||
else
|
||||
to_default = 0;
|
||||
|
||||
if (inh_flags & X509_VP_FLAG_OVERWRITE)
|
||||
to_overwrite = 1;
|
||||
else
|
||||
to_overwrite = 0;
|
||||
|
||||
x509_verify_param_copy(purpose, 0);
|
||||
x509_verify_param_copy(trust, 0);
|
||||
x509_verify_param_copy(depth, -1);
|
||||
|
||||
/* If overwrite or check time not set, copy across */
|
||||
|
||||
if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
|
||||
dest->check_time = src->check_time;
|
||||
dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
|
||||
/* Don't need to copy flag: that is done below */
|
||||
}
|
||||
|
||||
if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
|
||||
dest->flags = 0;
|
||||
|
||||
dest->flags |= src->flags;
|
||||
|
||||
if (test_x509_verify_param_copy(policies, NULL)) {
|
||||
if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
|
||||
return 0;
|
||||
}
|
||||
|
||||
x509_verify_param_copy(hostflags, 0);
|
||||
|
||||
if (test_x509_verify_param_copy(hosts, NULL)) {
|
||||
if (dest->hosts) {
|
||||
sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
|
||||
dest->hosts = NULL;
|
||||
}
|
||||
if (src->hosts) {
|
||||
dest->hosts = sk_deep_copy(src->hosts, strdup, str_free);
|
||||
if (dest->hosts == NULL)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (test_x509_verify_param_copy(email, NULL)) {
|
||||
if (!X509_VERIFY_PARAM_set1_email(dest, src->email,
|
||||
src->emaillen))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_x509_verify_param_copy(ip, NULL)) {
|
||||
if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from)
|
||||
{
|
||||
unsigned long save_flags = to->inh_flags;
|
||||
int ret;
|
||||
|
||||
to->inh_flags |= X509_VP_FLAG_DEFAULT;
|
||||
ret = X509_VERIFY_PARAM_inherit(to, from);
|
||||
to->inh_flags = save_flags;
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1);
|
||||
|
||||
static int
|
||||
x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src,
|
||||
size_t srclen, int nonul)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (src == NULL)
|
||||
return 0;
|
||||
|
||||
if (srclen == 0) {
|
||||
srclen = strlen(src);
|
||||
if (srclen == 0)
|
||||
return 0;
|
||||
if ((tmp = strdup(src)) == NULL)
|
||||
return 0;
|
||||
} else {
|
||||
if (nonul && memchr(src, '\0', srclen))
|
||||
return 0;
|
||||
if ((tmp = malloc(srclen)) == NULL)
|
||||
return 0;
|
||||
memcpy(tmp, src, srclen);
|
||||
}
|
||||
|
||||
if (*pdest)
|
||||
free(*pdest);
|
||||
*pdest = tmp;
|
||||
if (pdestlen)
|
||||
*pdestlen = srclen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
|
||||
{
|
||||
free(param->name);
|
||||
param->name = NULL;
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
param->name = strdup(name);
|
||||
if (param->name)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
|
||||
{
|
||||
param->flags |= flags;
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
|
||||
{
|
||||
param->flags &= ~flags;
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags);
|
||||
|
||||
unsigned long
|
||||
X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return param->flags;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
|
||||
{
|
||||
return X509_PURPOSE_set(¶m->purpose, purpose);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
|
||||
{
|
||||
return X509_TRUST_set(¶m->trust, trust);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust);
|
||||
|
||||
void
|
||||
X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
|
||||
{
|
||||
param->depth = depth;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth);
|
||||
|
||||
void
|
||||
X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
|
||||
{
|
||||
param->security_level = auth_level;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level);
|
||||
|
||||
time_t
|
||||
X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return param->check_time;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time);
|
||||
|
||||
void
|
||||
X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
|
||||
{
|
||||
param->check_time = t;
|
||||
param->flags |= X509_V_FLAG_USE_CHECK_TIME;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
|
||||
{
|
||||
if (!param->policies) {
|
||||
param->policies = sk_ASN1_OBJECT_new_null();
|
||||
if (!param->policies)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_ASN1_OBJECT_push(param->policies, policy))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
|
||||
const char *name, size_t namelen)
|
||||
{
|
||||
if (x509_param_set_hosts_internal(param, SET_HOST, name, namelen))
|
||||
return 1;
|
||||
param->poisoned = 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
|
||||
const char *name, size_t namelen)
|
||||
{
|
||||
if (x509_param_set_hosts_internal(param, ADD_HOST, name, namelen))
|
||||
return 1;
|
||||
param->poisoned = 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host);
|
||||
|
||||
/* Public API in OpenSSL - nothing seems to use this. */
|
||||
unsigned int
|
||||
X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return param->hostflags;
|
||||
}
|
||||
|
||||
void
|
||||
X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags)
|
||||
{
|
||||
param->hostflags = flags;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags);
|
||||
|
||||
char *
|
||||
X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return param->peername;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
|
||||
size_t emaillen)
|
||||
{
|
||||
if (x509_param_set1_internal(¶m->email, ¶m->emaillen,
|
||||
email, emaillen, 1))
|
||||
return 1;
|
||||
param->poisoned = 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
|
||||
size_t iplen)
|
||||
{
|
||||
if (iplen != 4 && iplen != 16)
|
||||
goto err;
|
||||
if (x509_param_set1_internal((char **)¶m->ip, ¶m->iplen,
|
||||
(char *)ip, iplen, 0))
|
||||
return 1;
|
||||
err:
|
||||
param->poisoned = 1;
|
||||
return 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
|
||||
{
|
||||
unsigned char ipout[16];
|
||||
size_t iplen;
|
||||
|
||||
iplen = (size_t)a2i_ipadd(ipout, ipasc);
|
||||
return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc);
|
||||
|
||||
int
|
||||
X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return param->depth;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth);
|
||||
|
||||
const char *
|
||||
X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
|
||||
{
|
||||
return param->name;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_name);
|
||||
|
||||
/*
|
||||
* Default verify parameters: these are used for various applications and can
|
||||
* be overridden by the user specified table.
|
||||
*/
|
||||
|
||||
static const X509_VERIFY_PARAM default_table[] = {
|
||||
{
|
||||
.name = "default",
|
||||
.flags = X509_V_FLAG_TRUSTED_FIRST,
|
||||
.depth = 100,
|
||||
.trust = 0, /* XXX This is not the default trust value */
|
||||
},
|
||||
{
|
||||
.name = "pkcs7",
|
||||
.purpose = X509_PURPOSE_SMIME_SIGN,
|
||||
.trust = X509_TRUST_EMAIL,
|
||||
.depth = -1,
|
||||
},
|
||||
{
|
||||
.name = "smime_sign",
|
||||
.purpose = X509_PURPOSE_SMIME_SIGN,
|
||||
.trust = X509_TRUST_EMAIL,
|
||||
.depth = -1,
|
||||
},
|
||||
{
|
||||
.name = "ssl_client",
|
||||
.purpose = X509_PURPOSE_SSL_CLIENT,
|
||||
.trust = X509_TRUST_SSL_CLIENT,
|
||||
.depth = -1,
|
||||
},
|
||||
{
|
||||
.name = "ssl_server",
|
||||
.purpose = X509_PURPOSE_SSL_SERVER,
|
||||
.trust = X509_TRUST_SSL_SERVER,
|
||||
.depth = -1,
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count);
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup);
|
||||
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup);
|
||||
233
crypto/x509/x509cset.c
Normal file
233
crypto/x509/x509cset.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/* $OpenBSD: x509cset.c,v 1.19 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2001.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "x509_local.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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_up_ref);
|
||||
|
||||
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));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_set_version);
|
||||
|
||||
int
|
||||
X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
|
||||
{
|
||||
if ((x == NULL) || (x->crl == NULL))
|
||||
return (0);
|
||||
return (X509_NAME_set(&x->crl->issuer, name));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_set_issuer_name);
|
||||
|
||||
int
|
||||
X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
|
||||
{
|
||||
ASN1_TIME *in;
|
||||
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
in = x->crl->lastUpdate;
|
||||
if (in != tm) {
|
||||
in = ASN1_STRING_dup(tm);
|
||||
if (in != NULL) {
|
||||
ASN1_TIME_free(x->crl->lastUpdate);
|
||||
x->crl->lastUpdate = in;
|
||||
}
|
||||
}
|
||||
return (in != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_set_lastUpdate);
|
||||
|
||||
int
|
||||
X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
|
||||
{
|
||||
return X509_CRL_set_lastUpdate(x, tm);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_set1_lastUpdate);
|
||||
|
||||
int
|
||||
X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
|
||||
{
|
||||
ASN1_TIME *in;
|
||||
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
in = x->crl->nextUpdate;
|
||||
if (in != tm) {
|
||||
in = ASN1_STRING_dup(tm);
|
||||
if (in != NULL) {
|
||||
ASN1_TIME_free(x->crl->nextUpdate);
|
||||
x->crl->nextUpdate = in;
|
||||
}
|
||||
}
|
||||
return (in != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_set_nextUpdate);
|
||||
|
||||
int
|
||||
X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
|
||||
{
|
||||
return X509_CRL_set_nextUpdate(x, tm);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_set1_nextUpdate);
|
||||
|
||||
int
|
||||
X509_CRL_sort(X509_CRL *c)
|
||||
{
|
||||
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;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_sort);
|
||||
|
||||
const STACK_OF(X509_EXTENSION) *
|
||||
X509_REVOKED_get0_extensions(const X509_REVOKED *x)
|
||||
{
|
||||
return x->extensions;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get0_extensions);
|
||||
|
||||
const ASN1_TIME *
|
||||
X509_REVOKED_get0_revocationDate(const X509_REVOKED *x)
|
||||
{
|
||||
return x->revocationDate;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get0_revocationDate);
|
||||
|
||||
const ASN1_INTEGER *
|
||||
X509_REVOKED_get0_serialNumber(const X509_REVOKED *x)
|
||||
{
|
||||
return x->serialNumber;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_get0_serialNumber);
|
||||
|
||||
int
|
||||
X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
|
||||
{
|
||||
ASN1_TIME *in;
|
||||
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
in = x->revocationDate;
|
||||
if (in != tm) {
|
||||
in = ASN1_STRING_dup(tm);
|
||||
if (in != NULL) {
|
||||
ASN1_TIME_free(x->revocationDate);
|
||||
x->revocationDate = in;
|
||||
}
|
||||
}
|
||||
return (in != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_set_revocationDate);
|
||||
|
||||
int
|
||||
X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
|
||||
{
|
||||
ASN1_INTEGER *in;
|
||||
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
in = x->serialNumber;
|
||||
if (in != serial) {
|
||||
in = ASN1_INTEGER_dup(serial);
|
||||
if (in != NULL) {
|
||||
ASN1_INTEGER_free(x->serialNumber);
|
||||
x->serialNumber = in;
|
||||
}
|
||||
}
|
||||
return (in != NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REVOKED_set_serialNumber);
|
||||
|
||||
int
|
||||
i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp)
|
||||
{
|
||||
crl->crl->enc.modified = 1;
|
||||
return i2d_X509_CRL_INFO(crl->crl, pp);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_re_X509_CRL_tbs);
|
||||
452
crypto/x509/x509name.c
Normal file
452
crypto/x509/x509name.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/* $OpenBSD: x509name.c,v 1.35 2023/05/29 11:54:50 beck Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
|
||||
obj = OBJ_nid2obj(nid);
|
||||
if (obj == NULL)
|
||||
return (-1);
|
||||
return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_get_text_by_NID);
|
||||
|
||||
int
|
||||
X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
|
||||
int len)
|
||||
{
|
||||
unsigned char *text = NULL;
|
||||
ASN1_STRING *data;
|
||||
int i, text_len;
|
||||
int ret = -1;
|
||||
CBS cbs;
|
||||
|
||||
i = X509_NAME_get_index_by_OBJ(name, obj, -1);
|
||||
if (i < 0)
|
||||
goto err;
|
||||
data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
|
||||
/*
|
||||
* Fail if we cannot encode as UTF-8, or if the UTF-8 encoding of the
|
||||
* string contains a 0 byte, because mortal callers seldom handle the
|
||||
* length difference correctly.
|
||||
*/
|
||||
if ((text_len = ASN1_STRING_to_UTF8(&text, data)) < 0)
|
||||
goto err;
|
||||
CBS_init(&cbs, text, text_len);
|
||||
if (CBS_contains_zero_byte(&cbs))
|
||||
goto err;
|
||||
/* We still support the "pass NULL to find out how much" API */
|
||||
if (buf != NULL) {
|
||||
if (len <= 0 || !CBS_write_bytes(&cbs, buf, len - 1, NULL))
|
||||
goto err;
|
||||
/* It must be a C string */
|
||||
buf[text_len] = '\0';
|
||||
}
|
||||
ret = text_len;
|
||||
|
||||
err:
|
||||
free(text);
|
||||
return (ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ);
|
||||
|
||||
int
|
||||
X509_NAME_entry_count(const X509_NAME *name)
|
||||
{
|
||||
if (name == NULL)
|
||||
return (0);
|
||||
return (sk_X509_NAME_ENTRY_num(name->entries));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_entry_count);
|
||||
|
||||
int
|
||||
X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
|
||||
obj = OBJ_nid2obj(nid);
|
||||
if (obj == NULL)
|
||||
return (-2);
|
||||
return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_get_index_by_NID);
|
||||
|
||||
/* NOTE: you should be passing -1, not 0 as lastpos */
|
||||
int
|
||||
X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
|
||||
int lastpos)
|
||||
{
|
||||
int n;
|
||||
X509_NAME_ENTRY *ne;
|
||||
STACK_OF(X509_NAME_ENTRY) *sk;
|
||||
|
||||
if (name == NULL)
|
||||
return (-1);
|
||||
if (lastpos < 0)
|
||||
lastpos = -1;
|
||||
sk = name->entries;
|
||||
n = sk_X509_NAME_ENTRY_num(sk);
|
||||
for (lastpos++; lastpos < n; lastpos++) {
|
||||
ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
|
||||
if (OBJ_cmp(ne->object, obj) == 0)
|
||||
return (lastpos);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_get_index_by_OBJ);
|
||||
|
||||
X509_NAME_ENTRY *
|
||||
X509_NAME_get_entry(const X509_NAME *name, int loc)
|
||||
{
|
||||
if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc ||
|
||||
loc < 0)
|
||||
return (NULL);
|
||||
else
|
||||
return (sk_X509_NAME_ENTRY_value(name->entries, loc));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_get_entry);
|
||||
|
||||
X509_NAME_ENTRY *
|
||||
X509_NAME_delete_entry(X509_NAME *name, int loc)
|
||||
{
|
||||
X509_NAME_ENTRY *ret;
|
||||
int i, n, set_prev, set_next;
|
||||
STACK_OF(X509_NAME_ENTRY) *sk;
|
||||
|
||||
if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc ||
|
||||
loc < 0)
|
||||
return (NULL);
|
||||
sk = name->entries;
|
||||
ret = sk_X509_NAME_ENTRY_delete(sk, loc);
|
||||
n = sk_X509_NAME_ENTRY_num(sk);
|
||||
name->modified = 1;
|
||||
if (loc == n)
|
||||
return (ret);
|
||||
|
||||
/* else we need to fixup the set field */
|
||||
if (loc != 0)
|
||||
set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
|
||||
else
|
||||
set_prev = ret->set - 1;
|
||||
set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
|
||||
|
||||
/* set_prev is the previous set
|
||||
* set is the current set
|
||||
* set_next is the following
|
||||
* prev 1 1 1 1 1 1 1 1
|
||||
* set 1 1 2 2
|
||||
* next 1 1 2 2 2 2 3 2
|
||||
* so basically only if prev and next differ by 2, then
|
||||
* re-number down by 1 */
|
||||
if (set_prev + 1 < set_next)
|
||||
for (i = loc; i < n; i++)
|
||||
sk_X509_NAME_ENTRY_value(sk, i)->set--;
|
||||
return (ret);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_delete_entry);
|
||||
|
||||
int
|
||||
X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
|
||||
const unsigned char *bytes, int len, int loc, int set)
|
||||
{
|
||||
X509_NAME_ENTRY *ne;
|
||||
int ret;
|
||||
|
||||
ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
|
||||
if (!ne)
|
||||
return 0;
|
||||
ret = X509_NAME_add_entry(name, ne, loc, set);
|
||||
X509_NAME_ENTRY_free(ne);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_add_entry_by_OBJ);
|
||||
|
||||
int
|
||||
X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
|
||||
const unsigned char *bytes, int len, int loc, int set)
|
||||
{
|
||||
X509_NAME_ENTRY *ne;
|
||||
int ret;
|
||||
|
||||
ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
|
||||
if (!ne)
|
||||
return 0;
|
||||
ret = X509_NAME_add_entry(name, ne, loc, set);
|
||||
X509_NAME_ENTRY_free(ne);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_add_entry_by_NID);
|
||||
|
||||
int
|
||||
X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
|
||||
const unsigned char *bytes, int len, int loc, int set)
|
||||
{
|
||||
X509_NAME_ENTRY *ne;
|
||||
int ret;
|
||||
|
||||
ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
|
||||
if (!ne)
|
||||
return 0;
|
||||
ret = X509_NAME_add_entry(name, ne, loc, set);
|
||||
X509_NAME_ENTRY_free(ne);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_add_entry_by_txt);
|
||||
|
||||
/* if set is -1, append to previous set, 0 'a new one', and 1,
|
||||
* prepend to the guy we are about to stomp on. */
|
||||
int
|
||||
X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc,
|
||||
int set)
|
||||
{
|
||||
X509_NAME_ENTRY *new_name = NULL;
|
||||
int n, i, inc;
|
||||
STACK_OF(X509_NAME_ENTRY) *sk;
|
||||
|
||||
if (name == NULL)
|
||||
return (0);
|
||||
sk = name->entries;
|
||||
n = sk_X509_NAME_ENTRY_num(sk);
|
||||
if (loc > n)
|
||||
loc = n;
|
||||
else if (loc < 0)
|
||||
loc = n;
|
||||
inc = (set == 0);
|
||||
name->modified = 1;
|
||||
|
||||
if (set == -1) {
|
||||
if (loc == 0) {
|
||||
set = 0;
|
||||
inc = 1;
|
||||
} else
|
||||
set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
|
||||
} else /* if (set >= 0) */ {
|
||||
if (loc >= n) {
|
||||
if (loc != 0)
|
||||
set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
|
||||
else
|
||||
set = 0;
|
||||
} else
|
||||
set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
|
||||
}
|
||||
|
||||
/* OpenSSL has ASN1-generated X509_NAME_ENTRY_dup() without const. */
|
||||
if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL)
|
||||
goto err;
|
||||
new_name->set = set;
|
||||
if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (inc) {
|
||||
n = sk_X509_NAME_ENTRY_num(sk);
|
||||
for (i = loc + 1; i < n; i++)
|
||||
sk_X509_NAME_ENTRY_value(sk, i)->set += 1;
|
||||
}
|
||||
return (1);
|
||||
|
||||
err:
|
||||
if (new_name != NULL)
|
||||
X509_NAME_ENTRY_free(new_name);
|
||||
return (0);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_add_entry);
|
||||
|
||||
X509_NAME_ENTRY *
|
||||
X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
|
||||
const char *field, int type, const unsigned char *bytes, int len)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
X509_NAME_ENTRY *nentry;
|
||||
|
||||
obj = OBJ_txt2obj(field, 0);
|
||||
if (obj == NULL) {
|
||||
X509error(X509_R_INVALID_FIELD_NAME);
|
||||
ERR_asprintf_error_data("name=%s", field);
|
||||
return (NULL);
|
||||
}
|
||||
nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
|
||||
ASN1_OBJECT_free(obj);
|
||||
return nentry;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_txt);
|
||||
|
||||
X509_NAME_ENTRY *
|
||||
X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,
|
||||
const unsigned char *bytes, int len)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
X509_NAME_ENTRY *nentry;
|
||||
|
||||
obj = OBJ_nid2obj(nid);
|
||||
if (obj == NULL) {
|
||||
X509error(X509_R_UNKNOWN_NID);
|
||||
return (NULL);
|
||||
}
|
||||
nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
|
||||
ASN1_OBJECT_free(obj);
|
||||
return nentry;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_NID);
|
||||
|
||||
X509_NAME_ENTRY *
|
||||
X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, const ASN1_OBJECT *obj,
|
||||
int type, const unsigned char *bytes, int len)
|
||||
{
|
||||
X509_NAME_ENTRY *ret;
|
||||
|
||||
if ((ne == NULL) || (*ne == NULL)) {
|
||||
if ((ret = X509_NAME_ENTRY_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret= *ne;
|
||||
|
||||
if (!X509_NAME_ENTRY_set_object(ret, obj))
|
||||
goto err;
|
||||
if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
|
||||
goto err;
|
||||
|
||||
if ((ne != NULL) && (*ne == NULL))
|
||||
*ne = ret;
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
if ((ne == NULL) || (ret != *ne))
|
||||
X509_NAME_ENTRY_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_OBJ);
|
||||
|
||||
int
|
||||
X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
|
||||
{
|
||||
if ((ne == NULL) || (obj == NULL)) {
|
||||
X509error(ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
ASN1_OBJECT_free(ne->object);
|
||||
ne->object = OBJ_dup(obj);
|
||||
return ((ne->object == NULL) ? 0 : 1);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_set_object);
|
||||
|
||||
int
|
||||
X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
|
||||
const unsigned char *bytes, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
|
||||
return (0);
|
||||
if ((type > 0) && (type & MBSTRING_FLAG))
|
||||
return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type,
|
||||
OBJ_obj2nid(ne->object)) ? 1 : 0;
|
||||
if (len < 0)
|
||||
len = strlen((const char *)bytes);
|
||||
i = ASN1_STRING_set(ne->value, bytes, len);
|
||||
if (!i)
|
||||
return (0);
|
||||
if (type != V_ASN1_UNDEF) {
|
||||
if (type == V_ASN1_APP_CHOOSE)
|
||||
ne->value->type = ASN1_PRINTABLE_type(bytes, len);
|
||||
else
|
||||
ne->value->type = type;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_set_data);
|
||||
|
||||
ASN1_OBJECT *
|
||||
X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne)
|
||||
{
|
||||
if (ne == NULL)
|
||||
return (NULL);
|
||||
return (ne->object);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_get_object);
|
||||
|
||||
ASN1_STRING *
|
||||
X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne)
|
||||
{
|
||||
if (ne == NULL)
|
||||
return (NULL);
|
||||
return (ne->value);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_get_data);
|
||||
|
||||
int
|
||||
X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
|
||||
{
|
||||
return (ne->set);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_ENTRY_set);
|
||||
110
crypto/x509/x509rset.c
Normal file
110
crypto/x509/x509rset.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/* $OpenBSD: x509rset.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509_REQ_set_version(X509_REQ *x, long version)
|
||||
{
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
x->req_info->enc.modified = 1;
|
||||
return (ASN1_INTEGER_set(x->req_info->version, version));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_set_version);
|
||||
|
||||
long
|
||||
X509_REQ_get_version(const X509_REQ *x)
|
||||
{
|
||||
return ASN1_INTEGER_get(x->req_info->version);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_version);
|
||||
|
||||
int
|
||||
X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
|
||||
{
|
||||
if ((x == NULL) || (x->req_info == NULL))
|
||||
return (0);
|
||||
x->req_info->enc.modified = 1;
|
||||
return (X509_NAME_set(&x->req_info->subject, name));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_set_subject_name);
|
||||
|
||||
X509_NAME *
|
||||
X509_REQ_get_subject_name(const X509_REQ *x)
|
||||
{
|
||||
return x->req_info->subject;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_get_subject_name);
|
||||
|
||||
int
|
||||
X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
|
||||
{
|
||||
if ((x == NULL) || (x->req_info == NULL))
|
||||
return (0);
|
||||
x->req_info->enc.modified = 1;
|
||||
return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_set_pubkey);
|
||||
136
crypto/x509/x509spki.c
Normal file
136
crypto/x509/x509spki.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/* $OpenBSD: x509spki.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <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));
|
||||
}
|
||||
LCRYPTO_ALIAS(NETSCAPE_SPKI_set_pubkey);
|
||||
|
||||
EVP_PKEY *
|
||||
NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
|
||||
{
|
||||
if ((x == NULL) || (x->spkac == NULL))
|
||||
return (NULL);
|
||||
return (X509_PUBKEY_get(x->spkac->pubkey));
|
||||
}
|
||||
LCRYPTO_ALIAS(NETSCAPE_SPKI_get_pubkey);
|
||||
|
||||
/* Load a Netscape SPKI from a base64 encoded string */
|
||||
|
||||
NETSCAPE_SPKI *
|
||||
NETSCAPE_SPKI_b64_decode(const char *str, int len)
|
||||
{
|
||||
unsigned char *spki_der;
|
||||
const unsigned char *p;
|
||||
int spki_len;
|
||||
NETSCAPE_SPKI *spki;
|
||||
|
||||
if (len <= 0)
|
||||
len = strlen(str);
|
||||
if (!(spki_der = malloc(len + 1))) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
|
||||
if (spki_len < 0) {
|
||||
X509error(X509_R_BASE64_DECODE_ERROR);
|
||||
free(spki_der);
|
||||
return NULL;
|
||||
}
|
||||
p = spki_der;
|
||||
spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
|
||||
free(spki_der);
|
||||
return spki;
|
||||
}
|
||||
LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_decode);
|
||||
|
||||
/* Generate a base64 encoded string from an SPKI */
|
||||
|
||||
char *
|
||||
NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
|
||||
{
|
||||
unsigned char *der_spki, *p;
|
||||
char *b64_str;
|
||||
int der_len;
|
||||
der_len = i2d_NETSCAPE_SPKI(spki, NULL);
|
||||
der_spki = malloc(der_len);
|
||||
b64_str = reallocarray(NULL, der_len, 2);
|
||||
if (!der_spki || !b64_str) {
|
||||
X509error(ERR_R_MALLOC_FAILURE);
|
||||
free(der_spki);
|
||||
free(b64_str);
|
||||
return NULL;
|
||||
}
|
||||
p = der_spki;
|
||||
i2d_NETSCAPE_SPKI(spki, &p);
|
||||
EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
|
||||
free(der_spki);
|
||||
return b64_str;
|
||||
}
|
||||
LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_encode);
|
||||
130
crypto/x509/x509type.c
Normal file
130
crypto/x509/x509type.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/* $OpenBSD: x509type.c,v 1.19 2023/06/15 18:30: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/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "evp_local.h"
|
||||
#include "x509_local.h"
|
||||
|
||||
int
|
||||
X509_certificate_type(const X509 *x, const EVP_PKEY *pkey)
|
||||
{
|
||||
const EVP_PKEY *pk = pkey;
|
||||
int 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_ED25519:
|
||||
ret = EVP_PKT_SIGN;
|
||||
break;
|
||||
case EVP_PKEY_DH:
|
||||
ret = EVP_PK_DH|EVP_PKT_EXCH;
|
||||
break;
|
||||
case NID_id_GostR3410_94:
|
||||
case NID_id_GostR3410_2001:
|
||||
ret = EVP_PKT_EXCH|EVP_PKT_SIGN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_certificate_type);
|
||||
541
crypto/x509/x_all.c
Normal file
541
crypto/x509/x_all.c
Normal file
@@ -0,0 +1,541 @@
|
||||
/* $OpenBSD: x_all.c,v 1.30 2023/02/16 08:38:17 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <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
|
||||
|
||||
#include "x509_local.h"
|
||||
|
||||
X509 *
|
||||
d2i_X509_bio(BIO *bp, X509 **x509)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&X509_it, bp, x509);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_X509_bio);
|
||||
|
||||
int
|
||||
i2d_X509_bio(BIO *bp, X509 *x509)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&X509_it, bp, x509);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_X509_bio);
|
||||
|
||||
X509 *
|
||||
d2i_X509_fp(FILE *fp, X509 **x509)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&X509_it, fp, x509);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_X509_fp);
|
||||
|
||||
int
|
||||
i2d_X509_fp(FILE *fp, X509 *x509)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&X509_it, fp, x509);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_X509_fp);
|
||||
|
||||
X509_CRL *
|
||||
d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&X509_CRL_it, bp, crl);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_X509_CRL_bio);
|
||||
|
||||
int
|
||||
i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&X509_CRL_it, bp, crl);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_X509_CRL_bio);
|
||||
|
||||
X509_CRL *
|
||||
d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&X509_CRL_it, fp, crl);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_X509_CRL_fp);
|
||||
|
||||
int
|
||||
i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&X509_CRL_it, fp, crl);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_X509_CRL_fp);
|
||||
|
||||
X509_REQ *
|
||||
d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&X509_REQ_it, bp, req);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_X509_REQ_bio);
|
||||
|
||||
int
|
||||
i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&X509_REQ_it, bp, req);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_X509_REQ_bio);
|
||||
|
||||
X509_REQ *
|
||||
d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&X509_REQ_it, fp, req);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_X509_REQ_fp);
|
||||
|
||||
int
|
||||
i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&X509_REQ_it, fp, req);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_X509_REQ_fp);
|
||||
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
RSA *
|
||||
d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&RSAPrivateKey_it, bp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_RSAPrivateKey_bio);
|
||||
|
||||
int
|
||||
i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&RSAPrivateKey_it, bp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_RSAPrivateKey_bio);
|
||||
|
||||
RSA *
|
||||
d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&RSAPrivateKey_it, fp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_RSAPrivateKey_fp);
|
||||
|
||||
int
|
||||
i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&RSAPrivateKey_it, fp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_RSAPrivateKey_fp);
|
||||
|
||||
RSA *
|
||||
d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&RSAPublicKey_it, bp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_RSAPublicKey_bio);
|
||||
|
||||
int
|
||||
i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&RSAPublicKey_it, bp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_RSAPublicKey_bio);
|
||||
|
||||
RSA *
|
||||
d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&RSAPublicKey_it, fp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_RSAPublicKey_fp);
|
||||
|
||||
int
|
||||
i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&RSAPublicKey_it, fp, rsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_RSAPublicKey_fp);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
DSA *
|
||||
d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&DSAPrivateKey_it, bp, dsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_DSAPrivateKey_bio);
|
||||
|
||||
int
|
||||
i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&DSAPrivateKey_it, bp, dsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_DSAPrivateKey_bio);
|
||||
|
||||
DSA *
|
||||
d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&DSAPrivateKey_it, fp, dsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_DSAPrivateKey_fp);
|
||||
|
||||
int
|
||||
i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&DSAPrivateKey_it, fp, dsa);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_DSAPrivateKey_fp);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
EC_KEY *
|
||||
d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
|
||||
{
|
||||
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_ECPrivateKey_bio);
|
||||
|
||||
int
|
||||
i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
|
||||
{
|
||||
return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_ECPrivateKey_bio);
|
||||
|
||||
EC_KEY *
|
||||
d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
|
||||
{
|
||||
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_ECPrivateKey_fp);
|
||||
|
||||
int
|
||||
i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
|
||||
{
|
||||
return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_ECPrivateKey_fp);
|
||||
#endif
|
||||
|
||||
X509_SIG *
|
||||
d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&X509_SIG_it, bp, p8);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PKCS8_bio);
|
||||
|
||||
int
|
||||
i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&X509_SIG_it, bp, p8);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKCS8_bio);
|
||||
|
||||
X509_SIG *
|
||||
d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&X509_SIG_it, fp, p8);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PKCS8_fp);
|
||||
|
||||
int
|
||||
i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&X509_SIG_it, fp, p8);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKCS8_fp);
|
||||
|
||||
PKCS8_PRIV_KEY_INFO *
|
||||
d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf)
|
||||
{
|
||||
return ASN1_item_d2i_bio(&PKCS8_PRIV_KEY_INFO_it, bp,
|
||||
p8inf);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_bio);
|
||||
|
||||
int
|
||||
i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
|
||||
{
|
||||
return ASN1_item_i2d_bio(&PKCS8_PRIV_KEY_INFO_it, bp,
|
||||
p8inf);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_bio);
|
||||
|
||||
PKCS8_PRIV_KEY_INFO *
|
||||
d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf)
|
||||
{
|
||||
return ASN1_item_d2i_fp(&PKCS8_PRIV_KEY_INFO_it, fp,
|
||||
p8inf);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_fp);
|
||||
|
||||
int
|
||||
i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
|
||||
{
|
||||
return ASN1_item_i2d_fp(&PKCS8_PRIV_KEY_INFO_it, fp,
|
||||
p8inf);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_fp);
|
||||
|
||||
EVP_PKEY *
|
||||
d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
|
||||
{
|
||||
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey,
|
||||
bp, a);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PrivateKey_bio);
|
||||
|
||||
int
|
||||
i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
|
||||
{
|
||||
return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PrivateKey_bio);
|
||||
|
||||
EVP_PKEY *
|
||||
d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
|
||||
{
|
||||
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey,
|
||||
fp, a);
|
||||
}
|
||||
LCRYPTO_ALIAS(d2i_PrivateKey_fp);
|
||||
|
||||
int
|
||||
i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
|
||||
{
|
||||
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PrivateKey_fp);
|
||||
|
||||
int
|
||||
i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
|
||||
{
|
||||
PKCS8_PRIV_KEY_INFO *p8inf;
|
||||
int ret;
|
||||
|
||||
p8inf = EVP_PKEY2PKCS8(key);
|
||||
if (!p8inf)
|
||||
return 0;
|
||||
ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8inf);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_bio);
|
||||
|
||||
int
|
||||
i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
|
||||
{
|
||||
PKCS8_PRIV_KEY_INFO *p8inf;
|
||||
int ret;
|
||||
p8inf = EVP_PKEY2PKCS8(key);
|
||||
if (!p8inf)
|
||||
return 0;
|
||||
ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8inf);
|
||||
return ret;
|
||||
}
|
||||
LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_fp);
|
||||
|
||||
int
|
||||
X509_verify(X509 *a, EVP_PKEY *r)
|
||||
{
|
||||
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
|
||||
return 0;
|
||||
return (ASN1_item_verify(&X509_CINF_it, a->sig_alg,
|
||||
a->signature, a->cert_info, r));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_verify);
|
||||
|
||||
int
|
||||
X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
|
||||
{
|
||||
return (ASN1_item_verify(&X509_REQ_INFO_it,
|
||||
a->sig_alg, a->signature, a->req_info, r));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_verify);
|
||||
|
||||
int
|
||||
NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
|
||||
{
|
||||
return (ASN1_item_verify(&NETSCAPE_SPKAC_it,
|
||||
a->sig_algor, a->signature, a->spkac, r));
|
||||
}
|
||||
LCRYPTO_ALIAS(NETSCAPE_SPKI_verify);
|
||||
|
||||
int
|
||||
X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
{
|
||||
x->cert_info->enc.modified = 1;
|
||||
return (ASN1_item_sign(&X509_CINF_it,
|
||||
x->cert_info->signature, x->sig_alg, x->signature,
|
||||
x->cert_info, pkey, md));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_sign);
|
||||
|
||||
int
|
||||
X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
|
||||
{
|
||||
x->cert_info->enc.modified = 1;
|
||||
return ASN1_item_sign_ctx(&X509_CINF_it,
|
||||
x->cert_info->signature, x->sig_alg, x->signature,
|
||||
x->cert_info, ctx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_sign_ctx);
|
||||
|
||||
int
|
||||
X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
{
|
||||
return (ASN1_item_sign(&X509_REQ_INFO_it,
|
||||
x->sig_alg, NULL, x->signature, x->req_info, pkey, md));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_sign);
|
||||
|
||||
int
|
||||
X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
|
||||
{
|
||||
return ASN1_item_sign_ctx(&X509_REQ_INFO_it,
|
||||
x->sig_alg, NULL, x->signature, x->req_info, ctx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_sign_ctx);
|
||||
|
||||
int
|
||||
X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
{
|
||||
x->crl->enc.modified = 1;
|
||||
return(ASN1_item_sign(&X509_CRL_INFO_it, x->crl->sig_alg,
|
||||
x->sig_alg, x->signature, x->crl, pkey, md));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_sign);
|
||||
|
||||
int
|
||||
X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
|
||||
{
|
||||
x->crl->enc.modified = 1;
|
||||
return ASN1_item_sign_ctx(&X509_CRL_INFO_it,
|
||||
x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_sign_ctx);
|
||||
|
||||
int
|
||||
NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
{
|
||||
return (ASN1_item_sign(&NETSCAPE_SPKAC_it,
|
||||
x->sig_algor, NULL, x->signature, x->spkac, pkey, md));
|
||||
}
|
||||
LCRYPTO_ALIAS(NETSCAPE_SPKI_sign);
|
||||
|
||||
int
|
||||
X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
ASN1_BIT_STRING *key;
|
||||
key = X509_get0_pubkey_bitstr(data);
|
||||
if (!key)
|
||||
return 0;
|
||||
return EVP_Digest(key->data, key->length, md, len, type, NULL);
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_pubkey_digest);
|
||||
|
||||
int
|
||||
X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
return (ASN1_item_digest(&X509_it, type, (char *)data,
|
||||
md, len));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_digest);
|
||||
|
||||
int
|
||||
X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
return (ASN1_item_digest(&X509_CRL_it, type, (char *)data,
|
||||
md, len));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_CRL_digest);
|
||||
|
||||
int
|
||||
X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
return (ASN1_item_digest(&X509_REQ_it, type, (char *)data,
|
||||
md, len));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_REQ_digest);
|
||||
|
||||
int
|
||||
X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md,
|
||||
unsigned int *len)
|
||||
{
|
||||
return (ASN1_item_digest(&X509_NAME_it, type, (char *)data,
|
||||
md, len));
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_NAME_digest);
|
||||
|
||||
int
|
||||
X509_up_ref(X509 *x)
|
||||
{
|
||||
int i = CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
|
||||
return i > 1 ? 1 : 0;
|
||||
}
|
||||
LCRYPTO_ALIAS(X509_up_ref);
|
||||
Reference in New Issue
Block a user