- In order to not add many X509_XXXX_with_libctx() functions the libctx and propq may be stored in the X509 object via a call to X509_new_with_libctx().
- Loading via PEM_read_bio_X509() or d2i_X509() should pass in a created cert using X509_new_with_libctx().
- Renamed some XXXX_ex() to XXX_with_libctx() for X509 API's.
- Removed the extra parameters in check_purpose..
- X509_digest() has been modified so that it expects a const EVP_MD object() and then internally it does the fetch when it needs to (via ASN1_item_digest_with_libctx()).
- Added API's that set the libctx when they load such as X509_STORE_new_with_libctx() so that the cert chains can be verified.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12153)
BIO_printf(bio_err,
"Everything appears to be ok, creating and signing the certificate\n");
- if ((ret = X509_new()) == NULL)
+ if ((ret = X509_new_with_libctx(app_get0_libctx(), app_get0_propq())) == NULL)
goto end;
#ifdef X509_V3
int app_provider_load(OPENSSL_CTX *libctx, const char *provider_name);
void app_providers_cleanup(void);
+OPENSSL_CTX *app_get0_libctx(void);
+const char *app_get0_propq(void);
+
#endif
return app_libctx;
}
+/* TODO(3.0): Make this an environment variable if required */
+const char *app_get0_propq(void)
+{
+ return NULL;
+}
+
OPENSSL_CTX *app_create_libctx(void)
{
/*
if (bio == NULL)
return 0;
- xis = PEM_X509_INFO_read_bio(bio, NULL,
- (pem_password_cb *)password_callback,
- &cb_data);
+ xis = PEM_X509_INFO_read_bio_with_libctx(bio, NULL,
+ (pem_password_cb *)password_callback,
+ &cb_data,
+ app_get0_libctx(),
+ app_get0_propq());
BIO_free(bio);
{
PW_CB_DATA uidata;
OSSL_STORE_CTX *ctx = NULL;
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
int ret = 0;
/* TODO make use of the engine reference 'eng' when loading pkeys */
unbuffer(stdin);
bio = BIO_new_fp(stdin, 0);
if (bio != NULL)
- ctx = OSSL_STORE_attach(bio, NULL, "file", NULL,
+ ctx = OSSL_STORE_attach(bio, "file", libctx, propq,
get_ui_method(), &uidata, NULL, NULL);
uri = "<stdin>";
} else {
- ctx = OSSL_STORE_open(uri, get_ui_method(), &uidata, NULL, NULL);
+ ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq, get_ui_method(),
+ &uidata, NULL, NULL);
}
if (ctx == NULL) {
BIO_printf(bio_err, "Could not open file or uri %s for loading %s\n",
{
X509_STORE *store = X509_STORE_new();
X509_LOOKUP *lookup;
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
if (store == NULL)
goto end;
if (lookup == NULL)
goto end;
if (CAfile != NULL) {
- if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
+ if (!X509_LOOKUP_load_file_with_libctx(lookup, CAfile,
+ X509_FILETYPE_PEM,
+ libctx, propq)) {
BIO_printf(bio_err, "Error loading file %s\n", CAfile);
goto end;
}
} else {
- X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+ X509_LOOKUP_load_file_with_libctx(lookup, NULL,
+ X509_FILETYPE_DEFAULT,
+ libctx, propq);
}
}
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store());
if (lookup == NULL)
goto end;
- if (!X509_LOOKUP_add_store(lookup, CAstore)) {
+ if (!X509_LOOKUP_add_store_with_libctx(lookup, CAstore, libctx, propq)) {
if (CAstore != NULL)
BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
goto end;
if (x509) {
EVP_PKEY *tmppkey;
X509V3_CTX ext_ctx;
- if ((x509ss = X509_new()) == NULL)
+ if ((x509ss = X509_new_with_libctx(app_get0_libctx(),
+ app_get0_propq())) == NULL)
goto end;
/* Set version to V3 */
static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
int expected, int criterion, OSSL_STORE_SEARCH *search,
int text, int noout, int recursive, int indent, BIO *out,
- const char *prog);
+ const char *prog, OPENSSL_CTX *libctx, const char *propq);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN,
char *alias = NULL;
OSSL_STORE_SEARCH *search = NULL;
const EVP_MD *digest = NULL;
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
ret = process(argv[0], get_ui_method(), &pw_cb_data,
expected, criterion, search,
- text, noout, recursive, 0, out, prog);
+ text, noout, recursive, 0, out, prog, libctx, propq);
end:
OPENSSL_free(fingerprint);
static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
int expected, int criterion, OSSL_STORE_SEARCH *search,
int text, int noout, int recursive, int indent, BIO *out,
- const char *prog)
+ const char *prog, OPENSSL_CTX *libctx, const char *propq)
{
OSSL_STORE_CTX *store_ctx = NULL;
int ret = 1, items = 0;
- if ((store_ctx = OSSL_STORE_open(uri, uimeth, uidata, NULL, NULL))
+ if ((store_ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq,
+ uimeth, uidata, NULL, NULL))
== NULL) {
BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri);
ERR_print_errors(bio_err);
const char *suburi = OSSL_STORE_INFO_get0_NAME(info);
ret += process(suburi, uimeth, uidata,
expected, criterion, search,
- text, noout, recursive, indent + 2, out, prog);
+ text, noout, recursive, indent + 2, out, prog,
+ libctx, propq);
}
break;
case OSSL_STORE_INFO_PARAMS:
{
X509_STORE *cert_ctx = NULL;
X509_LOOKUP *lookup = NULL;
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
cert_ctx = X509_STORE_new();
X509_STORE_set_verify_cb(cert_ctx, verify_cb);
BIO_printf(bio_err, "memory allocation failure\n");
goto err;
}
- if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
+ if (!X509_LOOKUP_load_file_with_libctx(lookup, CAfile,
+ X509_FILETYPE_PEM,
+ libctx, propq)) {
BIO_printf(bio_err, "Error loading file %s\n", CAfile);
goto err;
}
BIO_printf(bio_err, "memory allocation failure\n");
goto err;
}
- if (!X509_LOOKUP_load_store(lookup, CAstore)) {
+ if (!X509_LOOKUP_load_store_with_libctx(lookup, CAstore, libctx, propq)) {
BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
goto err;
}
goto end;
}
- if (!X509_STORE_set_default_paths(ctx)) {
+ if (!X509_STORE_set_default_paths_with_libctx(ctx, app_get0_libctx(),
+ app_get0_propq())) {
ERR_print_errors(bio_err);
goto end;
}
"We need a private key to sign with, use -signkey or -CAkey or -CA <file> with private key\n");
goto end;
}
- if ((x = X509_new()) == NULL)
+ if ((x = X509_new_with_libctx(app_get0_libctx(), app_get0_propq())) == NULL)
goto end;
if (sno == NULL) {
* https://www.openssl.org/source/license.html
*/
+/* We need to use some engine deprecated APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include "internal/cryptlib.h"
+#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
+#include "crypto/x509.h"
#ifndef OPENSSL_NO_DEPRECATED_3_0
#endif
-int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
- unsigned char *md, unsigned int *len)
+int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *md,
+ void *asn, unsigned char *data,
+ unsigned int *len, OPENSSL_CTX *libctx,
+ const char *propq)
{
- int i;
+ int i, ret = 0;
unsigned char *str = NULL;
+ EVP_MD *fetched_md = (EVP_MD *)md;
i = ASN1_item_i2d(asn, &str, it);
- if (!str)
+ if (str == NULL)
return 0;
- if (!EVP_Digest(str, i, md, len, type, NULL)) {
- OPENSSL_free(str);
- return 0;
+ if (EVP_MD_provider(md) == NULL) {
+#if !defined(OPENSSL_NO_ENGINE)
+ if (ENGINE_get_digest_engine(EVP_MD_type(md)) == NULL)
+#endif
+ fetched_md = EVP_MD_fetch(libctx, EVP_MD_name(md), propq);
}
+ if (fetched_md == NULL)
+ goto err;
+
+ ret = EVP_Digest(str, i, data, len, fetched_md, NULL);
+err:
OPENSSL_free(str);
- return 1;
+ if (fetched_md != md)
+ EVP_MD_free(fetched_md);
+ return ret;
}
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *md, void *asn,
+ unsigned char *data, unsigned int *len)
+{
+ return asn1_item_digest_with_libctx(it, md, asn, data, len, NULL, NULL);
+}
+
#include <openssl/err.h>
#include <openssl/ess.h>
#include "crypto/ess.h"
+#include "crypto/x509.h"
DEFINE_STACK_OF(ESS_CERT_ID)
DEFINE_STACK_OF(ESS_CERT_ID_V2)
unsigned char cert_sha1[SHA_DIGEST_LENGTH];
/* Call for side-effect of computing hash and caching extensions */
- if (!X509v3_cache_extensions(cert, NULL, NULL))
+ if (!x509v3_cache_extensions(cert))
return NULL;
if ((cid = ESS_CERT_ID_new()) == NULL)
return -1;
/* Recompute SHA1 hash of certificate if necessary (side effect). */
- if (!X509v3_cache_extensions(cert, NULL, NULL))
+ if (!x509v3_cache_extensions(cert))
return -1;
/* TODO(3.0): fetch sha1 algorithm from providers */
DEFINE_STACK_OF(X509_INFO)
#ifndef OPENSSL_NO_STDIO
-STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
- pem_password_cb *cb, void *u)
+STACK_OF(X509_INFO)
+*PEM_X509_INFO_read_with_libctx(FILE *fp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u,
+ OPENSSL_CTX *libctx, const char *propq)
{
BIO *b;
STACK_OF(X509_INFO) *ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
- PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
+ PEMerr(0, ERR_R_BUF_LIB);
return 0;
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
+ ret = PEM_X509_INFO_read_bio_with_libctx(b, sk, cb, u, libctx, propq);
BIO_free(b);
return ret;
}
+
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u)
+{
+ return PEM_X509_INFO_read_with_libctx(fp, sk, cb, u, NULL, NULL);
+}
#endif
-STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
- pem_password_cb *cb, void *u)
+STACK_OF(X509_INFO)
+*PEM_X509_INFO_read_bio_with_libctx(BIO *bp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u,
+ OPENSSL_CTX *libctx, const char *propq)
{
X509_INFO *xi = NULL;
char *name = NULL, *header = NULL;
if (sk == NULL) {
if ((ret = sk_X509_INFO_new_null()) == NULL) {
- PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE);
+ PEMerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
} else
goto err;
goto start;
}
+ xi->x509 = X509_new_with_libctx(libctx, propq);
+ if (xi->x509 == NULL)
+ goto err;
pp = &(xi->x509);
} else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
d2i = (D2I_OF(void)) d2i_X509_AUX;
goto err;
goto start;
}
+ xi->x509 = X509_new_with_libctx(libctx, propq);
+ if (xi->x509 == NULL)
+ goto err;
pp = &(xi->x509);
} else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
d2i = (D2I_OF(void)) d2i_X509_CRL;
p = data;
if (ptype) {
if (!d2i_PrivateKey(ptype, pp, &p, len)) {
- PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
+ PEMerr(0, ERR_R_ASN1_LIB);
goto err;
}
} else if (d2i(pp, &p, len) == NULL) {
- PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
+ PEMerr(0, ERR_R_ASN1_LIB);
goto err;
}
} else { /* encrypted RSA data */
return ret;
}
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u)
+{
+ return PEM_X509_INFO_read_bio_with_libctx(bp, sk, cb, u, NULL, NULL);
+}
+
/* A TJH addition */
int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc,
const unsigned char *kstr, int klen,
if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL)
return NULL;
- if ((ctx = OSSL_STORE_attach(bp, libctx, "file", propq, ui_method, u,
+ if ((ctx = OSSL_STORE_attach(bp, "file", libctx, propq, ui_method, u,
NULL, NULL)) == NULL)
goto err;
#ifndef OPENSSL_NO_SECURE_HEAP
}
#endif
- while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) {
+ while (!OSSL_STORE_eof(ctx)
+ && (info = OSSL_STORE_load(ctx)) != NULL) {
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
ret = OSSL_STORE_INFO_get1_PKEY(info);
break;
OSSL_STORE_CTX *ctx = NULL;
OSSL_STORE_INFO *info = NULL;
- if ((ctx = OSSL_STORE_attach(bp, NULL, "file", NULL, UI_null(), NULL,
+ if ((ctx = OSSL_STORE_attach(bp, "file", NULL, NULL, UI_null(), NULL,
NULL, NULL)) == NULL)
goto err;
if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL)
return NULL;
- if ((ctx = OSSL_STORE_attach(bp, NULL, "file", NULL, ui_method, u,
+ if ((ctx = OSSL_STORE_attach(bp, "file", NULL, NULL, ui_method, u,
NULL, NULL)) == NULL)
goto err;
*matchcount = 1;
}
- if ((cert = d2i_X509_AUX(NULL, &blob, len)) != NULL
- || (ignore_trusted && (cert = d2i_X509(NULL, &blob, len)) != NULL)) {
+ cert = X509_new_with_libctx(libctx, propq);
+ if (cert == NULL)
+ return NULL;
+
+ if ((d2i_X509_AUX(&cert, &blob, len)) != NULL
+ || (ignore_trusted && (d2i_X509(&cert, &blob, len)) != NULL)) {
*matchcount = 1;
store_info = OSSL_STORE_INFO_new_CERT(cert);
}
/* Expected object type. May be unspecified */
int expected_type;
-
OPENSSL_CTX *libctx;
char *propq;
};
if (ctx == NULL)
return;
+ OPENSSL_free(ctx->propq);
OPENSSL_free(ctx->uri);
if (ctx->type != is_dir) {
if (ctx->_.file.last_handler != NULL) {
ctx->_.file.last_handler = NULL;
}
}
- OPENSSL_free(ctx->propq);
OPENSSL_free(ctx);
}
return 1;
}
-static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
- const char *uri,
- const UI_METHOD *ui_method,
- void *ui_data)
+static OSSL_STORE_LOADER_CTX *file_open_with_libctx
+ (const OSSL_STORE_LOADER *loader, const char *uri,
+ OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data)
{
OSSL_STORE_LOADER_CTX *ctx = NULL;
struct stat st;
} else if (uri[7] == '/') {
p = &uri[7];
} else {
- OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN,
- OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED);
+ OSSL_STOREerr(0, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED);
return NULL;
}
}
* be absolute. So says RFC 8089
*/
if (path_data[i].check_absolute && path_data[i].path[0] != '/') {
- OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN,
- OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE);
+ OSSL_STOREerr(0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE);
ERR_add_error_data(1, path_data[i].path);
return NULL;
}
ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN, ERR_R_MALLOC_FAILURE);
+ OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
ctx->uri = OPENSSL_strdup(uri);
if (ctx->uri == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN, ERR_R_MALLOC_FAILURE);
+ OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
if (ctx->_.dir.last_entry == NULL) {
if (ctx->_.dir.last_errno != 0) {
char errbuf[256];
- OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN, ERR_R_SYS_LIB);
+ OSSL_STOREerr(0, ERR_R_SYS_LIB);
errno = ctx->_.dir.last_errno;
if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
ERR_add_error_data(1, errbuf);
BIO_free_all(ctx->_.file.file);
goto err;
}
+ if (propq != NULL) {
+ ctx->propq = OPENSSL_strdup(propq);
+ if (ctx->propq == NULL) {
+ OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ ctx->libctx = libctx;
return ctx;
err:
return NULL;
}
-static OSSL_STORE_LOADER_CTX *file_attach(const OSSL_STORE_LOADER *loader,
- BIO *bp, OPENSSL_CTX *libctx,
- const char *propq,
- const UI_METHOD *ui_method,
- void *ui_data)
+static OSSL_STORE_LOADER_CTX *file_open
+ (const OSSL_STORE_LOADER *loader, const char *uri,
+ const UI_METHOD *ui_method, void *ui_data)
{
- OSSL_STORE_LOADER_CTX *ctx;
+ return file_open_with_libctx(loader, uri, NULL, NULL, ui_method, ui_data);
+}
- if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL
- || (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_ATTACH, ERR_R_MALLOC_FAILURE);
- OSSL_STORE_LOADER_CTX_free(ctx);
- return NULL;
+static OSSL_STORE_LOADER_CTX *file_attach
+ (const OSSL_STORE_LOADER *loader, BIO *bp,
+ OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data)
+{
+ OSSL_STORE_LOADER_CTX *ctx = NULL;
+
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+ OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
}
+ if (propq != NULL) {
+ ctx->propq = OPENSSL_strdup(propq);
+ if (ctx->propq == NULL) {
+ OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
ctx->libctx = libctx;
ctx->flags |= FILE_FLAG_ATTACHED;
ctx->_.file.file = bp;
if (!file_find_type(ctx)) {
/* Safety measure */
ctx->_.file.file = NULL;
- OSSL_STORE_LOADER_CTX_free(ctx);
- ctx = NULL;
+ goto err;
}
-
return ctx;
+err:
+ OSSL_STORE_LOADER_CTX_free(ctx);
+ return NULL;
}
static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
ctx->flags |= FILE_FLAG_SECMEM;
break;
default:
- OSSL_STOREerr(OSSL_STORE_F_FILE_CTRL,
- ERR_R_PASSED_INVALID_ARGUMENT);
+ OSSL_STOREerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
ret = 0;
break;
}
static int file_eof(OSSL_STORE_LOADER_CTX *ctx);
static int file_error(OSSL_STORE_LOADER_CTX *ctx);
static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
- const UI_METHOD *ui_method, void *ui_data)
+ const UI_METHOD *ui_method,
+ void *ui_data)
{
OSSL_STORE_INFO *result = NULL;
if (!ctx->_.dir.end_reached) {
char errbuf[256];
assert(ctx->_.dir.last_errno != 0);
- OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD, ERR_R_SYS_LIB);
+ OSSL_STOREerr(0, ERR_R_SYS_LIB);
errno = ctx->_.dir.last_errno;
ctx->errcnt++;
if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
if (newname != NULL
&& (result = OSSL_STORE_INFO_new_NAME(newname)) == NULL) {
OPENSSL_free(newname);
- OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD, ERR_R_OSSL_STORE_LIB);
+ OSSL_STOREerr(0, ERR_R_OSSL_STORE_LIB);
return NULL;
}
} while (result == NULL && !file_eof(ctx));
}
if (matchcount > 1) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD,
- OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE);
+ OSSL_STOREerr(0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE);
} else if (matchcount == 1) {
/*
* If there are other errors on the stack, they already show
* what the problem is.
*/
if (ERR_peek_error() == 0) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD,
- OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
+ OSSL_STOREerr(0, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
if (pem_name != NULL)
ERR_add_error_data(3, "PEM type is '", pem_name, "'");
}
file_load,
file_eof,
file_error,
- file_close
+ file_close,
+ file_open_with_libctx,
};
static void store_file_loader_deinit(void)
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-
-#include "e_os.h"
-
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/trace.h>
int loading;
};
-OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method,
- void *ui_data,
- OSSL_STORE_post_process_info_fn post_process,
- void *post_process_data)
+OSSL_STORE_CTX *OSSL_STORE_open_with_libctx(
+ const char *uri, OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data,
+ OSSL_STORE_post_process_info_fn post_process, void *post_process_data)
{
const OSSL_STORE_LOADER *loader = NULL;
OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
OSSL_TRACE1(STORE, "Looking up scheme %s\n", schemes[i]);
if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) {
OSSL_TRACE1(STORE, "Found loader for scheme %s\n", schemes[i]);
- loader_ctx = loader->open(loader, uri, ui_method, ui_data);
+ if (loader->open_with_libctx != NULL)
+ loader_ctx = loader->open_with_libctx(loader, uri, libctx, propq,
+ ui_method, ui_data);
+ else
+ loader_ctx = loader->open(loader, uri, ui_method, ui_data);
OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx);
}
}
goto err;
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE);
+ OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
return NULL;
}
+OSSL_STORE_CTX *OSSL_STORE_open(const char *uri,
+ const UI_METHOD *ui_method, void *ui_data,
+ OSSL_STORE_post_process_info_fn post_process,
+ void *post_process_data)
+{
+ return OSSL_STORE_open_with_libctx(uri, NULL, NULL, ui_method, ui_data,
+ post_process, post_process_data);
+}
+
int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...)
{
va_list args;
return NULL;
}
-OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, OPENSSL_CTX *libctx,
- const char *scheme, const char *propq,
+OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme,
+ OPENSSL_CTX *libctx, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data)
OSSL_STORE_eof_fn eof;
OSSL_STORE_error_fn error;
OSSL_STORE_close_fn close;
+ OSSL_STORE_open_with_libctx_fn open_with_libctx;
};
DEFINE_LHASH_OF(OSSL_STORE_LOADER);
template.load = NULL;
template.eof = NULL;
template.close = NULL;
+ template.open_with_libctx = NULL;
if (!ossl_store_init_once())
return NULL;
} BY_DIR;
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
- char **ret);
+ char **retp);
+
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, X509_LOOKUP_TYPE type,
const X509_NAME *name, X509_OBJECT *ret);
+static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl,
+ X509_LOOKUP_TYPE type,
+ const X509_NAME *name,
+ X509_OBJECT *ret,
+ OPENSSL_CTX *libctx,
+ const char *propq);
static X509_LOOKUP_METHOD x509_dir_lookup = {
"Load certs from files in a directory",
- new_dir, /* new_item */
- free_dir, /* free */
- NULL, /* init */
- NULL, /* shutdown */
- dir_ctrl, /* ctrl */
- get_cert_by_subject, /* get_by_subject */
- NULL, /* get_by_issuer_serial */
- NULL, /* get_by_fingerprint */
- NULL, /* get_by_alias */
+ new_dir, /* new_item */
+ free_dir, /* free */
+ NULL, /* init */
+ NULL, /* shutdown */
+ dir_ctrl, /* ctrl */
+ get_cert_by_subject, /* get_by_subject */
+ NULL, /* get_by_issuer_serial */
+ NULL, /* get_by_fingerprint */
+ NULL, /* get_by_alias */
+ get_cert_by_subject_with_libctx, /* get_by_subject_with_libctx */
+ NULL, /* ctrl_with_libctx */
};
X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
return 1;
}
-static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
- const X509_NAME *name, X509_OBJECT *ret)
+static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl,
+ X509_LOOKUP_TYPE type,
+ const X509_NAME *name,
+ X509_OBJECT *ret,
+ OPENSSL_CTX *libctx,
+ const char *propq)
{
BY_DIR *ctx;
union {
stmp.data.crl = &data.crl;
postfix = "r";
} else {
- X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE);
+ X509err(0, X509_R_WRONG_LOOKUP_TYPE);
goto finish;
}
if ((b = BUF_MEM_new()) == NULL) {
- X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB);
+ X509err(0, ERR_R_BUF_LIB);
goto finish;
}
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
if (!BUF_MEM_grow(b, j)) {
- X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto finish;
}
if (type == X509_LU_CRL && ent->hashes) {
#endif
/* found one. */
if (type == X509_LU_X509) {
- if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0)
+ if ((X509_load_cert_file_with_libctx(xl, b->data, ent->dir_type,
+ libctx, propq)) == 0)
break;
} else if (type == X509_LU_CRL) {
if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0)
hent = OPENSSL_malloc(sizeof(*hent));
if (hent == NULL) {
CRYPTO_THREAD_unlock(ctx->lock);
- X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
ok = 0;
goto finish;
}
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
CRYPTO_THREAD_unlock(ctx->lock);
OPENSSL_free(hent);
- X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
ok = 0;
goto finish;
}
BUF_MEM_free(b);
return ok;
}
+
+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret)
+{
+ return get_cert_by_subject_with_libctx(xl, type, name, ret, NULL, NULL);
+}
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
+static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd,
+ const char *argc, long argl, char **ret,
+ OPENSSL_CTX *libctx, const char *propq);
+
+
static X509_LOOKUP_METHOD x509_file_lookup = {
"Load file into cache",
NULL, /* new_item */
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
+ NULL, /* get_by_subject_with_libctx */
+ by_file_ctrl_with_libctx, /* ctrl_with_libctx */
};
X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
return &x509_file_lookup;
}
-static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
- long argl, char **ret)
+static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd,
+ const char *argp, long argl, char **ret,
+ OPENSSL_CTX *libctx, const char *propq)
{
int ok = 0;
const char *file;
if (argl == X509_FILETYPE_DEFAULT) {
file = ossl_safe_getenv(X509_get_default_cert_file_env());
if (file)
- ok = (X509_load_cert_crl_file(ctx, file,
- X509_FILETYPE_PEM) != 0);
+ ok = (X509_load_cert_crl_file_with_libctx(ctx, file,
+ X509_FILETYPE_PEM,
+ libctx, propq) != 0);
else
- ok = (X509_load_cert_crl_file
- (ctx, X509_get_default_cert_file(),
- X509_FILETYPE_PEM) != 0);
+ ok = (X509_load_cert_crl_file_with_libctx(
+ ctx, X509_get_default_cert_file(),
+ X509_FILETYPE_PEM, libctx, propq) != 0);
if (!ok) {
- X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS);
+ X509err(0, X509_R_LOADING_DEFAULTS);
}
} else {
if (argl == X509_FILETYPE_PEM)
- ok = (X509_load_cert_crl_file(ctx, argp,
- X509_FILETYPE_PEM) != 0);
+ ok = (X509_load_cert_crl_file_with_libctx(ctx, argp,
+ X509_FILETYPE_PEM,
+ libctx, propq) != 0);
else
- ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0);
+ ok = (X509_load_cert_file_with_libctx(ctx, argp, (int)argl,
+ libctx, propq) != 0);
}
break;
}
return ok;
}
-int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd,
+ const char *argp, long argl, char **ret)
+{
+ return by_file_ctrl_with_libctx(ctx, cmd, argp, argl, ret, NULL, NULL);
+}
+
+int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type,
+ OPENSSL_CTX *libctx, const char *propq)
{
int ret = 0;
BIO *in = NULL;
in = BIO_new(BIO_s_file());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
- X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB);
+ X509err(0, ERR_R_SYS_LIB);
+ goto err;
+ }
+
+ if (type != X509_FILETYPE_PEM && type != X509_FILETYPE_ASN1) {
+ X509err(0, X509_R_BAD_X509_FILETYPE);
+ goto err;
+ }
+ x = X509_new_with_libctx(libctx, propq);
+ if (x == NULL) {
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
if (type == X509_FILETYPE_PEM) {
for (;;) {
- x = PEM_read_bio_X509_AUX(in, NULL, NULL, "");
- if (x == NULL) {
+ if (PEM_read_bio_X509_AUX(in, &x, NULL, "") == NULL) {
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
PEM_R_NO_START_LINE) && (count > 0)) {
ERR_clear_error();
break;
} else {
- X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB);
+ X509err(0, ERR_R_PEM_LIB);
goto err;
}
}
}
ret = count;
} else if (type == X509_FILETYPE_ASN1) {
- x = d2i_X509_bio(in, NULL);
- if (x == NULL) {
- X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB);
+ if (d2i_X509_bio(in, &x) == NULL) {
+ X509err(0, ERR_R_ASN1_LIB);
goto err;
}
i = X509_STORE_add_cert(ctx->store_ctx, x);
if (!i)
goto err;
ret = i;
- } else {
- X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE);
- goto err;
}
if (ret == 0)
- X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_NO_CERTIFICATE_FOUND);
+ X509err(0, X509_R_NO_CERTIFICATE_FOUND);
err:
X509_free(x);
BIO_free(in);
return ret;
}
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
+{
+ return X509_load_cert_file_with_libctx(ctx, file, type, NULL, NULL);
+}
+
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
int ret = 0;
return ret;
}
-int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
+int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file,
+ int type, OPENSSL_CTX *libctx,
+ const char *propq)
{
STACK_OF(X509_INFO) *inf;
X509_INFO *itmp;
int i, count = 0;
if (type != X509_FILETYPE_PEM)
- return X509_load_cert_file(ctx, file, type);
+ return X509_load_cert_file_with_libctx(ctx, file, type, libctx, propq);
in = BIO_new_file(file, "r");
if (!in) {
- X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB);
+ X509err(0, ERR_R_SYS_LIB);
return 0;
}
- inf = PEM_X509_INFO_read_bio(in, NULL, NULL, "");
+ inf = PEM_X509_INFO_read_bio_with_libctx(in, NULL, NULL, "", libctx, propq);
BIO_free(in);
if (!inf) {
- X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
+ X509err(0, ERR_R_PEM_LIB);
return 0;
}
for (i = 0; i < sk_X509_INFO_num(inf); i++) {
}
}
if (count == 0)
- X509err(X509_F_X509_LOAD_CERT_CRL_FILE,
- X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
+ X509err(0, X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
err:
sk_X509_INFO_pop_free(inf, X509_INFO_free);
return count;
}
+
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
+{
+ return X509_load_cert_crl_file_with_libctx(ctx, file, type, NULL, NULL);
+}
+
/* Generic object loader, given expected type and criterion */
static int cache_objects(X509_LOOKUP *lctx, const char *uri,
const OSSL_STORE_SEARCH *criterion,
- int depth)
+ int depth, OPENSSL_CTX *libctx, const char *propq)
{
int ok = 0;
OSSL_STORE_CTX *ctx = NULL;
X509_STORE *xstore = X509_LOOKUP_get_store(lctx);
- if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL)
+ if ((ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq,
+ NULL, NULL, NULL, NULL)) == NULL)
return 0;
/*
*/
if (depth > 0)
ok = cache_objects(lctx, OSSL_STORE_INFO_get0_NAME(info),
- criterion, depth - 1);
+ criterion, depth - 1, libctx, propq);
} else {
/*
* We know that X509_STORE_add_{cert|crl} increments the object's
sk_OPENSSL_STRING_pop_free(uris, free_uri);
}
-static int by_store_ctrl(X509_LOOKUP *ctx, int cmd,
- const char *argp, long argl,
- char **retp)
+static int by_store_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd,
+ const char *argp, long argl,
+ char **retp,
+ OPENSSL_CTX *libctx, const char *propq)
{
switch (cmd) {
case X509_L_ADD_STORE:
}
case X509_L_LOAD_STORE:
/* This is a shortcut for quick loading of specific containers */
- return cache_objects(ctx, argp, NULL, 0);
+ return cache_objects(ctx, argp, NULL, 0, libctx, propq);
}
return 0;
}
+static int by_store_ctrl(X509_LOOKUP *ctx, int cmd,
+ const char *argp, long argl, char **retp)
+{
+ return by_store_ctrl_with_libctx(ctx, cmd, argp, argl, retp, NULL, NULL);
+}
+
static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
- const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret)
+ const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret,
+ OPENSSL_CTX *libctx, const char *propq)
{
STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx);
int i;
for (i = 0; i < sk_OPENSSL_STRING_num(uris); i++) {
ok = cache_objects(ctx, sk_OPENSSL_STRING_value(uris, i), criterion,
- 1 /* depth */);
+ 1 /* depth */, libctx, propq);
if (ok)
break;
return ok;
}
-static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
- const X509_NAME *name, X509_OBJECT *ret)
+static int by_store_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret,
+ OPENSSL_CTX *libctx, const char *propq)
{
OSSL_STORE_SEARCH *criterion =
OSSL_STORE_SEARCH_by_name((X509_NAME *)name); /* won't modify it */
- int ok = by_store(ctx, type, criterion, ret);
+ int ok = by_store(ctx, type, criterion, ret, libctx, propq);
STACK_OF(X509_OBJECT) *store_objects =
X509_STORE_get0_objects(X509_LOOKUP_get_store(ctx));
X509_OBJECT *tmp = NULL;
return ok;
}
+static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret)
+{
+ return by_store_subject_with_libctx(ctx, type, name, ret, NULL, NULL);
+}
+
/*
* We lack the implementations for get_by_issuer_serial, get_by_fingerprint
* and get_by_alias. There's simply not enough support in the X509_LOOKUP
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
+ by_store_subject_with_libctx,
+ by_store_ctrl_with_libctx
};
X509_LOOKUP_METHOD *X509_LOOKUP_store(void)
int idx;
const X509_PURPOSE *pt;
- if (!X509v3_cache_extensions(x, NULL, NULL))
+ if (!x509v3_cache_extensions(x))
return -1;
/* Return if side-effect only call */
* e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields.
* Set EXFLAG_INVALID and return 0 in case the certificate is invalid.
*/
-int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq)
+int x509v3_cache_extensions(X509 *x)
{
BASIC_CONSTRAINTS *bs;
PROXY_CERT_INFO_EXTENSION *pci;
EXTENDED_KEY_USAGE *extusage;
X509_EXTENSION *ex;
int i;
- EVP_MD *sha1;
#ifdef tsan_ld_acq
/* fast lock-free check, see end of the function for details. */
return (x->ex_flags & EXFLAG_INVALID) == 0;
}
- /* Cache the SHA1 digest of the cert */
- sha1 = EVP_MD_fetch(libctx, "SHA1", propq);
- if (sha1 != NULL) {
- if (!X509_digest(x, sha1, x->sha1_hash, NULL))
+ if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL))
x->ex_flags |= EXFLAG_INVALID;
- EVP_MD_free(sha1);
- }
/* V1 should mean no extensions ... */
if (X509_get_version(x) == 0)
int X509_check_ca(X509 *x)
{
/* Note 0 normally means "not a CA" - but in this case means error. */
- if (!X509v3_cache_extensions(x, NULL, NULL))
+ if (!x509v3_cache_extensions(x))
return 0;
return check_ca(x);
* Returns 0 for OK, or positive for reason for mismatch
* where reason codes match those for X509_verify_cert().
*/
-int x509_check_issued_int(X509 *issuer, X509 *subject,
- OPENSSL_CTX *libctx, const char *propq)
+int X509_check_issued(X509 *issuer, X509 *subject)
{
int ret;
- if ((ret = x509_likely_issued(issuer, subject, libctx, propq)) != X509_V_OK)
+ if ((ret = x509_likely_issued(issuer, subject)) != X509_V_OK)
return ret;
return x509_signing_allowed(issuer, subject);
}
/* do the checks 1., 2., and 3. as described above for X509_check_issued() */
-int x509_likely_issued(X509 *issuer, X509 *subject,
- OPENSSL_CTX *libctx, const char *propq)
+int x509_likely_issued(X509 *issuer, X509 *subject)
{
int ret;
return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
/* set issuer->skid and subject->akid */
- if (!X509v3_cache_extensions(issuer, libctx, propq)
- || !X509v3_cache_extensions(subject, libctx, propq))
+ if (!x509v3_cache_extensions(issuer)
+ || !x509v3_cache_extensions(subject))
return X509_V_ERR_UNSPECIFIED;
ret = X509_check_akid(issuer, subject->akid);
return X509_V_OK;
}
-int X509_check_issued(X509 *issuer, X509 *subject)
-{
- return x509_check_issued_int(issuer, subject, NULL, NULL);
-}
-
int X509_check_akid(const X509 *issuer, const AUTHORITY_KEYID *akid)
{
if (akid == NULL)
#include <openssl/crypto.h>
#include <openssl/x509.h>
-int X509_STORE_set_default_paths(X509_STORE *ctx)
+int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx,
+ OPENSSL_CTX *libctx,
+ const char *propq)
{
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);
+ X509_LOOKUP_load_file_with_libctx(lookup, NULL, X509_FILETYPE_DEFAULT,
+ libctx, propq);
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
if (lookup == NULL)
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store());
if (lookup == NULL)
return 0;
- X509_LOOKUP_add_store(lookup, NULL);
+ X509_LOOKUP_add_store_with_libctx(lookup, NULL, libctx, propq);
/* clear any errors */
ERR_clear_error();
return 1;
}
+int X509_STORE_set_default_paths(X509_STORE *ctx)
+{
+ return X509_STORE_set_default_paths_with_libctx(ctx, NULL, NULL);
+}
-int X509_STORE_load_file(X509_STORE *ctx, const char *file)
+int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file,
+ OPENSSL_CTX *libctx, const char *propq)
{
X509_LOOKUP *lookup;
if (file == NULL
|| (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file())) == NULL
- || X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) == 0)
+ || X509_LOOKUP_load_file_with_libctx(lookup, file, X509_FILETYPE_PEM,
+ libctx, propq) == 0)
return 0;
return 1;
}
+int X509_STORE_load_file(X509_STORE *ctx, const char *file)
+{
+ return X509_STORE_load_file_with_libctx(ctx, file, NULL, NULL);
+}
+
int X509_STORE_load_path(X509_STORE *ctx, const char *path)
{
X509_LOOKUP *lookup;
return 1;
}
-int X509_STORE_load_store(X509_STORE *ctx, const char *uri)
+int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *uri,
+ OPENSSL_CTX *libctx, const char *propq)
{
X509_LOOKUP *lookup;
if (uri == NULL
|| (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store())) == NULL
- || X509_LOOKUP_add_store(lookup, uri) == 0)
+ || X509_LOOKUP_add_store_with_libctx(lookup, uri, libctx, propq) == 0)
return 0;
return 1;
}
-int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
- const char *path)
+int X509_STORE_load_store(X509_STORE *ctx, const char *uri)
+{
+ return X509_STORE_load_store_with_libctx(ctx, uri, NULL, NULL);
+}
+
+int X509_STORE_load_locations_with_libctx(X509_STORE *ctx, const char *file,
+ const char *path,
+ OPENSSL_CTX *libctx, const char *propq)
{
if (file == NULL && path == NULL)
return 0;
- if (file != NULL && !X509_STORE_load_file(ctx, file))
+ if (file != NULL && !X509_STORE_load_file_with_libctx(ctx, file,
+ libctx, propq))
return 0;
if (path != NULL && !X509_STORE_load_path(ctx, path))
return 0;
return 1;
}
+
+int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
+ const char *path)
+{
+ return X509_STORE_load_locations_with_libctx(ctx, file, path, NULL, NULL);
+}
X509_OBJECT *ret);
int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
const char *str, int len, X509_OBJECT *ret);
+ int (*get_by_subject_with_libctx) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret,
+ OPENSSL_CTX *libctx, const char *propq);
+ int (*ctrl_with_libctx) (X509_LOOKUP *ctx, int cmd,
+ const char *argc, long argl, char **ret,
+ OPENSSL_CTX *libctx, const char *propq);
};
/* This is the functions plus an instance of the local variables. */
void x509_set_signature_info(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
const ASN1_STRING *sig);
-int x509_likely_issued(X509 *issuer, X509 *subject,
- OPENSSL_CTX *libctx, const char *propq);
+int x509_likely_issued(X509 *issuer, X509 *subject);
int x509_signing_allowed(const X509 *issuer, const X509 *subject);
return 1;
}
-int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
- char **ret)
+int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc,
+ long argl, char **ret,
+ OPENSSL_CTX *libctx, const char *propq)
{
if (ctx->method == NULL)
return -1;
+ if (ctx->method->ctrl_with_libctx != NULL)
+ return ctx->method->ctrl_with_libctx(ctx, cmd, argc, argl, ret,
+ libctx, propq);
if (ctx->method->ctrl != NULL)
return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
+ return 1;
+}
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+ char **ret)
+{
+ return X509_LOOKUP_ctrl_with_libctx(ctx, cmd, argc, argl, ret, NULL, NULL);
+}
+
+int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret,
+ OPENSSL_CTX *libctx, const char *propq)
+{
+ if (ctx->skip
+ || ctx->method == NULL
+ || (ctx->method->get_by_subject == NULL
+ && ctx->method->get_by_subject_with_libctx == NULL))
+ return 0;
+ if (ctx->method->get_by_subject_with_libctx != NULL)
+ return ctx->method->get_by_subject_with_libctx(ctx, type, name, ret,
+ libctx, propq);
else
- return 1;
+ return ctx->method->get_by_subject(ctx, type, name, ret);
}
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
const X509_NAME *name, X509_OBJECT *ret)
{
- if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
- return 0;
- if (ctx->skip)
- return 0;
- return ctx->method->get_by_subject(ctx, type, name, ret);
+ return X509_LOOKUP_by_subject_with_libctx(ctx, type, name, ret, NULL, NULL);
}
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) {
- X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->cache = 1;
if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) {
- X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) {
- X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
- X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ X509err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
-
ret->references = 1;
return ret;
if (tmp == NULL || type == X509_LU_CRL) {
for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) {
lu = sk_X509_LOOKUP_value(store->get_cert_methods, i);
- j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
+ j = X509_LOOKUP_by_subject_with_libctx(lu, type, name, &stmp,
+ vs->libctx, vs->propq);
if (j) {
tmp = &stmp;
break;
* to match issuer and subject names (i.e., the cert being self-issued) and any
* present authority key identifier to match the subject key identifier, etc.
*/
-static int x509_self_signed_ex(X509 *cert, int verify_signature,
- OPENSSL_CTX *libctx, const char *propq)
+int X509_self_signed(X509 *cert, int verify_signature)
{
EVP_PKEY *pkey;
X509err(0, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
return -1;
}
- if (!X509v3_cache_extensions(cert, libctx, propq))
+ if (!x509v3_cache_extensions(cert))
return -1;
if ((cert->ex_flags & EXFLAG_SS) == 0)
return 0;
if (!verify_signature)
return 1;
- return X509_verify_ex(cert, pkey, libctx, propq);
-}
-
-/* wrapper for internal use */
-static int cert_self_signed(X509_STORE_CTX *ctx, X509 *x, int verify_signature)
-{
- return x509_self_signed_ex(x, verify_signature, ctx->libctx, ctx->propq);
-}
-
-int X509_self_signed(X509 *cert, int verify_signature)
-{
- return x509_self_signed_ex(cert, verify_signature, NULL, NULL);
+ return X509_verify(cert, pkey);
}
/* Given a certificate try and find an exact match in the store */
*/
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
{
- if (x509_likely_issued(issuer, x, ctx->libctx, ctx->propq) != X509_V_OK)
+ if (x509_likely_issued(issuer, x) != X509_V_OK)
return 0;
if ((x->ex_flags & EXFLAG_SI) == 0 || sk_X509_num(ctx->chain) != 1) {
int i;
ret = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
if (!verify_cb_cert(ctx, xi, issuer_depth, ret))
return 0;
- } else if (X509_verify_ex(xs, pkey, ctx->libctx, ctx->propq) <= 0) {
+ } else if (X509_verify(xs, pkey) <= 0) {
ret = X509_V_ERR_CERT_SIGNATURE_FAILURE;
if (!verify_cb_cert(ctx, xs, n, ret))
return 0;
if (t->usage != DANETLS_USAGE_DANE_TA ||
t->selector != DANETLS_SELECTOR_SPKI ||
t->mtype != DANETLS_MATCHING_FULL ||
- X509_verify_ex(cert, t->spki, ctx->libctx, ctx->propq) <= 0)
+ X509_verify(cert, t->spki) <= 0)
continue;
/* Clear any PKIX-?? matches that failed to extend to a full chain */
return 0;
}
- self_signed = cert_self_signed(ctx, cert, 0);
+ self_signed = X509_self_signed(cert, 0);
if (self_signed < 0) {
ctx->error = X509_V_ERR_UNSPECIFIED;
return 0;
search = 0;
continue;
}
- self_signed = cert_self_signed(ctx, x, 0);
+ self_signed = X509_self_signed(x, 0);
if (self_signed < 0) {
ctx->error = X509_V_ERR_UNSPECIFIED;
return 0;
x = xtmp;
++ctx->num_untrusted;
- self_signed = cert_self_signed(ctx, xtmp, 0);
+ self_signed = X509_self_signed(xtmp, 0);
if (self_signed < 0) {
sk_X509_free(sktmp);
ctx->error = X509_V_ERR_UNSPECIFIED;
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
-#include "crypto/x509.h"
#include <openssl/http.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/x509v3.h>
#include "crypto/asn1.h"
+#include "crypto/x509.h"
static void clean_id_ctx(EVP_MD_CTX *ctx)
{
return NULL;
}
-int X509_verify_ex(X509 *a, EVP_PKEY *r, OPENSSL_CTX *libctx, const char *propq)
+int X509_verify(X509 *a, EVP_PKEY *r)
{
int rv = 0;
EVP_MD_CTX *ctx = NULL;
return 0;
id = a->distinguishing_id;
- if ((ctx = make_id_ctx(r, id, libctx, propq)) != NULL) {
+ if ((ctx = make_id_ctx(r, id, a->libctx, a->propq)) != NULL) {
rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
&a->signature, &a->cert_info, ctx);
clean_id_ctx(ctx);
return rv;
}
-int X509_verify(X509 *a, EVP_PKEY *r)
-{
- return X509_verify_ex(a, r, NULL, NULL);
-}
-
-int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx,
- const char *propq)
+int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx,
+ const char *propq)
{
int rv = 0;
EVP_MD_CTX *ctx = NULL;
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
{
- return X509_REQ_verify_ex(a, r, NULL, NULL);
+ return X509_REQ_verify_with_libctx(a, r, NULL, NULL);
}
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
return EVP_Digest(key->data, key->length, md, len, type, NULL);
}
-int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
+int X509_digest(const X509 *cert, const EVP_MD *md, unsigned char *data,
unsigned int *len)
{
- if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0
- && (data->ex_flags & EXFLAG_INVALID) == 0) {
+ if (EVP_MD_is_a(md, SN_sha1) && (cert->ex_flags & EXFLAG_SET) != 0
+ && (cert->ex_flags & EXFLAG_INVALID) == 0) {
/* Asking for SHA1 and we already computed it. */
if (len != NULL)
- *len = sizeof(data->sha1_hash);
- memcpy(md, data->sha1_hash, sizeof(data->sha1_hash));
+ *len = sizeof(cert->sha1_hash);
+ memcpy(data, cert->sha1_hash, sizeof(cert->sha1_hash));
return 1;
}
- return (ASN1_item_digest
- (ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
+ return (asn1_item_digest_with_libctx(ASN1_ITEM_rptr(X509), md, (char *)cert,
+ data, len, cert->libctx, cert->propq));
}
/* calculate cert digest using the same hash algorithm as in its signature */
ASN1_EMBED(X509, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509, X509)
-IMPLEMENT_ASN1_FUNCTIONS(X509)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(X509, X509, X509)
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+X509 *d2i_X509(X509 **a, const unsigned char **in, long len)
+{
+ X509 *cert = NULL;
+
+ cert = (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (X509_it()));
+ /* Only cache the extensions if the cert object was passed in */
+ if (cert != NULL && a != NULL) {
+ if (!x509v3_cache_extensions(cert))
+ cert = NULL;
+ }
+ return cert;
+}
+int i2d_X509(const X509 *a, unsigned char **out)
+{
+ return ASN1_item_i2d((const ASN1_VALUE *)a, out, (X509_it()));
+}
+
+X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq)
+{
+ X509 *cert = NULL;
+
+ cert = (X509 *)ASN1_item_new((X509_it()));
+ if (cert != NULL) {
+ cert->libctx = libctx;
+ cert->propq = propq;
+ }
+ return cert;
+}
+
int X509_set_ex_data(X509 *r, int idx, void *arg)
{
return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
/* struct ossl_store_loader_ctx_st is defined differently by each loader */
typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX;
- typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const char *uri,
- const UI_METHOD *ui_method,
- void *ui_data);
+ typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(
+ const char *uri, const UI_METHOD *ui_method, void *ui_data);
int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *store_loader,
OSSL_STORE_open_fn store_open_function);
- typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn)(const OSSL_STORE_LOADER
- *loader,
- BIO *bio,
- OPENSSL_CTX *libctx,
- const char *propq,
- const UI_METHOD
- *ui_method,
- void *ui_data);
+ typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn)
+ (const OSSL_STORE_LOADER *loader, BIO *bio,
+ OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data);
int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader,
OSSL_STORE_attach_fn attach_function);
typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd,
#include <openssl/store.h>
- OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, OPENSSL_CTX *libctx,
- const char *scheme, const char *propq,
+ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, const char *scheme,
+ OPENSSL_CTX *libctx, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data);
=head1 NAME
-OSSL_STORE_CTX, OSSL_STORE_post_process_info_fn, OSSL_STORE_open,
-OSSL_STORE_ctrl, OSSL_STORE_load, OSSL_STORE_eof, OSSL_STORE_error,
-OSSL_STORE_close - Types and functions to read objects from a URI
+OSSL_STORE_CTX, OSSL_STORE_post_process_info_fn,
+OSSL_STORE_open, OSSL_STORE_open_with_libctx,
+OSSL_STORE_ctrl, OSSL_STORE_load, OSSL_STORE_eof,
+OSSL_STORE_error, OSSL_STORE_close
+- Types and functions to read objects from a URI
=head1 SYNOPSIS
void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data);
+ OSSL_STORE_CTX *OSSL_STORE_open_with_libctx
+ (const char *uri, OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data,
+ OSSL_STORE_post_process_info_fn post_process, void *post_process_data);
+
int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */);
OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx);
int OSSL_STORE_eof(OSSL_STORE_CTX *ctx);
=head2 Types
B<OSSL_STORE_CTX> is a context variable that holds all the internal
-information for OSSL_STORE_open(), OSSL_STORE_load(), OSSL_STORE_eof() and
-OSSL_STORE_close() to work together.
+information for OSSL_STORE_open(), OSSL_STORE_open_with_libctx(),
+OSSL_STORE_load(), OSSL_STORE_eof() and OSSL_STORE_close() to work
+together.
=head2 Functions
-OSSL_STORE_open() takes a uri or path I<uri>, password UI method
+OSSL_STORE_open_with_libctx() takes a uri or path I<uri>, password UI method
I<ui_method> with associated data I<ui_data>, and post processing
callback I<post_process> with associated data I<post_process_data>,
-opens a channel to the data located at that URI and returns a
+a library context I<libctx> with an associated property query <propq>,
+and opens a channel to the data located at the URI and returns a
B<OSSL_STORE_CTX> with all necessary internal information.
The given I<ui_method> and I<ui_data> will be reused by all
functions that use B<OSSL_STORE_CTX> when interaction is needed,
the next object, until I<post_process> returns something other than
NULL, or the end of data is reached as indicated by OSSL_STORE_eof().
+OSSL_STORE_open() is similar to OSSL_STORE_open_with_libctx() but uses NULL for
+the library context I<libctx> and property query <propq>.
+
OSSL_STORE_ctrl() takes a B<OSSL_STORE_CTX>, and command number I<cmd> and
more arguments not specified here.
The available loader specific command numbers and arguments they each
=back
-OSSL_STORE_load() takes a B<OSSL_STORE_CTX>, tries to load the next available
-object and return it wrapped with B<OSSL_STORE_INFO>.
+OSSL_STORE_load() takes a B<OSSL_STORE_CTX> and tries to load the next
+available object and return it wrapped with B<OSSL_STORE_INFO>.
OSSL_STORE_eof() takes a B<OSSL_STORE_CTX> and checks if we've reached the end
of data.
OSSL_STORE_open() returns a pointer to a B<OSSL_STORE_CTX> on success, or
NULL on failure.
-OSSL_STORE_load() returns a pointer to a B<OSSL_STORE_INFO> on success, or
-NULL on error or when end of data is reached.
+OSSL_STORE_load() returns a pointer to a B<OSSL_STORE_INFO> on success, or NULL
+on error or when end of data is reached.
Use OSSL_STORE_error() and OSSL_STORE_eof() to determine the meaning of a
returned NULL.
=head1 HISTORY
+OSSL_STORE_open_with_libctx() was added in OpenSSL 3.0.
+
OSSL_STORE_CTX(), OSSL_STORE_post_process_info_fn(), OSSL_STORE_open(),
OSSL_STORE_ctrl(), OSSL_STORE_load(), OSSL_STORE_eof() and OSSL_STORE_close()
were added in OpenSSL 1.1.1.
--- /dev/null
+=pod
+
+=head1 NAME
+
+PEM_X509_INFO_read_bio_with_libctx, PEM_X509_INFO_read_with_libctx
+- read a PEM-encoded data structure from a bio into one or more B<X509_INFO>
+object's
+
+=head1 SYNOPSIS
+
+ #include <openssl/pem.h>
+
+ STACK_OF(X509_INFO) *PEM_X509_INFO_read_with_libctx(FILE *fp,
+ STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb,
+ void *u,
+ OPENSSL_CTX *libctx,
+ const char *propq);
+
+ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_with_libctx(BIO *bio,
+ STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb,
+ void *u,
+ OPENSSL_CTX *libctx,
+ const char *propq);
+
+=head1 DESCRIPTION
+
+The loaded B<X509_INFO> object's can contain a CRL, a certificate and a
+corresponding private key.
+
+PEM_X509_INFO_read_with_libctx() loads the B<X509_INFO> objects from a file I<fp>.
+The library context I<libctx> and property query <propq> are used for fetching
+algorithms from providers.
+
+PEM_X509_INFO_read_bio_with_libctx loads the B<X509_INFO> objects using a bio
+I<bp>. The library context I<libctx> and property query <propq> are used for
+fetching algorithms from providers.
+
+
+=head1 RETURN VALUES
+
+PEM_X509_INFO_read_with_libctx() and PEM_X509_INFO_read_bio_with_libctx() return
+a stack of B<X509_INFO> objects or NULL on failure.
+
+=head1 SEE ALSO
+
+L<PEM_read_bio_ex(3)>,
+L<passphrase-encoding(7)>
+
+=head1 HISTORY
+
+The functions PEM_X509_INFO_read_with_libctx() and
+PEM_X509_INFO_read_bio_with_libctx() were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
Although the PEM routines take several arguments in almost all applications
most of them are set to 0 or NULL.
+To read a certificate with a library context in PEM format from a BIO:
+
+ X509 *x = X509_new_with_libctx(libctx, NULL);
+
+ if (x == NULL)
+ /* Error */
+
+ if (PEM_read_bio_X509(bp, &x, 0, NULL) == NULL)
+ /* Error */
+
Read a certificate in PEM format from a BIO:
X509 *x;
=head1 NAME
-SSL_load_client_CA_file,
+SSL_load_client_CA_file_with_libctx, SSL_load_client_CA_file,
SSL_add_file_cert_subjects_to_stack,
SSL_add_dir_cert_subjects_to_stack,
SSL_add_store_cert_subjects_to_stack
#include <openssl/ssl.h>
+ STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file,
+ OPENSSL_CTX *libctx,
+ const char *propq);
STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
=head1 DESCRIPTION
-SSL_load_client_CA_file() reads certificates from I<file> and returns
-a STACK_OF(X509_NAME) with the subject names found.
+SSL_load_client_CA_file_with_libctx() reads certificates from I<file> and returns
+a STACK_OF(X509_NAME) with the subject names found. The library context I<libctx>
+and property query <propq> are used when fetching algorithms from providers.
+
+SSL_load_client_CA_file() is similar to SSL_load_client_CA_file_with_libctx()
+but uses NULL for the library context I<libctx> and property query <propq>.
SSL_add_file_cert_subjects_to_stack() reads certificates from I<file>,
and adds their subject name to the already existing I<stack>.
=head1 HISTORY
-SSL_add_store_cert_subjects_to_stack() was added in OpenSSL 3.0.
+SSL_load_client_CA_file_with_libctx() and SSL_add_store_cert_subjects_to_stack()
+were added in OpenSSL 3.0.
=head1 COPYRIGHT
X509_LOOKUP_new, X509_LOOKUP_free, X509_LOOKUP_init,
X509_LOOKUP_shutdown,
X509_LOOKUP_set_method_data, X509_LOOKUP_get_method_data,
-X509_LOOKUP_ctrl,
-X509_LOOKUP_load_file, X509_LOOKUP_add_dir, X509_LOOKUP_add_store,
-X509_LOOKUP_load_store,
-X509_LOOKUP_get_store, X509_LOOKUP_by_subject,
+X509_LOOKUP_ctrl_with_libctx, X509_LOOKUP_ctrl,
+X509_LOOKUP_load_file_with_libctx, X509_LOOKUP_load_file,
+X509_LOOKUP_add_dir,
+X509_LOOKUP_add_store_with_libctx, X509_LOOKUP_add_store,
+X509_LOOKUP_load_store_with_libctx, X509_LOOKUP_load_store,
+X509_LOOKUP_get_store,
+X509_LOOKUP_by_subject_with_libctx, X509_LOOKUP_by_subject,
X509_LOOKUP_by_issuer_serial, X509_LOOKUP_by_fingerprint,
X509_LOOKUP_by_alias
- OpenSSL certificate lookup mechanisms
int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data);
void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx);
+ int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc,
+ long argl, char **ret, OPENSSL_CTX *libctx,
+ const char *propq);
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
+ int X509_LOOKUP_load_file_with_libctx(X509_LOOKUP *ctx, char *name, long type,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_LOOKUP_load_file(X509_LOOKUP *ctx, char *name, long type);
+ int X509_LOOKUP_load_file_with_libctx(X509_LOOKUP *ctx, char *name, long type,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_LOOKUP_add_dir(X509_LOOKUP *ctx, char *name, long type);
+ int X509_LOOKUP_add_store_with_libctx(X509_LOOKUP *ctx, char *uri,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_LOOKUP_add_store(X509_LOOKUP *ctx, char *uri);
+ int X509_LOOKUP_load_store_with_libctx(X509_LOOKUP *ctx, char *uri,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_LOOKUP_load_store(X509_LOOKUP *ctx, char *uri);
X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx);
+ int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
const X509_NAME *name, X509_OBJECT *ret);
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
associates and retrieves a pointer to application data to and from the
given B<X509_LOOKUP>, respectively.
-X509_LOOKUP_ctrl() is used to set or get additional data to or from a
-B<X509_LOOKUP> structure or its associated L<X509_LOOKUP_METHOD(3)>.
+X509_LOOKUP_ctrl_with_libctx() is used to set or get additional data to or from
+a B<X509_LOOKUP> structure or its associated L<X509_LOOKUP_METHOD(3)>.
The arguments of the control command are passed via I<argc> and I<argl>,
-its return value via I<*ret>.
+its return value via I<*ret>. The library context I<libctx> and property
+query <propq> are used when fetching algorithms from providers.
The meaning of the arguments depends on the I<cmd> number of the
control command. In general, this function is not called directly, but
wrapped by a macro call, see below.
The control I<cmd>s known to OpenSSL are discussed in more depth
in L</Control Commands>.
-X509_LOOKUP_load_file() passes a filename to be loaded immediately
-into the associated B<X509_STORE>.
+X509_LOOKUP_ctrl() is similar to X509_LOOKUP_ctrl_with_libctx() but
+uses NULL for the library context I<libctx> and property query <propq>.
+
+X509_LOOKUP_load_file_with_libctx() passes a filename to be loaded immediately
+into the associated B<X509_STORE>. The library context I<libctx> and property
+query <propq> are used when fetching algorithms from providers.
I<type> indicates what type of object is expected.
This can only be used with a lookup using the implementation
L<X509_LOOKUP_file(3)>.
+X509_LOOKUP_load_file() is similar to X509_LOOKUP_load_file_with_libctx() but
+uses NULL for the library context I<libctx> and property query <propq>.
+
X509_LOOKUP_add_dir() passes a directory specification from which
certificates and CRLs are loaded on demand into the associated
B<X509_STORE>.
This can only be used with a lookup using the implementation
L<X509_LOOKUP_hash_dir(3)>.
-X509_LOOKUP_add_store() passes a URI for a directory-like structure
+X509_LOOKUP_add_store_with_libctx() passes a URI for a directory-like structure
from which containers with certificates and CRLs are loaded on demand
-into the associated B<X509_STORE>.
-X509_LOOKUP_load_store() passes a URI for a single container from
+into the associated B<X509_STORE>. The library context I<libctx> and property
+query <propq> are used when fetching algorithms from providers.
+
+X509_LOOKUP_add_store() is similar to X509_LOOKUP_add_store_with_libctx() but
+uses NULL for the library context I<libctx> and property query <propq>.
+
+X509_LOOKUP_load_store_with_libctx() passes a URI for a single container from
which certificates and CRLs are immediately loaded into the associated
-B<X509_STORE>.
+B<X509_STORE>. The library context I<libctx> and property query <propq> are used
+when fetching algorithms from providers.
These functions can only be used with a lookup using the
implementation L<X509_LOOKUP_store(3)>.
-X509_LOOKUP_load_file(), X509_LOOKUP_add_dir(),
-X509_LOOKUP_add_store(), and X509_LOOKUP_load_store() are implemented
-as macros that use X509_LOOKUP_ctrl().
+X509_LOOKUP_load_store() is similar to X509_LOOKUP_load_store_with_libctx() but
+uses NULL for the library context I<libctx> and property query <propq>.
-X509_LOOKUP_by_subject(), X509_LOOKUP_by_issuer_serial(),
-X509_LOOKUP_by_fingerprint(), and X509_LOOKUP_by_alias() look up
-certificates and CRLs in the L<X509_STORE(3)> associated with the
-B<X509_LOOKUP> using different criteria, where the looked up object is
-stored in I<ret>.
+X509_LOOKUP_load_file_with_libctx(), X509_LOOKUP_load_file(),
+X509_LOOKUP_add_dir(),
+X509_LOOKUP_add_store_with_libctx() X509_LOOKUP_add_store(),
+X509_LOOKUP_load_store_with_libctx() and X509_LOOKUP_load_store() are
+implemented as macros that use X509_LOOKUP_ctrl().
+
+X509_LOOKUP_by_subject_with_libctx(), X509_LOOKUP_by_subject(),
+X509_LOOKUP_by_issuer_serial(), X509_LOOKUP_by_fingerprint(), and
+X509_LOOKUP_by_alias() look up certificates and CRLs in the L<X509_STORE(3)>
+associated with the B<X509_LOOKUP> using different criteria, where the looked up
+object is stored in I<ret>.
Some of the underlying B<X509_LOOKUP_METHOD>s will also cache objects
matching the criteria in the associated B<X509_STORE>, which makes it
possible to handle cases where the criteria have more than one hit.
=head2 Control Commands
-The B<X509_LOOKUP_METHOD>s built into OpenSSL recognise the following
+The B<X509_LOOKUP_METHOD>s built into OpenSSL recognize the following
X509_LOOKUP_ctrl() I<cmd>s:
=over 4
=item B<X509_L_FILE_LOAD>
-This is the command that X509_LOOKUP_load_file() uses.
+This is the command that X509_LOOKUP_load_file_with_libctx() and
+X509_LOOKUP_load_file() use.
The filename is passed in I<argc>, and the type in I<argl>.
=item B<X509_L_ADD_DIR>
=item B<X509_L_ADD_STORE>
-This is the command that X509_LOOKUP_add_store() uses.
+This is the command that X509_LOOKUP_add_store_with_libctx() and
+X509_LOOKUP_add_store() use.
The URI is passed in I<argc>.
=item B<X509_L_LOAD_STORE>
-This is the command that X509_LOOKUP_load_store() uses.
+This is the command that X509_LOOKUP_load_store_with_libctx() and
+X509_LOOKUP_load_store() use.
The URI is passed in I<argc>.
=back
X509_LOOKUP_get_store() returns a B<X509_STORE> pointer if there is
one, otherwise NULL.
-X509_LOOKUP_by_subject(), X509_LOOKUP_by_issuer_serial(),
-X509_LOOKUP_by_fingerprint(), and X509_LOOKUP_by_alias() all return 0
-if there is no B<X509_LOOKUP_METHOD> or that method doesn't implement
-the corresponding function.
+X509_LOOKUP_by_subject_with_libctx(), X509_LOOKUP_by_subject(),
+X509_LOOKUP_by_issuer_serial(), X509_LOOKUP_by_fingerprint(), and
+X509_LOOKUP_by_alias() all return 0 if there is no B<X509_LOOKUP_METHOD> or that
+method doesn't implement the corresponding function.
Otherwise, it returns what the corresponding function in the
B<X509_LOOKUP_METHOD> returns, which is usually 1 on success and 0 in
error.
L<X509_LOOKUP_METHOD(3)>, L<X509_STORE(3)>
+=head1 HISTORY
+
+The functions X509_LOOKUP_by_subject_with_libctx() and
+X509_LOOKUP_ctrl_with_libctx() were added in OpenSSL 3.0.
+
+The macros X509_LOOKUP_load_file_with_libctx(),
+X509_LOOKUP_load_store_with_libctx() and 509_LOOKUP_add_store_with_libctx() were
+added in OpenSSL 3.0.
+
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
=head1 NAME
X509_LOOKUP_hash_dir, X509_LOOKUP_file, X509_LOOKUP_store,
-X509_load_cert_file,
+X509_load_cert_file_with_libctx, X509_load_cert_file,
X509_load_crl_file,
-X509_load_cert_crl_file - Default OpenSSL certificate
-lookup methods
+X509_load_cert_crl_file_with_libctx, X509_load_cert_crl_file
+- Default OpenSSL certificate lookup methods
=head1 SYNOPSIS
X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
X509_LOOKUP_METHOD *X509_LOOKUP_store(void);
+ int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file,
+ int type, OPENSSL_CTX *libctx,
+ const char *propq);
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+ int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file,
+ int type, OPENSSL_CTX *libctx,
+ const char *propq);
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
=head1 DESCRIPTION
=head1 HISTORY
-B<X509_LOOKUP_store> was added in OpenSSL 3.0.
+The functions X509_load_cert_file_with_libctx(),
+X509_load_cert_crl_file_with_libctx() and X509_LOOKUP_store() were added in
+OpenSSL 3.0.
=head1 COPYRIGHT
X509_STORE_add_cert, X509_STORE_add_crl, X509_STORE_set_depth,
X509_STORE_set_flags, X509_STORE_set_purpose, X509_STORE_set_trust,
X509_STORE_add_lookup,
-X509_STORE_load_file, X509_STORE_load_path, X509_STORE_load_store,
-X509_STORE_set_default_paths,
-X509_STORE_load_locations
+X509_STORE_load_file_with_libctx, X509_STORE_load_file, X509_STORE_load_path,
+X509_STORE_load_store_with_libctx, X509_STORE_load_store,
+X509_STORE_set_default_paths_with_libctx, X509_STORE_set_default_paths,
+X509_STORE_load_locations_with_libctx, X509_STORE_load_locations
- X509_STORE manipulation
=head1 SYNOPSIS
X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *store,
X509_LOOKUP_METHOD *meth);
+ int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx,
+ OPENSSL_CTX *libctx,
+ const char *propq);
int X509_STORE_set_default_paths(X509_STORE *ctx);
+ int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_STORE_load_file(X509_STORE *ctx, const char *file);
int X509_STORE_load_path(X509_STORE *ctx, const char *dir);
+ int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *uri,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_STORE_load_store(X509_STORE *ctx, const char *uri);
-
+ int X509_STORE_load_locations_with_libctx(X509_STORE *ctx,
+ const char *file, const char *dir,
+ OPENSSL_CTX *libctx,
+ const char *propq);
int X509_STORE_load_locations(X509_STORE *ctx,
const char *file, const char *dir);
I<store>. This also associates the B<X509_STORE> with the lookup, so
B<X509_LOOKUP> functions can look up objects in that store.
-X509_STORE_load_file() loads trusted certificate(s) into an
-B<X509_STORE> from a given file.
+X509_STORE_load_file_with_libctx() loads trusted certificate(s) into an
+B<X509_STORE> from a given file. The library context I<libctx> and property
+query <propq> are used when fetching algorithms from providers.
+
+X509_STORE_load_file() is similar to X509_STORE_load_file_with_libctx() but
+uses NULL for the library context I<libctx> and property query <propq>.
X509_STORE_load_path() loads trusted certificate(s) into an
B<X509_STORE> from a given directory path.
The certificates in the directory must be in hashed form, as
documented in L<X509_LOOKUP_hash_dir(3)>.
-X509_STORE_load_store() loads trusted certificate(s) into an
-B<X509_STORE> from a store at a given URI.
+X509_STORE_load_store_with_libctx() loads trusted certificate(s) into an
+B<X509_STORE> from a store at a given URI. The library context I<libctx> and
+property query <propq> are used when fetching algorithms from providers.
-X509_STORE_load_locations() combines X509_STORE_load_file() and
-X509_STORE_load_dir() for a given file and/or directory path.
+X509_STORE_load_store() is similar to X509_STORE_load_store_with_libctx() but
+uses NULL for the library context I<libctx> and property query <propq>.
+
+X509_STORE_load_locations_with_libctx() combines
+X509_STORE_load_file_with_libctx() and X509_STORE_load_dir() for a given file
+and/or directory path.
It is permitted to specify just a file, just a directory, or both
paths.
-X509_STORE_set_default_paths() is somewhat misnamed, in that it does not
-set what default paths should be used for loading certificates. Instead,
+X509_STORE_load_locations() is similar to X509_STORE_load_locations_with_libctx()
+but uses NULL for the library context I<libctx> and property query <propq>.
+
+X509_STORE_set_default_paths_with_libctx() is somewhat misnamed, in that it does
+not set what default paths should be used for loading certificates. Instead,
it loads certificates into the B<X509_STORE> from the hardcoded default
-paths.
+paths. The library context I<libctx> and property query <propq> are used when
+fetching algorithms from providers.
+
+X509_STORE_set_default_paths() is similar to
+X509_STORE_set_default_paths_with_libctx() but uses NULL for the library
+context I<libctx> and property query <propq>.
=head1 RETURN VALUES
X509_STORE_add_cert(), X509_STORE_add_crl(), X509_STORE_set_depth(),
-X509_STORE_set_flags(), X509_STORE_set_purpose(),
-X509_STORE_set_trust(), X509_STORE_load_file(),
-X509_STORE_load_path(), X509_STORE_load_store(),
-X509_STORE_load_locations(), and X509_STORE_set_default_paths() return
-1 on success or 0 on failure.
+X509_STORE_set_flags(), X509_STORE_set_purpose(), X509_STORE_set_trust(),
+X509_STORE_load_file_with_libctx(), X509_STORE_load_file(),
+X509_STORE_load_path(),
+X509_STORE_load_store_with_libctx(), X509_STORE_load_store(),
+X509_STORE_load_locations_with_libctx(), X509_STORE_load_locations(),
+X509_STORE_set_default_paths_with_libctx() and X509_STORE_set_default_paths()
+return 1 on success or 0 on failure.
X509_STORE_add_lookup() returns the found or created
L<X509_LOOKUP(3)>, or NULL on error.
L<X509_STORE_new(3)>,
L<X509_STORE_get0_param(3)>
+=head1 HISTORY
+
+The functions X509_STORE_set_default_paths_with_libctx(),
+X509_STORE_load_file_with_libctx(), X509_STORE_load_store_with_libctx() and
+X509_STORE_load_locations_with_libctx() were added in OpenSSL 3.0.
+
=head1 COPYRIGHT
Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
=head1 NAME
-X509_STORE_new, X509_STORE_up_ref, X509_STORE_free, X509_STORE_lock,
-X509_STORE_unlock - X509_STORE allocation, freeing and locking functions
+X509_STORE_new, X509_STORE_up_ref, X509_STORE_free,
+X509_STORE_lock,X509_STORE_unlock
+- X509_STORE allocation, freeing and locking functions
=head1 SYNOPSIS
=head1 COPYRIGHT
-Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
=head1 NAME
X509_chain_up_ref,
-X509_new, X509_free, X509_up_ref - X509 certificate ASN1 allocation functions
+X509_new, X509_new_with_libctx,
+X509_free, X509_up_ref - X509 certificate ASN1 allocation functions
=head1 SYNOPSIS
#include <openssl/x509.h>
X509 *X509_new(void);
+ X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq);
void X509_free(X509 *a);
int X509_up_ref(X509 *a);
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *x);
The X509 ASN1 allocation routines, allocate and free an
X509 structure, which represents an X509 certificate.
-X509_new() allocates and initializes a X509 structure with reference count
-B<1>.
+X509_new_with_libctx() allocates and initializes a X509 structure with a
+library context of I<libctx>, property query of <propq> and a reference
+count of B<1>. Many X509 functions such as X509_check_purpose(), and
+X509_verify() use this library context to select which providers supply the
+fetched algorithms (SHA1 is used internally).
+
+X509_new() is similar to X509_new_with_libctx() but sets the library context
+and property query to NULL. This results in the default (NULL) library context
+being used for any X509 operations requiring algorithm fetches.
X509_free() decrements the reference count of B<X509> structure B<a> and
frees it up if the reference count is zero. If B<a> is NULL nothing is done.
L<X509V3_get_d2i(3)>,
L<X509_verify_cert(3)>
+=head1 HISTORY
+
+The function X509_new_with_libctx() was added in OpenSSL 3.0.
+
=head1 COPYRIGHT
Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
L<X509_NAME_add_entry_by_txt(3)>,
L<X509_new(3)>,
L<X509_verify_cert(3)>,
-L<X509_verify_ex(3)>, L<X509_verify(3)>,
-L<X509_REQ_verify_ex(3)>, L<X509_REQ_verify(3)>,
+L<X509_verify(3)>,
+L<X509_REQ_verify_with_libctx(3)>, L<X509_REQ_verify(3)>,
L<X509_CRL_verify(3)>
=head1 HISTORY
=head1 NAME
-X509_verify_ex, X509_verify, X509_self_signed,
-X509_REQ_verify_ex, X509_REQ_verify,
+X509_verify, X509_self_signed,
+X509_REQ_verify_with_libctx, X509_REQ_verify,
X509_CRL_verify -
verify certificate, certificate request, or CRL signature
#include <openssl/x509.h>
- int X509_verify_ex(X509 *x, EVP_PKEY *pkey,
- OPENSSL_CTX *libctx, const char *propq);
int X509_verify(X509 *x, EVP_PKEY *pkey);
int X509_self_signed(X509 *cert, int verify_signature);
- int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *pkey,
- OPENSSL_CTX *libctx, const char *propq);
+ int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *pkey,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
=head1 DESCRIPTION
-X509_verify_ex() verifies the signature of certificate I<x> using public key
-I<pkey>. Any cryptographic algorithms required for the verification are fetched
-using the library context I<libctx> and the property query string I<propq>.
-Only the signature is checked:
-no other checks (such as certificate chain validity) are performed.
-
-X509_verify() is the same as X509_verify_ex() except that the default library
-context and property query string are used.
+X509_verify() verifies the signature of certificate I<x> using public key
+I<pkey>. Only the signature is checked: no other checks (such as certificate
+chain validity) are performed.
X509_self_signed() checks whether a certificate is self-signed.
For success the issuer and subject names must match, the components of the
The signature itself is actually verified only if B<verify_signature> is 1, as
for explicitly trusted certificates this verification is not worth the effort.
-X509_REQ_verify_ex(), X509_REQ_verify() and X509_CRL_verify()
+X509_REQ_verify_with_libctx(), X509_REQ_verify() and X509_CRL_verify()
verify the signatures of certificate requests and CRLs, respectively.
=head1 RETURN VALUES
-X509_verify_ex(), X509_verify(),
-X509_REQ_verify_ex(), X509_REQ_verify() and X509_CRL_verify()
+X509_verify(),
+X509_REQ_verify_with_libctx(), X509_REQ_verify() and X509_CRL_verify()
return 1 if the signature is valid and 0 if the signature check fails.
If the signature could not be checked at all because it was ill-formed
or some other error occurred then -1 is returned.
The X509_verify(), X509_REQ_verify(), and X509_CRL_verify()
functions are available in all versions of OpenSSL.
-X509_verify_ex(), X509_REQ_verify_ex(), and X509_self_signed()
-were added in OpenSSL 3.0.
+X509_REQ_verify_with_libctx(), and X509_self_signed() were added in OpenSSL 3.0.
=head1 COPYRIGHT
+++ /dev/null
-=pod
-
-=head1 NAME
-
-X509v3_cache_extensions
-- cache info on various X.509v3 extensions and further derived certificate data
-
-=head1 SYNOPSIS
-
- #include <openssl/x509v3.h>
-
- int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq);
-
-=head1 DESCRIPTION
-
-This function processes any X509v3 extensions that might be present in an X509
-object and caches the result of that processing as well as further derived info,
-for instance if the certificate is self-issued. Many OpenSSL functions that use
-an X509 object will cause extensions to be processed and cached implicitly. If
-this is done implicitly then the default library context and property query
-string will be used. In some cases it may be desirable to use some other library
-context and property query string. If so then an application can call
-X509v3_cache_extensions() explicitly. This should be done before any function
-that needs to use those extensions is called - otherwise calling
-X509v3_cache_extensions() will have no effect. Typically this means calling this
-soon after creation of the X509 object. The X509 object to be processed is
-given in I<x> and the library context and property query string to use are given
-in I<libctx> and I<propq>.
-
-=head1 RETURN VALUES
-
-This function returns 0 if the extensions are invalid or an error occurred.
-Otherwise it returns 1.
-
-=head1 COPYRIGHT
-
-Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License"). You may not use
-this file except in compliance with the License. You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
L<X509_NAME_add_entry_by_NID(3)>,
L<X509_NAME_print_ex(3)>,
L<X509_NAME_new(3)>,
+L<PEM_X509_INFO_read(3)>,
L<d2i_X509(3)>,
L<d2i_X509_ALGOR(3)>,
L<d2i_X509_CRL(3)>,
=head1 COPYRIGHT
-Copyright 2003-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2003-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
# include <openssl/store.h>
# include <openssl/ui.h>
-/*
- * Two functions to read PEM data off an already opened BIO. To be used
- * instead of OSSLSTORE_open() and OSSLSTORE_close(). Everything is done
- * as usual with OSSLSTORE_load() and OSSLSTORE_eof().
- */
-OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
- void *ui_data, OPENSSL_CTX *libctx,
- const char *propq);
-int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx);
-
void ossl_store_cleanup_int(void);
#endif
/* Set on live certificates for authentication purposes */
ASN1_OCTET_STRING *distinguishing_id;
+
+ OPENSSL_CTX *libctx;
+ const char *propq;
} /* X509 */ ;
/*
int a2i_ipadd(unsigned char *ipout, const char *ipasc);
int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags);
+int x509v3_cache_extensions(X509 *x);
void x509_init_sig_info(X509 *x);
-
-int x509_check_issued_int(X509 *issuer, X509 *subject, OPENSSL_CTX *libctx,
- const char *propq);
+int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *type,
+ void *data, unsigned char *md,
+ unsigned int *len, OPENSSL_CTX *libctx,
+ const char *propq);
STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
pem_password_cb *cb, void *u);
+STACK_OF(X509_INFO)
+*PEM_X509_INFO_read_bio_with_libctx(BIO *bp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u,
+ OPENSSL_CTX *libctx, const char *propq);
+
int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc,
const unsigned char *kstr, int klen,
pem_password_cb *cd, void *u);
pem_password_cb *callback, void *u);
STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
pem_password_cb *cb, void *u);
+STACK_OF(X509_INFO)
+*PEM_X509_INFO_read_with_libctx(FILE *fp, STACK_OF(X509_INFO) *sk,
+ pem_password_cb *cb, void *u,
+ OPENSSL_CTX *libctx, const char *propq);
#endif
int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
__owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file);
__owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+__owur STACK_OF(X509_NAME)
+*SSL_load_client_CA_file_with_libctx(const char *file,
+ OPENSSL_CTX *libctx, const char *propq);
__owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
const char *file);
int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data);
+OSSL_STORE_CTX *OSSL_STORE_open_with_libctx
+ (const char *uri, OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data,
+ OSSL_STORE_post_process_info_fn post_process, void *post_process_data);
+
/*
* Control / fine tune the OSSL_STORE channel. |cmd| determines what is to be
* done, and depends on the underlying loader (use OSSL_STORE_get0_scheme to
* Note that this function is considered unsafe, all depending on what the
* BIO actually reads.
*/
-OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, OPENSSL_CTX *libctx,
- const char *scheme, const char *propq,
+OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, const char *scheme,
+ OPENSSL_CTX *libctx, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data);
const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader);
/* struct ossl_store_loader_ctx_st is defined differently by each loader */
typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX;
-typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const OSSL_STORE_LOADER
- *loader,
- const char *uri,
- const UI_METHOD *ui_method,
- void *ui_data);
+typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)
+ (const OSSL_STORE_LOADER *loader, const char *uri,
+ const UI_METHOD *ui_method, void *ui_data);
+typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_with_libctx_fn)
+ (const OSSL_STORE_LOADER *loader,
+ const char *uri, OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data);
+
int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader,
OSSL_STORE_open_fn open_function);
-typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn)(const OSSL_STORE_LOADER
- *loader,
- BIO *bio,
- OPENSSL_CTX *libctx,
- const char *propq,
- const UI_METHOD
- *ui_method,
- void *ui_data);
+typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn)
+ (const OSSL_STORE_LOADER *loader, BIO *bio,
+ OPENSSL_CTX *libctx, const char *propq,
+ const UI_METHOD *ui_method, void *ui_data);
int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader,
OSSL_STORE_attach_fn attach_function);
typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd,
void *ui_data);
int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader,
OSSL_STORE_load_fn load_function);
+
typedef int (*OSSL_STORE_eof_fn)(OSSL_STORE_LOADER_CTX *ctx);
int OSSL_STORE_LOADER_set_eof(OSSL_STORE_LOADER *loader,
OSSL_STORE_eof_fn eof_function);
const char *X509_verify_cert_error_string(long n);
-int X509_verify_ex(X509 *a, EVP_PKEY *r, OPENSSL_CTX *libctx, const char *propq);
int X509_verify(X509 *a, EVP_PKEY *r);
int X509_self_signed(X509 *cert, int verify_signature);
-int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx,
- const char *propq);
+int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx,
+ const char *propq);
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
DECLARE_ASN1_FUNCTIONS(X509_CINF)
DECLARE_ASN1_FUNCTIONS(X509)
+X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq);
DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
#define X509_get_ex_new_index(l, p, newf, dupf, freef) \
const X509_NAME *nm);
typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx);
-
void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
# define X509_STORE_CTX_set_app_data(ctx,data) \
# define X509_LOOKUP_load_store(x,name) \
X509_LOOKUP_ctrl((x),X509_L_LOAD_STORE,(name),0,NULL)
+# define X509_LOOKUP_load_file_with_libctx(x, name, type, libctx, propq) \
+X509_LOOKUP_ctrl_with_libctx((x), X509_L_FILE_LOAD, (name), (long)(type), NULL,\
+ (libctx), (propq))
+
+# define X509_LOOKUP_load_store_with_libctx(x, name, libctx, propq) \
+X509_LOOKUP_ctrl_with_libctx((x), X509_L_LOAD_STORE, (name), 0, NULL, \
+ (libctx), (propq))
+
+# define X509_LOOKUP_add_store_with_libctx(x, name, libctx, propq) \
+X509_LOOKUP_ctrl_with_libctx((x), X509_L_ADD_STORE, (name), 0, NULL, \
+ (libctx), (propq))
+
+
# define X509_V_OK 0
# define X509_V_ERR_UNSPECIFIED 1
# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
typedef int (*X509_LOOKUP_ctrl_fn)(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
+typedef int (*X509_LOOKUP_ctrl_with_libctx_fn)(
+ X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret,
+ OPENSSL_CTX *libctx, const char *propq);
+
typedef int (*X509_LOOKUP_get_by_subject_fn)(X509_LOOKUP *ctx,
X509_LOOKUP_TYPE type,
const X509_NAME *name,
X509_OBJECT *ret);
+typedef int (*X509_LOOKUP_get_by_subject_with_libctx_fn)(X509_LOOKUP *ctx,
+ X509_LOOKUP_TYPE type,
+ const X509_NAME *name,
+ X509_OBJECT *ret,
+ OPENSSL_CTX *libctx,
+ const char *propq);
typedef int (*X509_LOOKUP_get_by_issuer_serial_fn)(X509_LOOKUP *ctx,
X509_LOOKUP_TYPE type,
const X509_NAME *name,
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
+int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc,
+ long argl, char **ret,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file,
+ int type, OPENSSL_CTX *libctx,
+ const char *propq);
X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
void X509_LOOKUP_free(X509_LOOKUP *ctx);
int X509_LOOKUP_init(X509_LOOKUP *ctx);
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
const X509_NAME *name, X509_OBJECT *ret);
+int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret,
+ OPENSSL_CTX *libctx, const char *propq);
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
const X509_NAME *name,
const ASN1_INTEGER *serial,
const char *dir);
int X509_STORE_set_default_paths(X509_STORE *ctx);
+int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file,
+ OPENSSL_CTX *libctx, const char *propq);
+int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *store,
+ OPENSSL_CTX *libctx, const char *propq);
+int X509_STORE_load_locations_with_libctx(X509_STORE *ctx,
+ const char *file, const char *dir,
+ OPENSSL_CTX *libctx, const char *propq);
+int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx,
+ OPENSSL_CTX *libctx,
+ const char *propq);
+
#define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \
CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef)
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
X509V3_CTX *ctx, CONF_VALUE *cnf,
int is_nc);
-int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq);
-
void X509V3_conf_free(CONF_VALUE *val);
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
return 0;
}
}
- if (!X509v3_cache_extensions((X509 *)parg, ctx->libctx, ctx->propq)) {
- SSLerr(0, ERR_LIB_X509);
- return 0;
- }
if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) {
SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE);
return 0;
{
int i, r;
CERT_PKEY *cpk = s != NULL ? s->cert->key : ctx->cert->key;
- SSL_CTX *realctx = s != NULL ? s->ctx : ctx;
if (!cpk)
return 0;
for (i = 0; i < sk_X509_num(chain); i++) {
X509 *x = sk_X509_value(chain, i);
- if (!X509v3_cache_extensions(x, realctx->libctx, realctx->propq)) {
- SSLerr(0, ERR_LIB_X509);
- return 0;
- }
-
r = ssl_security_cert(s, ctx, x, 0, 0);
if (r != 1) {
SSLerr(SSL_F_SSL_CERT_SET0_CHAIN, r);
return X509_NAME_hash((X509_NAME *)a);
}
-STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
+STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file,
+ OPENSSL_CTX *libctx,
+ const char *propq)
{
BIO *in = BIO_new(BIO_s_file());
X509 *x = NULL;
X509_NAME *xn = NULL;
STACK_OF(X509_NAME) *ret = NULL;
LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp);
+ OPENSSL_CTX *prev_libctx = NULL;
if ((name_hash == NULL) || (in == NULL)) {
- SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
+ x = X509_new_with_libctx(libctx, propq);
+ if (x == NULL) {
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
if (!BIO_read_filename(in, file))
goto err;
+ /* Internally lh_X509_NAME_retrieve() needs the libctx to retrieve SHA1 */
+ prev_libctx = OPENSSL_CTX_set0_default(libctx);
for (;;) {
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
break;
if (ret == NULL) {
ret = sk_X509_NAME_new_null();
if (ret == NULL) {
- SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
}
sk_X509_NAME_pop_free(ret, X509_NAME_free);
ret = NULL;
done:
+ /* restore the old libctx */
+ OPENSSL_CTX_set0_default(prev_libctx);
BIO_free(in);
X509_free(x);
lh_X509_NAME_free(name_hash);
return ret;
}
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
+{
+ return SSL_load_client_CA_file_with_libctx(file, NULL, NULL);
+}
+
int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
const char *file)
{
X509_STORE_CTX *xs_ctx = NULL;
STACK_OF(X509) *chain = NULL, *untrusted = NULL;
X509 *x;
+ SSL_CTX *real_ctx = (s == NULL) ? ctx : s->ctx;
int i, rv = 0;
if (!cpk->x509) {
untrusted = cpk->chain;
}
- if (s == NULL)
- xs_ctx = X509_STORE_CTX_new_with_libctx(ctx->libctx, ctx->propq);
- else
- xs_ctx = X509_STORE_CTX_new_with_libctx(s->ctx->libctx, s->ctx->propq);
+ xs_ctx = X509_STORE_CTX_new_with_libctx(real_ctx->libctx, ctx->propq);
if (xs_ctx == NULL) {
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_MALLOC_FAILURE);
goto err;
{
CERT *cert;
X509_STORE **st;
+ SSL_CTX *ctx;
+ OPENSSL_CTX *libctx = NULL;
+ const char *propq = NULL;
- if (cctx->ctx)
+ if (cctx->ctx != NULL) {
cert = cctx->ctx->cert;
- else if (cctx->ssl)
+ ctx = cctx->ctx;
+ } else if (cctx->ssl != NULL) {
cert = cctx->ssl->cert;
- else
+ ctx = cctx->ssl->ctx;
+ } else {
return 1;
+ }
+ if (ctx != NULL) {
+ libctx = ctx->libctx;
+ propq = ctx->propq;
+ }
st = verify_store ? &cert->verify_store : &cert->chain_store;
if (*st == NULL) {
*st = X509_STORE_new();
return 0;
}
- if (CAfile != NULL && !X509_STORE_load_file(*st, CAfile))
+ if (CAfile != NULL && !X509_STORE_load_file_with_libctx(*st, CAfile,
+ libctx, propq))
return 0;
if (CApath != NULL && !X509_STORE_load_path(*st, CApath))
return 0;
- if (CAstore != NULL && !X509_STORE_load_store(*st, CAstore))
+ if (CAstore != NULL && !X509_STORE_load_store_with_libctx(*st, CAstore,
+ libctx, propq))
return 0;
return 1;
}
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
{
- return X509_STORE_set_default_paths(ctx->cert_store);
+ return X509_STORE_set_default_paths_with_libctx(ctx->cert_store,
+ ctx->libctx, ctx->propq);
}
int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx)
/* We ignore errors, in case the directory doesn't exist */
ERR_set_mark();
- X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+ X509_LOOKUP_load_file_with_libctx(lookup, NULL, X509_FILETYPE_DEFAULT,
+ ctx->libctx, ctx->propq);
ERR_pop_to_mark();
/* We ignore errors, in case the directory doesn't exist */
ERR_set_mark();
- X509_LOOKUP_add_store(lookup, NULL);
+ X509_LOOKUP_add_store_with_libctx(lookup, NULL, ctx->libctx, ctx->propq);
ERR_pop_to_mark();
int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile)
{
- return X509_STORE_load_file(ctx->cert_store, CAfile);
+ return X509_STORE_load_file_with_libctx(ctx->cert_store, CAfile,
+ ctx->libctx, ctx->propq);
}
int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath)
int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore)
{
- return X509_STORE_load_store(ctx->cert_store, CAstore);
+ return X509_STORE_load_store_with_libctx(ctx->cert_store, CAstore,
+ ctx->libctx, ctx->propq);
}
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
unsigned int flags;
const SSL_METHOD *meth;
const SSL_CONF_CMD *cmds;
+ OPENSSL_CTX *prev_libctx = NULL;
+ OPENSSL_CTX *libctx = NULL;
if (s == NULL && ctx == NULL) {
SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER);
if (s != NULL) {
meth = s->method;
SSL_CONF_CTX_set_ssl(cctx, s);
+ libctx = s->ctx->libctx;
} else {
meth = ctx->method;
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
+ libctx = ctx->libctx;
}
if (meth->ssl_accept != ssl_undefined_function)
flags |= SSL_CONF_FLAG_SERVER;
if (meth->ssl_connect != ssl_undefined_function)
flags |= SSL_CONF_FLAG_CLIENT;
SSL_CONF_CTX_set_flags(cctx, flags);
+ prev_libctx = OPENSSL_CTX_set0_default(libctx);
for (i = 0; i < cmd_count; i++) {
char *cmdstr, *arg;
}
rv = SSL_CONF_CTX_finish(cctx);
err:
+ OPENSSL_CTX_set0_default(prev_libctx);
SSL_CONF_CTX_free(cctx);
return rv <= 0 ? 0 : 1;
}
SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if (!X509v3_cache_extensions(x, ssl->ctx->libctx, ssl->ctx->propq)) {
- SSLerr(0, ERR_LIB_X509);
- return 0;
- }
+
rv = ssl_security_cert(ssl, NULL, x, 0, 1);
if (rv != 1) {
SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv);
int j;
BIO *in;
int ret = 0;
- X509 *x = NULL;
+ X509 *cert = NULL, *x = NULL;
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
goto end;
}
+
+ if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) {
+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+ x = X509_new_with_libctx(ssl->ctx->libctx, ssl->ctx->propq);
+ if (x == NULL) {
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
- x = d2i_X509_bio(in, NULL);
+ cert = d2i_X509_bio(in, &x);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
- x = PEM_read_bio_X509(in, NULL, ssl->default_passwd_callback,
- ssl->default_passwd_callback_userdata);
+ cert = PEM_read_bio_X509(in, &x, ssl->default_passwd_callback,
+ ssl->default_passwd_callback_userdata);
} else {
SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
goto end;
}
- if (x == NULL) {
+ if (cert == NULL) {
SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j);
goto end;
}
X509 *x;
int ret;
- x = d2i_X509(NULL, &d, (long)len);
+ x = X509_new_with_libctx(ssl->ctx->libctx, ssl->ctx->propq);
if (x == NULL) {
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (d2i_X509(&x, &d, (long)len)== NULL) {
+ X509_free(x);
SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
return 0;
}
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if (!X509v3_cache_extensions(x, ctx->libctx, ctx->propq)) {
- SSLerr(0, ERR_LIB_X509);
- return 0;
- }
+
rv = ssl_security_cert(NULL, ctx, x, 0, 1);
if (rv != 1) {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv);
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
{
- int j;
+ int j = SSL_R_BAD_VALUE;
BIO *in;
int ret = 0;
- X509 *x = NULL;
+ X509 *x = NULL, *cert = NULL;
in = BIO_new(BIO_s_file());
if (in == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
goto end;
}
+ if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) {
+ SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+ x = X509_new_with_libctx(ctx->libctx, ctx->propq);
+ if (x == NULL) {
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
- x = d2i_X509_bio(in, NULL);
+ cert = d2i_X509_bio(in, &x);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
- x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else {
- SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
- goto end;
+ cert = PEM_read_bio_X509(in, &x, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
}
-
- if (x == NULL) {
+ if (cert == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j);
goto end;
}
X509 *x;
int ret;
- x = d2i_X509(NULL, &d, (long)len);
+ x = X509_new_with_libctx(ctx->libctx, ctx->propq);
if (x == NULL) {
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (d2i_X509(&x, &d, (long)len) == NULL) {
+ X509_free(x);
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
return 0;
}
X509 *x = NULL;
pem_password_cb *passwd_callback;
void *passwd_callback_userdata;
+ SSL_CTX *real_ctx = (ssl == NULL) ? ctx : ssl->ctx;
ERR_clear_error(); /* clear error stack for
* SSL_CTX_use_certificate() */
goto end;
}
- x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback,
- passwd_callback_userdata);
+ x = X509_new_with_libctx(real_ctx->libctx, real_ctx->propq);
if (x == NULL) {
+ SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+ if (PEM_read_bio_X509_AUX(in, &x, passwd_callback,
+ passwd_callback_userdata) == NULL) {
SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
goto end;
}
goto end;
}
- while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
- passwd_callback_userdata))
- != NULL) {
- if (ctx)
- r = SSL_CTX_add0_chain_cert(ctx, ca);
- else
- r = SSL_add0_chain_cert(ssl, ca);
- /*
- * Note that we must not free ca if it was successfully added to
- * the chain (while we must free the main certificate, since its
- * reference count is increased by SSL_CTX_use_certificate).
- */
- if (!r) {
- X509_free(ca);
- ret = 0;
+ while (1) {
+ ca = X509_new_with_libctx(real_ctx->libctx, real_ctx->propq);
+ if (ca == NULL) {
+ SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE);
goto end;
}
+ if (PEM_read_bio_X509(in, &ca, passwd_callback,
+ passwd_callback_userdata) != NULL) {
+ if (ctx)
+ r = SSL_CTX_add0_chain_cert(ctx, ca);
+ else
+ r = SSL_add0_chain_cert(ssl, ca);
+ /*
+ * Note that we must not free ca if it was successfully added to
+ * the chain (while we must free the main certificate, since its
+ * reference count is increased by SSL_CTX_use_certificate).
+ */
+ if (!r) {
+ X509_free(ca);
+ ret = 0;
+ goto end;
+ }
+ } else {
+ X509_free(ca);
+ break;
+ }
}
/* When the while loop ends, it's usually just EOF. */
err = ERR_peek_last_error();
int j;
int rv;
CERT *c = ssl != NULL ? ssl->cert : ctx->cert;
- SSL_CTX *actualctx = ssl == NULL ? ctx : ssl->ctx;
STACK_OF(X509) *dup_chain = NULL;
EVP_PKEY *pubkey = NULL;
- if (!X509v3_cache_extensions(x509, actualctx->libctx, actualctx->propq)) {
- SSLerr(0, ERR_R_X509_LIB);
- goto out;
- }
-
/* Do all security checks before anything else */
rv = ssl_security_cert(ssl, ctx, x509, 0, 1);
if (rv != 1) {
}
certstart = certbytes;
- x = d2i_X509(NULL, (const unsigned char **)&certbytes, cert_len);
+ x = X509_new_with_libctx(s->ctx->libctx, s->ctx->propq);
if (x == NULL) {
+ SSLfatal(s, SSL_AD_DECODE_ERROR,
+ SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+ SSLerr(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (d2i_X509(&x, (const unsigned char **)&certbytes,
+ cert_len) == NULL) {
SSLfatal(s, SSL_AD_BAD_CERTIFICATE,
SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_ASN1_LIB);
goto err;
}
+
if (certbytes != (certstart + cert_len)) {
SSLfatal(s, SSL_AD_DECODE_ERROR,
SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
}
certstart = certbytes;
- x = d2i_X509(NULL, (const unsigned char **)&certbytes, l);
+ x = X509_new_with_libctx(s->ctx->libctx, s->ctx->propq);
if (x == NULL) {
+ SSLfatal(s, SSL_AD_DECODE_ERROR,
+ SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (d2i_X509(&x, (const unsigned char **)&certbytes, l) == NULL) {
SSLfatal(s, SSL_AD_DECODE_ERROR,
SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB);
goto err;
}
+
if (certbytes != (certstart + l)) {
SSLfatal(s, SSL_AD_DECODE_ERROR,
SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
BIO_snprintf(test_app, sizeof(test_app), "test-%d", idx);
- test_ctx = SSL_TEST_CTX_create(conf, test_app);
+ test_ctx = SSL_TEST_CTX_create(conf, test_app, libctx);
if (!TEST_ptr(test_ctx))
goto err;
}
__owur static int parse_expected_ca_names(STACK_OF(X509_NAME) **pnames,
- const char *value)
+ const char *value, OPENSSL_CTX *libctx)
{
if (value == NULL)
return 0;
if (!strcmp(value, "empty"))
*pnames = sk_X509_NAME_new_null();
else
- *pnames = SSL_load_client_CA_file(value);
+ *pnames = SSL_load_client_CA_file_with_libctx(value, libctx, NULL);
return *pnames != NULL;
}
__owur static int parse_expected_server_ca_names(SSL_TEST_CTX *test_ctx,
const char *value)
{
- return parse_expected_ca_names(&test_ctx->expected_server_ca_names, value);
+ return parse_expected_ca_names(&test_ctx->expected_server_ca_names, value,
+ test_ctx->libctx);
}
__owur static int parse_expected_client_ca_names(SSL_TEST_CTX *test_ctx,
const char *value)
{
- return parse_expected_ca_names(&test_ctx->expected_client_ca_names, value);
+ return parse_expected_ca_names(&test_ctx->expected_client_ca_names, value,
+ test_ctx->libctx);
}
/* ExpectedCipher */
{ "SessionTicketAppData", &parse_server_session_ticket_app_data },
};
-SSL_TEST_CTX *SSL_TEST_CTX_new(void)
+SSL_TEST_CTX *SSL_TEST_CTX_new(OPENSSL_CTX *libctx)
{
SSL_TEST_CTX *ret;
/* The return code is checked by caller */
if ((ret = OPENSSL_zalloc(sizeof(*ret))) != NULL) {
+ ret->libctx = libctx;
ret->app_data_size = default_app_data_size;
ret->max_fragment_size = default_max_fragment_size;
}
void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
{
+ if (ctx == NULL)
+ return;
ssl_test_ctx_free_extra_data(ctx);
OPENSSL_free(ctx->expected_npn_protocol);
OPENSSL_free(ctx->expected_alpn_protocol);
return 1;
}
-SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
+SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section,
+ OPENSSL_CTX *libctx)
{
STACK_OF(CONF_VALUE) *sk_conf = NULL;
SSL_TEST_CTX *ctx = NULL;
size_t j;
if (!TEST_ptr(sk_conf = NCONF_get_section(conf, test_section))
- || !TEST_ptr(ctx = SSL_TEST_CTX_new()))
+ || !TEST_ptr(ctx = SSL_TEST_CTX_new(libctx)))
goto err;
for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
char *expected_cipher;
/* Expected Session Ticket Application Data */
char *expected_session_ticket_app_data;
+
+ OPENSSL_CTX *libctx;
} SSL_TEST_CTX;
const char *ssl_test_result_name(ssl_test_result_t result);
* Load the test case context from |conf|.
* See test/README.ssltest.md for details on the conf file format.
*/
-SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section);
+SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section,
+ OPENSSL_CTX *libctx);
-SSL_TEST_CTX *SSL_TEST_CTX_new(void);
+SSL_TEST_CTX *SSL_TEST_CTX_new(OPENSSL_CTX *libctx);
void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx);
if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
return NULL;
fixture->test_case_name = test_case_name;
- if (!TEST_ptr(fixture->expected_ctx = SSL_TEST_CTX_new())) {
+ if (!TEST_ptr(fixture->expected_ctx = SSL_TEST_CTX_new(NULL))) {
OPENSSL_free(fixture);
return NULL;
}
int success = 0;
SSL_TEST_CTX *ctx;
- if (!TEST_ptr(ctx = SSL_TEST_CTX_create(conf, fixture->test_section))
+ if (!TEST_ptr(ctx = SSL_TEST_CTX_create(conf, fixture->test_section,
+ fixture->expected_ctx->libctx))
|| !testctx_eq(ctx, fixture->expected_ctx))
goto err;
SSL_TEST_CTX *ctx;
if (!TEST_ptr_null(ctx = SSL_TEST_CTX_create(conf,
- bad_configurations[idx]))) {
+ bad_configurations[idx], NULL))) {
SSL_TEST_CTX_free(ctx);
return 0;
}
if (!TEST_ptr(certbio = BIO_new_file(cert, "r")))
goto end;
- chaincert = PEM_read_bio_X509(certbio, NULL, NULL, NULL);
+
+ if (!TEST_ptr(chaincert = X509_new_with_libctx(libctx, NULL)))
+ goto end;
+
+ if (PEM_read_bio_X509(certbio, &chaincert, NULL, NULL) == NULL)
+ goto end;
BIO_free(certbio);
certbio = NULL;
- if (!TEST_ptr(chaincert))
- goto end;
if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, min_version,
max_version, &sctx, &cctx, cert,
testresult = 1;
end:
+ BIO_free(certbio);
X509_free(chaincert);
SSL_free(serverssl);
SSL_free(clientssl);
if (!TEST_ptr(certbio = BIO_new_file(cert, "r"))
|| !TEST_ptr(id = OCSP_RESPID_new())
|| !TEST_ptr(ids = sk_OCSP_RESPID_new_null())
- || !TEST_ptr(ocspcert = PEM_read_bio_X509(certbio,
- NULL, NULL, NULL))
+ || !TEST_ptr(ocspcert = X509_new_with_libctx(libctx, NULL))
+ || !TEST_ptr(PEM_read_bio_X509(certbio, &ocspcert, NULL, NULL))
|| !TEST_true(OCSP_RESPID_set_by_key_ex(id, ocspcert, libctx, NULL))
|| !TEST_true(sk_OCSP_RESPID_push(ids, id)))
goto end;
goto out;
if (!TEST_ptr(in = BIO_new(BIO_s_file()))
|| !TEST_int_ge(BIO_read_filename(in, rootfile), 0)
- || !TEST_ptr(rootx = PEM_read_bio_X509(in, NULL, NULL, NULL))
+ || !TEST_ptr(rootx = X509_new_with_libctx(libctx, NULL))
+ || !TEST_ptr(PEM_read_bio_X509(in, &rootx, NULL, NULL))
|| !TEST_true(sk_X509_push(chain, rootx)))
goto out;
rootx = NULL;
BIO_free(in);
if (!TEST_ptr(in = BIO_new(BIO_s_file()))
|| !TEST_int_ge(BIO_read_filename(in, ecdsacert), 0)
- || !TEST_ptr(x509 = PEM_read_bio_X509(in, NULL, NULL, NULL)))
+ || !TEST_ptr(x509 = X509_new_with_libctx(libctx, NULL))
+ || !TEST_ptr(PEM_read_bio_X509(in, &x509, NULL, NULL)))
goto out;
BIO_free(in);
if (!TEST_ptr(in = BIO_new(BIO_s_file()))
X509 *xcert;
EVP_PKEY *privpkey;
BIO *in = NULL;
+ BIO *priv_in = NULL;
/* Check that SSL_get0_peer_certificate() returns something sensible */
if (!TEST_ptr(SSL_get0_peer_certificate(ssl)))
if (!TEST_ptr(in))
return 0;
- xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
- BIO_free(in);
- if (!TEST_ptr(xcert))
- return 0;
-
- in = BIO_new_file(privkey, "r");
- if (!TEST_ptr(in)) {
- X509_free(xcert);
- return 0;
- }
-
- privpkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
- BIO_free(in);
- if (!TEST_ptr(privpkey)) {
- X509_free(xcert);
- return 0;
- }
+ if (!TEST_ptr(xcert = X509_new_with_libctx(libctx, NULL))
+ || !TEST_ptr(PEM_read_bio_X509(in, &xcert, NULL, NULL))
+ || !TEST_ptr(priv_in = BIO_new_file(privkey, "r"))
+ || !TEST_ptr(privpkey = PEM_read_bio_PrivateKey(priv_in, NULL, NULL,
+ NULL)))
+ goto err;
*x509 = xcert;
*pkey = privpkey;
+ BIO_free(in);
+ BIO_free(priv_in);
return 1;
+err:
+ X509_free(xcert);
+ BIO_free(in);
+ BIO_free(priv_in);
+ return 0;
}
static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
SRP_Calc_u_ex ? 3_0_0 EXIST::FUNCTION:SRP
SRP_Calc_x_ex ? 3_0_0 EXIST::FUNCTION:SRP
SRP_Calc_client_key_ex ? 3_0_0 EXIST::FUNCTION:SRP
-X509v3_cache_extensions ? 3_0_0 EXIST::FUNCTION:
+X509v3_cache_extensions ? 3_0_0 NOEXIST::FUNCTION:
EVP_PKEY_gettable_params ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_get_int_param ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_get_size_t_param ? 3_0_0 EXIST::FUNCTION:
X509_VERIFY_PARAM_get0_host ? 3_0_0 EXIST::FUNCTION:
X509_VERIFY_PARAM_get0_email ? 3_0_0 EXIST::FUNCTION:
X509_VERIFY_PARAM_get1_ip_asc ? 3_0_0 EXIST::FUNCTION:
-X509_verify_ex ? 3_0_0 EXIST::FUNCTION:
-X509_REQ_verify_ex ? 3_0_0 EXIST::FUNCTION:
+X509_verify_ex ? 3_0_0 NOEXIST::FUNCTION:
+X509_REQ_verify_ex ? 3_0_0 NOEXIST::FUNCTION:
X509_ALGOR_copy ? 3_0_0 EXIST::FUNCTION:
X509_REQ_set0_signature ? 3_0_0 EXIST::FUNCTION:
X509_REQ_set1_signature_algo ? 3_0_0 EXIST::FUNCTION:
EC_KEY_new_with_libctx ? 3_0_0 EXIST::FUNCTION:EC
EC_KEY_new_by_curve_name_with_libctx ? 3_0_0 EXIST::FUNCTION:EC
OPENSSL_CTX_set0_default ? 3_0_0 EXIST::FUNCTION:
+PEM_X509_INFO_read_bio_with_libctx ? 3_0_0 EXIST::FUNCTION:
+PEM_X509_INFO_read_with_libctx ? 3_0_0 EXIST::FUNCTION:STDIO
+X509_REQ_verify_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_new_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_LOOKUP_ctrl_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_load_cert_file_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_load_cert_crl_file_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_LOOKUP_by_subject_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_STORE_load_file_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_STORE_load_store_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_STORE_load_locations_with_libctx ? 3_0_0 EXIST::FUNCTION:
+X509_STORE_set_default_paths_with_libctx ? 3_0_0 EXIST::FUNCTION:
+OSSL_STORE_open_with_libctx ? 3_0_0 EXIST::FUNCTION:
SSL_new_session_ticket ? 3_0_0 EXIST::FUNCTION:
SSL_get0_peer_certificate ? 3_0_0 EXIST::FUNCTION:
SSL_get1_peer_certificate ? 3_0_0 EXIST::FUNCTION:
+SSL_load_client_CA_file_with_libctx ? 3_0_0 EXIST::FUNCTION:
X509_http_nbio define
X509_LOOKUP_add_dir define
X509_LOOKUP_add_store define
+X509_LOOKUP_add_store_with_libctx define
X509_LOOKUP_load_file define
+X509_LOOKUP_load_file_with_libctx define
X509_LOOKUP_load_store define
+X509_LOOKUP_load_store_with_libctx define
X509_STORE_set_lookup_crls_cb define
X509_STORE_set_verify_func define
EVP_PKEY_CTX_set1_id define