/*
- * Copyright 2016-2018 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
#include "internal/o_dir.h"
#include "internal/cryptlib.h"
#include "crypto/store.h"
+#include "crypto/evp.h"
#include "store_local.h"
+DEFINE_STACK_OF(X509)
+
#ifdef _WIN32
# define stat _stat
#endif
* or any other interactive data.
* ui_data: Application data to be passed to ui_method when
* it's called.
+ * libctx: The library context to be used if applicable
+ * propq: The property query string for any algorithm fetches
* Output:
* a OSSL_STORE_INFO
*/
size_t len, void **handler_ctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data);
+ void *ui_data,
+ OPENSSL_CTX *libctx,
+ const char *propq);
/*
* The eof function should return 1 if there's no more data to be found
* with the handler_ctx, otherwise 0. This is only used when the handler is
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data, OPENSSL_CTX *libctx,
+ const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data,
+ OPENSSL_CTX *libctx,
+ const char *propq)
{
X509_SIG *p8 = NULL;
char kbuf[PEM_BUFSIZE];
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data, OPENSSL_CTX *libctx,
+ const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
EVP_PKEY *pkey = NULL;
*matchcount = 1;
if (p8inf != NULL)
- pkey = EVP_PKCS82PKEY(p8inf);
+ pkey = evp_pkcs82pkey_int(p8inf, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8inf);
} else {
int slen;
&& (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
slen)) != NULL) {
*matchcount = 1;
- pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
+ pkey = d2i_PrivateKey_ex(ameth->pkey_id, NULL, &blob, len,
+ libctx, propq);
}
}
} else {
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
continue;
- tmp_pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &tmp_blob, len);
+ tmp_pkey = d2i_PrivateKey_ex(ameth->pkey_id, NULL, &tmp_blob, len,
+ libctx, propq);
if (tmp_pkey != NULL) {
if (pkey != NULL)
EVP_PKEY_free(tmp_pkey);
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data, OPENSSL_CTX *libctx,
+ const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
EVP_PKEY *pkey = NULL;
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data, OPENSSL_CTX *libctx,
+ const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
int slen = 0;
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data,
+ OPENSSL_CTX *libctx,
+ const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
X509 *cert = NULL;
size_t len, void **pctx,
int *matchcount,
const UI_METHOD *ui_method,
- void *ui_data)
+ void *ui_data, OPENSSL_CTX *libctx,
+ const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
X509_CRL *crl = NULL;
} type;
int errcnt;
#define FILE_FLAG_SECMEM (1<<0)
+#define FILE_FLAG_ATTACHED (1<<1)
unsigned int flags;
union {
struct { /* Used with is_raw and is_pem */
/* Expected object type. May be unspecified */
int expected_type;
+
+ OPENSSL_CTX *libctx;
+ char *propq;
};
static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx)
ctx->_.file.last_handler = NULL;
}
}
+ OPENSSL_free(ctx->propq);
OPENSSL_free(ctx);
}
+static int file_find_type(OSSL_STORE_LOADER_CTX *ctx)
+{
+ BIO *buff = NULL;
+ char peekbuf[4096] = { 0, };
+
+ if ((buff = BIO_new(BIO_f_buffer())) == NULL)
+ return 0;
+
+ ctx->_.file.file = BIO_push(buff, ctx->_.file.file);
+ if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) {
+ peekbuf[sizeof(peekbuf) - 1] = '\0';
+ if (strstr(peekbuf, "-----BEGIN ") != NULL)
+ ctx->type = is_pem;
+ }
+ return 1;
+}
+
static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
const char *uri,
const UI_METHOD *ui_method,
}
ctx->_.dir.end_reached = 1;
}
- } else {
- BIO *buff = NULL;
- char peekbuf[4096] = { 0, };
-
- if ((buff = BIO_new(BIO_f_buffer())) == NULL
- || (ctx->_.file.file = BIO_new_file(path, "rb")) == NULL) {
- BIO_free_all(buff);
- goto err;
- }
-
- ctx->_.file.file = BIO_push(buff, ctx->_.file.file);
- if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) {
- peekbuf[sizeof(peekbuf) - 1] = '\0';
- if (strstr(peekbuf, "-----BEGIN ") != NULL)
- ctx->type = is_pem;
- }
+ } else if ((ctx->_.file.file = BIO_new_file(path, "rb")) == NULL
+ || !file_find_type(ctx)) {
+ BIO_free_all(ctx->_.file.file);
+ goto err;
}
return 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;
+
+ 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;
+ }
+
+ 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;
+ }
+
+ return ctx;
+}
+
static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
{
int ret = 1;
return 0;
}
-/* Internal function to decode an already opened PEM file */
-OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp)
-{
- OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
- if (ctx == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT,
- ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- ctx->_.file.file = bp;
- ctx->type = is_pem;
-
- return ctx;
-}
-
static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
const char *pem_name,
const char *pem_header,
OSSL_STORE_INFO *tmp_result =
handler->try_decode(pem_name, pem_header, data, len,
&tmp_handler_ctx, &try_matchcount,
- ui_method, ui_data);
+ ui_method, ui_data, ctx->libctx, ctx->propq);
if (try_matchcount > 0) {
ctx->_.file.last_handler->try_decode(NULL, NULL, NULL, 0,
&ctx->_.file.last_handler_ctx,
&try_matchcount,
- ui_method, ui_data);
+ ui_method, ui_data,
+ ctx->libctx, ctx->propq);
if (result == NULL) {
ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx);
static int file_close(OSSL_STORE_LOADER_CTX *ctx)
{
- if (ctx->type == is_dir) {
- OPENSSL_DIR_end(&ctx->_.dir.ctx);
+ if ((ctx->flags & FILE_FLAG_ATTACHED) == 0) {
+ if (ctx->type == is_dir)
+ OPENSSL_DIR_end(&ctx->_.dir.ctx);
+ else
+ BIO_free_all(ctx->_.file.file);
} else {
- BIO_free_all(ctx->_.file.file);
- }
- OSSL_STORE_LOADER_CTX_free(ctx);
- return 1;
-}
+ /*
+ * Because file_attach() called file_find_type(), we know that a
+ * BIO_f_buffer() has been pushed on top of the regular BIO.
+ */
+ BIO *buff = ctx->_.file.file;
-int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx)
-{
+ /* Detach buff */
+ (void)BIO_pop(ctx->_.file.file);
+ /* Safety measure */
+ ctx->_.file.file = NULL;
+
+ BIO_free(buff);
+ }
OSSL_STORE_LOADER_CTX_free(ctx);
return 1;
}
"file",
NULL,
file_open,
+ file_attach,
file_ctrl,
file_expect,
file_find,