/*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2021 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
/* THIS ENGINE IS FOR TESTING PURPOSES ONLY. */
+/* This file has quite some overlap with providers/implementations/storemgmt/file_store.c */
+
/* We need to use some engine deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED
-/* #include "e_os.h" */
+#include "../e_os.h" /* for stat and strncasecmp */
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include <openssl/engine.h>
#include <openssl/x509.h> /* For the PKCS8 stuff o.O */
#include "internal/asn1.h" /* For asn1_d2i_read_bio */
-#include "internal/pem.h" /* For PVK and "blob" PEM headers */
#include "internal/o_dir.h"
#include "internal/cryptlib.h"
+#include "crypto/ctype.h" /* For ossl_isdigit */
+#include "crypto/pem.h" /* For PVK and "blob" PEM headers */
#include "e_loader_attic_err.c"
DEFINE_STACK_OF(OSSL_STORE_INFO)
-#ifdef _WIN32
-# define stat _stat
-# define strncasecmp _strnicmp
-#endif
-
#ifndef S_ISDIR
# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
#endif
return NULL;
}
+ data->blob = embedded;
data->pem_name =
new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
store_info_free(info);
info = NULL;
}
- data->blob = embedded;
return info;
}
int *matchcount,
const UI_METHOD *ui_method,
void *ui_data, const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq);
/*
* The eof function should return 1 if there's no more data to be found
int *matchcount,
const UI_METHOD *ui_method,
void *ui_data, const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
*matchcount = 1;
- if (PKCS12_verify_mac(p12, "", 0)
+ if (!PKCS12_mac_present(p12)
+ || PKCS12_verify_mac(p12, "", 0)
|| PKCS12_verify_mac(p12, NULL, 0)) {
pass = "";
} else {
if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE,
- "PKCS12 import pass phrase", uri,
+ "PKCS12 import", uri,
ui_data)) == NULL) {
ATTICerr(0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR);
goto p12_end;
const UI_METHOD *ui_method,
void *ui_data,
const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
X509_SIG *p8 = NULL;
mem->data = (char *)new_data;
mem->max = mem->length = (size_t)new_data_len;
X509_SIG_free(p8);
+ p8 = NULL;
store_info = new_EMBEDDED(PEM_STRING_PKCS8INF, mem);
if (store_info == NULL) {
int *matchcount,
const UI_METHOD *ui_method,
void *ui_data, const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
*matchcount = 1;
if (p8inf != NULL)
- pkey = EVP_PKCS82PKEY_with_libctx(p8inf, libctx, propq);
+ pkey = EVP_PKCS82PKEY_ex(p8inf, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8inf);
} else {
int slen;
int *matchcount,
const UI_METHOD *ui_method,
void *ui_data, const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
int *matchcount,
const UI_METHOD *ui_method,
void *ui_data, const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
const UI_METHOD *ui_method,
void *ui_data,
const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
*matchcount = 1;
}
- cert = X509_new_with_libctx(libctx, propq);
+ cert = X509_new_ex(libctx, propq);
if (cert == NULL)
return NULL;
int *matchcount,
const UI_METHOD *ui_method,
void *ui_data, const char *uri,
- OPENSSL_CTX *libctx,
+ OSSL_LIB_CTX *libctx,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
/* Expected object type. May be unspecified */
int expected_type;
- OPENSSL_CTX *libctx;
+ OSSL_LIB_CTX *libctx;
char *propq;
};
return 1;
}
-static OSSL_STORE_LOADER_CTX *file_open_with_libctx
+static OSSL_STORE_LOADER_CTX *file_open_ex
(const OSSL_STORE_LOADER *loader, const char *uri,
- OPENSSL_CTX *libctx, const char *propq,
+ OSSL_LIB_CTX *libctx, const char *propq,
const UI_METHOD *ui_method, void *ui_data)
{
OSSL_STORE_LOADER_CTX *ctx = NULL;
unsigned int check_absolute:1;
} path_data[2];
size_t path_data_n = 0, i;
- const char *path;
+ const char *path, *p = uri, *q;
/*
* First step, just take the URI as is.
path_data[path_data_n++].path = uri;
/*
- * Second step, if the URI appears to start with the 'file' scheme,
+ * Second step, if the URI appears to start with the "file" scheme,
* extract the path and make that the second path to check.
* There's a special case if the URI also contains an authority, then
* the full URI shouldn't be used as a path anywhere.
*/
- if (strncasecmp(uri, "file:", 5) == 0) {
- const char *p = &uri[5];
-
- if (strncmp(&uri[5], "//", 2) == 0) {
+ if (CHECK_AND_SKIP_CASE_PREFIX(p, "file:")) {
+ q = p;
+ if (CHECK_AND_SKIP_PREFIX(q, "//")) {
path_data_n--; /* Invalidate using the full URI */
- if (strncasecmp(&uri[7], "localhost/", 10) == 0) {
- p = &uri[16];
- } else if (uri[7] == '/') {
- p = &uri[7];
+ if (CHECK_AND_SKIP_CASE_PREFIX(q, "localhost/")
+ || CHECK_AND_SKIP_PREFIX(q, "/")) {
+ p = q - 1;
} else {
ATTICerr(0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED);
return NULL;
path_data[path_data_n].check_absolute = 1;
#ifdef _WIN32
- /* Windows file: URIs with a drive letter start with a / */
+ /* Windows "file:" URIs with a drive letter start with a '/' */
if (p[0] == '/' && p[2] == ':' && p[3] == '/') {
char c = tolower(p[1]);
(const OSSL_STORE_LOADER *loader, const char *uri,
const UI_METHOD *ui_method, void *ui_data)
{
- return file_open_with_libctx(loader, uri, NULL, NULL, ui_method, ui_data);
+ return file_open_ex(loader, uri, NULL, NULL, ui_method, ui_data);
}
static OSSL_STORE_LOADER_CTX *file_attach
(const OSSL_STORE_LOADER *loader, BIO *bp,
- OPENSSL_CTX *libctx, const char *propq,
+ OSSL_LIB_CTX *libctx, const char *propq,
const UI_METHOD *ui_method, void *ui_data)
{
OSSL_STORE_LOADER_CTX *ctx = NULL;
return 0;
}
- hash = X509_NAME_hash(OSSL_STORE_SEARCH_get0_name(search));
+ hash = X509_NAME_hash_ex(OSSL_STORE_SEARCH_get0_name(search),
+ NULL, NULL, NULL);
BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name),
"%08lx", hash);
return 1;
}
if (result == NULL)
result = tmp_result;
+ if (result == NULL) /* e.g., PKCS#12 file decryption error */
+ break;
}
}
- if (*matchcount == 1 && matching_handlers[0]->repeatable) {
+ if (result != NULL
+ && *matchcount == 1 && matching_handlers[0]->repeatable) {
ctx->_.file.last_handler = matching_handlers[0];
ctx->_.file.last_handler_ctx = handler_ctx;
}
static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount)
{
-#ifdef OPENSSL_NO_DSA
- return NULL;
-#else
OSSL_STORE_INFO *result = NULL;
int ispub = -1;
}
return result;
-#endif
}
static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method,
void *ui_data, const char *uri,
int *matchcount)
{
-#if defined(OPENSSL_NO_DSA) || defined(OPENSSL_NO_RC4)
- return NULL;
-#else
OSSL_STORE_INFO *result = NULL;
{
}
return result;
-#endif
}
static int file_read_asn1(BIO *bp, unsigned char **data, long *len)
return 1;
}
-static int ends_with_dirsep(const char *uri)
-{
- if (*uri != '\0')
- uri += strlen(uri) - 1;
-#if defined(__VMS)
- if (*uri == ']' || *uri == '>' || *uri == ':')
- return 1;
-#elif defined(_WIN32)
- if (*uri == '\\')
- return 1;
-#endif
- return *uri == '/';
-}
-
static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name,
char **data)
{
assert(name != NULL);
assert(data != NULL);
{
- const char *pathsep = ends_with_dirsep(ctx->uri) ? "" : "/";
+ const char *pathsep = ossl_ends_with_dirsep(ctx->uri) ? "" : "/";
long calculated_length = strlen(ctx->uri) + strlen(pathsep)
+ strlen(name) + 1 /* \0 */;
static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name)
{
const char *p = NULL;
+ size_t len = strlen(ctx->_.dir.search_name);
/* If there are no search criteria, all names are accepted */
if (ctx->_.dir.search_name[0] == '\0')
/*
* First, check the basename
*/
- if (strncasecmp(name, ctx->_.dir.search_name,
- sizeof(ctx->_.dir.search_name) - 1) != 0
- || name[sizeof(ctx->_.dir.search_name) - 1] != '.')
+ if (strncasecmp(name, ctx->_.dir.search_name, len) != 0 || name[len] != '.')
return 0;
- p = &name[sizeof(ctx->_.dir.search_name)];
+ p = &name[len + 1];
/*
* Then, if the expected type is a CRL, check that the extension starts
static int bind_loader_attic(ENGINE *e)
{
- /* Ensure the ATTIC error handdling is set up on best effort basis */
+ /* Ensure the ATTIC error handling is set up on best effort basis */
ERR_load_ATTIC_strings();
if (/* Create the OSSL_STORE_LOADER */
(loader_attic = OSSL_STORE_LOADER_new(e, "file")) == NULL
- || !OSSL_STORE_LOADER_set_open_with_libctx(loader_attic,
- file_open_with_libctx)
+ || !OSSL_STORE_LOADER_set_open_ex(loader_attic, file_open_ex)
|| !OSSL_STORE_LOADER_set_open(loader_attic, file_open)
|| !OSSL_STORE_LOADER_set_attach(loader_attic, file_attach)
|| !OSSL_STORE_LOADER_set_ctrl(loader_attic, file_ctrl)