mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
STORE 'file' scheme loader: add support for the PKCS#12 container
Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3542)
This commit is contained in:
parent
e61ec2d9ba
commit
a09003ea22
@ -750,6 +750,7 @@ OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT:117:ossl_store_register_loader_int
|
||||
OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT:116:\
|
||||
ossl_store_unregister_loader_int
|
||||
OSSL_STORE_F_TRY_DECODE_PARAMS:121:try_decode_params
|
||||
OSSL_STORE_F_TRY_DECODE_PKCS12:122:try_decode_PKCS12
|
||||
PEM_F_B2I_DSS:127:b2i_dss
|
||||
PEM_F_B2I_PVK_BIO:128:b2i_PVK_bio
|
||||
PEM_F_B2I_RSA:129:b2i_rsa
|
||||
@ -1977,6 +1978,7 @@ OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest
|
||||
OCSP_R_UNKNOWN_NID:120:unknown nid
|
||||
OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type
|
||||
OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type
|
||||
OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac
|
||||
OSSL_STORE_R_INVALID_SCHEME:106:invalid scheme
|
||||
OSSL_STORE_R_IS_NOT_A:112:is not a
|
||||
OSSL_STORE_R_NOT_A_CERTIFICATE:100:not a certificate
|
||||
@ -1984,6 +1986,7 @@ OSSL_STORE_R_NOT_A_CRL:101:not a crl
|
||||
OSSL_STORE_R_NOT_A_KEY:102:not a key
|
||||
OSSL_STORE_R_NOT_A_NAME:103:not a name
|
||||
OSSL_STORE_R_NOT_PARAMETERS:104:not parameters
|
||||
OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR:114:passphrase callback error
|
||||
OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE:108:path must be absolute
|
||||
OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED:109:\
|
||||
ui process interrupted or cancelled
|
||||
|
@ -157,6 +157,121 @@ typedef struct file_handler_st {
|
||||
int repeatable;
|
||||
} FILE_HANDLER;
|
||||
|
||||
static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
|
||||
const char *pem_header,
|
||||
const unsigned char *blob,
|
||||
size_t len, void **pctx,
|
||||
const UI_METHOD *ui_method,
|
||||
void *ui_data)
|
||||
{
|
||||
OSSL_STORE_INFO *store_info = NULL;
|
||||
STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;
|
||||
|
||||
if (ctx == NULL) {
|
||||
/* Initial parsing */
|
||||
PKCS12 *p12;
|
||||
int ok = 0;
|
||||
|
||||
if (pem_name != NULL)
|
||||
/* No match, there is no PEM PKCS12 tag */
|
||||
return NULL;
|
||||
|
||||
if ((p12 = d2i_PKCS12(NULL, &blob, len)) != NULL) {
|
||||
char *pass = NULL;
|
||||
char tpass[PEM_BUFSIZE];
|
||||
EVP_PKEY *pkey = NULL;
|
||||
X509 *cert = NULL;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
|
||||
if (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 password",
|
||||
ui_data)) == NULL) {
|
||||
OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12,
|
||||
OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR);
|
||||
goto p12_end;
|
||||
}
|
||||
if (!PKCS12_verify_mac(p12, pass, strlen(pass))) {
|
||||
OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12,
|
||||
OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC);
|
||||
goto p12_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) {
|
||||
OSSL_STORE_INFO *si_pkey = NULL;
|
||||
OSSL_STORE_INFO *si_cert = NULL;
|
||||
OSSL_STORE_INFO *si_ca = NULL;
|
||||
|
||||
if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL
|
||||
&& (si_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL
|
||||
&& sk_OSSL_STORE_INFO_push(ctx, si_pkey) != 0
|
||||
&& (si_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL
|
||||
&& sk_OSSL_STORE_INFO_push(ctx, si_cert) != 0) {
|
||||
ok = 1;
|
||||
si_pkey = NULL;
|
||||
si_cert = NULL;
|
||||
|
||||
while(sk_X509_num(chain) > 0) {
|
||||
X509 *ca = sk_X509_value(chain, 0);
|
||||
|
||||
if ((si_ca = OSSL_STORE_INFO_new_CERT(ca)) == NULL
|
||||
|| sk_OSSL_STORE_INFO_push(ctx, si_ca) == 0) {
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
si_ca = NULL;
|
||||
(void)sk_X509_shift(chain);
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
OSSL_STORE_INFO_free(si_ca);
|
||||
OSSL_STORE_INFO_free(si_cert);
|
||||
OSSL_STORE_INFO_free(si_pkey);
|
||||
sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free);
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(cert);
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
ctx = NULL;
|
||||
}
|
||||
*pctx = ctx;
|
||||
}
|
||||
}
|
||||
p12_end:
|
||||
PKCS12_free(p12);
|
||||
if (!ok)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx != NULL)
|
||||
store_info = sk_OSSL_STORE_INFO_shift(ctx);
|
||||
|
||||
return store_info;
|
||||
}
|
||||
static int eof_PKCS12(void *ctx_)
|
||||
{
|
||||
STACK_OF(OSSL_STORE_INFO) *ctx = ctx_;
|
||||
|
||||
return ctx == NULL || sk_OSSL_STORE_INFO_num(ctx) == 0;
|
||||
}
|
||||
static void destroy_ctx_PKCS12(void **pctx)
|
||||
{
|
||||
STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;
|
||||
|
||||
sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free);
|
||||
*pctx = NULL;
|
||||
}
|
||||
static FILE_HANDLER PKCS12_handler = {
|
||||
"PKCS12",
|
||||
try_decode_PKCS12,
|
||||
eof_PKCS12,
|
||||
destroy_ctx_PKCS12,
|
||||
1 /* repeatable */
|
||||
};
|
||||
|
||||
int pem_check_suffix(const char *pem_str, const char *suffix);
|
||||
static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
|
||||
const char *pem_header,
|
||||
@ -352,6 +467,7 @@ static FILE_HANDLER X509CRL_handler = {
|
||||
};
|
||||
|
||||
static const FILE_HANDLER *file_handlers[] = {
|
||||
&PKCS12_handler,
|
||||
&X509Certificate_handler,
|
||||
&X509CRL_handler,
|
||||
¶ms_handler,
|
||||
|
@ -57,12 +57,16 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
|
||||
"ossl_store_unregister_loader_int"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PARAMS, 0),
|
||||
"try_decode_params"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS12, 0),
|
||||
"try_decode_PKCS12"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE),
|
||||
"ambiguous content type"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC),
|
||||
"error verifying pkcs12 mac"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_INVALID_SCHEME),
|
||||
"invalid scheme"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_IS_NOT_A), "is not a"},
|
||||
@ -73,6 +77,8 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_NAME), "not a name"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_PARAMETERS),
|
||||
"not parameters"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR),
|
||||
"passphrase callback error"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE),
|
||||
"path must be absolute"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED),
|
||||
|
@ -45,11 +45,13 @@ int ERR_load_OSSL_STORE_strings(void);
|
||||
# define OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT 117
|
||||
# define OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT 116
|
||||
# define OSSL_STORE_F_TRY_DECODE_PARAMS 121
|
||||
# define OSSL_STORE_F_TRY_DECODE_PKCS12 122
|
||||
|
||||
/*
|
||||
* OSSL_STORE reason codes.
|
||||
*/
|
||||
# define OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE 107
|
||||
# define OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC 113
|
||||
# define OSSL_STORE_R_INVALID_SCHEME 106
|
||||
# define OSSL_STORE_R_IS_NOT_A 112
|
||||
# define OSSL_STORE_R_NOT_A_CERTIFICATE 100
|
||||
@ -57,6 +59,7 @@ int ERR_load_OSSL_STORE_strings(void);
|
||||
# define OSSL_STORE_R_NOT_A_KEY 102
|
||||
# define OSSL_STORE_R_NOT_A_NAME 103
|
||||
# define OSSL_STORE_R_NOT_PARAMETERS 104
|
||||
# define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114
|
||||
# define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108
|
||||
# define OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 109
|
||||
# define OSSL_STORE_R_UNREGISTERED_SCHEME 105
|
||||
|
Loading…
Reference in New Issue
Block a user