Add library context and property query support into the PKCS12 API

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14434)
This commit is contained in:
Jon Spillett 2021-02-17 17:56:36 +10:00 committed by Pauli
parent d77ba503a2
commit b536880c45
50 changed files with 2309 additions and 345 deletions

View File

@ -46,6 +46,27 @@ OpenSSL 3.0
*Shane Lontis*
* Added enhanced PKCS#12 APIs which accept a library context `OSSL_LIB_CTX`
and (where relevant) a property query. Other APIs which handle PKCS#7 and
PKCS#8 objects have also been enhanced where required. This includes:
PKCS12_add_key_ex(), PKCS12_add_safe_ex(), PKCS12_add_safes_ex(),
PKCS12_create_ex(), PKCS12_decrypt_skey_ex(), PKCS12_init_ex(),
PKCS12_item_decrypt_d2i_ex(), PKCS12_item_i2d_encrypt_ex(),
PKCS12_key_gen_asc_ex(), PKCS12_key_gen_uni_ex(), PKCS12_key_gen_utf8_ex(),
PKCS12_pack_p7encdata_ex(), PKCS12_pbe_crypt_ex(), PKCS12_PBE_keyivgen_ex(),
PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(), PKCS5_pbe2_set_iv_ex(),
PKCS5_pbe_set0_algor_ex(), PKCS5_pbe_set_ex(), PKCS5_pbkdf2_set_ex(),
PKCS5_v2_PBE_keyivgen_ex(), PKCS5_v2_scrypt_keyivgen_ex(),
PKCS8_decrypt_ex(), PKCS8_encrypt_ex(), PKCS8_set0_pbe_ex().
As part of this change the EVP_PBE_xxx APIs can also accept a library
context and property query and will call an extended version of the key/IV
derivation function which supports these parameters. This includes
EVP_PBE_CipherInit_ex(), EVP_PBE_find_ex() and EVP_PBE_scrypt_ex().
*Jon Spillett*
* The default manual page suffix ($MANSUFFIX) has been changed to "ossl"
*Matt Caswell*

View File

@ -18,10 +18,7 @@ $OPENSSLSRC=\
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \
s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \
spkac.c verify.c version.c x509.c rehash.c storeutl.c \
list.c info.c fipsinstall.c
IF[{- !$disabled{'des'} -}]
$OPENSSLSRC=$OPENSSLSRC pkcs12.c
ENDIF
list.c info.c fipsinstall.c pkcs12.c
IF[{- !$disabled{'ec'} -}]
$OPENSSLSRC=$OPENSSLSRC ec.c ecparam.c
ENDIF

View File

@ -58,13 +58,19 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS,
OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER,
OPT_DESCERT, OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
#ifndef OPENSSL_NO_DES
OPT_DESCERT,
#endif
OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS,
OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
OPT_R_ENUM, OPT_PROV_ENUM, OPT_LEGACY_ALG
OPT_R_ENUM, OPT_PROV_ENUM,
#ifndef OPENSSL_NO_DES
OPT_LEGACY_ALG
#endif
} OPTION_CHOICE;
const OPTIONS pkcs12_options[] = {
@ -79,13 +85,15 @@ const OPTIONS pkcs12_options[] = {
{"nokeys", OPT_NOKEYS, '-', "Don't output private keys"},
{"nocerts", OPT_NOCERTS, '-', "Don't output certificates"},
{"noout", OPT_NOOUT, '-', "Don't output anything, just verify PKCS#12 input"},
#ifndef OPENSSL_NO_DES
{"legacy", OPT_LEGACY_ALG, '-',
#ifdef OPENSSL_NO_RC2
# ifdef OPENSSL_NO_RC2
"Use legacy encryption algorithm 3DES_CBC for keys and certs"
#else
# else
"Use legacy encryption: 3DES_CBC for keys, RC2_CBC for certs"
#endif
# endif
},
#endif
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
@ -130,8 +138,10 @@ const OPTIONS pkcs12_options[] = {
{"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default AES-256 CBC)"},
{"certpbe", OPT_CERTPBE, 's',
"Certificate PBE algorithm (default PBES2 with PBKDF2 and AES-256 CBC)"},
#ifndef OPENSSL_NO_DES
{"descert", OPT_DESCERT, '-',
"Encrypt output with 3DES (default PBES2 with PBKDF2 and AES-256 CBC)"},
#endif
{"macalg", OPT_MACALG, 's',
"Digest algorithm to use in MAC (default SHA1)"},
{"iter", OPT_ITER, 'p', "Specify the iteration count for encryption and MAC"},
@ -149,7 +159,10 @@ int pkcs12_main(int argc, char **argv)
char *passcertsarg = NULL, *passcerts = NULL;
char *name = NULL, *csp_name = NULL;
char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0, use_legacy = 0;
int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
#ifndef OPENSSL_NO_DES
int use_legacy = 0;
#endif
/* use library defaults for the iter, maciter, cert, and key PBE */
int iter = 0, maciter = 0;
int cert_pbe = NID_undef;
@ -214,9 +227,11 @@ int pkcs12_main(int argc, char **argv)
case OPT_NOMACVER:
macver = 0;
break;
#ifndef OPENSSL_NO_DES
case OPT_DESCERT:
cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
break;
#endif
case OPT_EXPORT:
export_pkcs12 = 1;
break;
@ -328,9 +343,11 @@ int pkcs12_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
#ifndef OPENSSL_NO_DES
case OPT_LEGACY_ALG:
use_legacy = 1;
break;
#endif
case OPT_PROV_CASES:
if (!opt_provider(o))
goto end;
@ -410,6 +427,7 @@ int pkcs12_main(int argc, char **argv)
if (cert_pbe == -1 && maciter == -1)
WARN_NO_EXPORT("nomac");
}
#ifndef OPENSSL_NO_DES
if (use_legacy) {
/* load the legacy provider if not loaded already*/
if (!OSSL_PROVIDER_available(app_get0_libctx(), "legacy")) {
@ -421,11 +439,11 @@ int pkcs12_main(int argc, char **argv)
}
if (cert_pbe == NID_undef) {
/* Adapt default algorithm */
#ifndef OPENSSL_NO_RC2
# ifndef OPENSSL_NO_RC2
cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
#else
# else
cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
#endif
# endif
}
if (key_pbe == NID_undef)
@ -435,7 +453,7 @@ int pkcs12_main(int argc, char **argv)
if (macalg == NULL)
macalg = "sha1";
}
#endif
private = 1;
@ -643,8 +661,9 @@ int pkcs12_main(int argc, char **argv)
if (!twopass)
OPENSSL_strlcpy(macpass, pass, sizeof(macpass));
p12 = PKCS12_create(cpass, name, key, ee_cert, certs,
key_pbe, cert_pbe, iter, -1, keytype);
p12 = PKCS12_create_ex(cpass, name, key, ee_cert, certs,
key_pbe, cert_pbe, iter, -1, keytype,
app_get0_libctx(), app_get0_propq());
if (p12 == NULL) {
BIO_printf(bio_err, "Error creating PKCS12 structure for %s\n",
@ -694,7 +713,12 @@ int pkcs12_main(int argc, char **argv)
if (out == NULL)
goto end;
if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) {
p12 = PKCS12_init_ex(NID_pkcs7_data, app_get0_libctx(), app_get0_propq());
if (p12 == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if ((p12 = d2i_PKCS12_bio(in, &p12)) == NULL) {
ERR_print_errors(bio_err);
goto end;
}

View File

@ -98,7 +98,6 @@ EOF
gendh => "dh",
dhparam => "dh",
ecparam => "ec",
pkcs12 => "des",
);
my %cmd_deprecated = (
# The format of this table is:

View File

@ -24,8 +24,9 @@ IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen)
int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *ctx)
{
PBEPARAM *pbe = NULL;
ASN1_STRING *pbe_str = NULL;
@ -54,7 +55,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
}
if (salt)
memcpy(sstr, salt, saltlen);
else if (RAND_bytes(sstr, saltlen) <= 0)
else if (RAND_bytes_ex(ctx, sstr, saltlen) <= 0)
goto err;
ASN1_STRING_set0(pbe->salt, sstr, saltlen);
@ -78,10 +79,17 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
return 0;
}
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen)
{
return PKCS5_pbe_set0_algor_ex(algor, alg, iter, salt, saltlen, NULL);
}
/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen)
X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *ctx)
{
X509_ALGOR *ret;
ret = X509_ALGOR_new();
@ -90,9 +98,16 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
return NULL;
}
if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
if (PKCS5_pbe_set0_algor_ex(ret, alg, iter, salt, saltlen, ctx))
return ret;
X509_ALGOR_free(ret);
return NULL;
}
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen)
{
return PKCS5_pbe_set_ex(alg, iter, salt, saltlen, NULL);
}

View File

@ -10,6 +10,8 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/core.h>
#include <openssl/core_names.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
@ -37,9 +39,10 @@ IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
* and IV.
*/
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid)
X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid,
OSSL_LIB_CTX *libctx)
{
X509_ALGOR *scheme = NULL, *ret = NULL;
int alg_nid, keylen;
@ -66,7 +69,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
if (EVP_CIPHER_iv_length(cipher)) {
if (aiv)
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
else if (RAND_bytes_ex(libctx, iv, EVP_CIPHER_iv_length(cipher)) <= 0)
goto err;
}
@ -104,7 +107,8 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
X509_ALGOR_free(pbe2->keyfunc);
pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
pbe2->keyfunc = PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen,
libctx);
if (pbe2->keyfunc == NULL)
goto merr;
@ -139,14 +143,25 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
return NULL;
}
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid)
{
return PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, aiv, prf_nid,
NULL);
}
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen)
{
return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
return PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, -1,
NULL);
}
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen)
X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen,
OSSL_LIB_CTX *libctx)
{
X509_ALGOR *keyfunc = NULL;
PBKDF2PARAM *kdf = NULL;
@ -171,7 +186,7 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
if (salt)
memcpy(osalt->data, salt, saltlen);
else if (RAND_bytes(osalt->data, saltlen) <= 0)
else if (RAND_bytes_ex(libctx, osalt->data, saltlen) <= 0)
goto merr;
if (iter <= 0)
@ -220,3 +235,10 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
X509_ALGOR_free(keyfunc);
return NULL;
}
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen)
{
return PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen, NULL);
}

View File

@ -10,10 +10,12 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
#include "crypto/evp.h"
#ifndef OPENSSL_NO_SCRYPT
/* PKCS#5 scrypt password based encryption structures */
@ -206,9 +208,10 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
return NULL;
}
int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de)
int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq)
{
unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
uint64_t p, r, N;
@ -252,7 +255,8 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0
|| ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0
|| ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0
|| EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
|| EVP_PBE_scrypt_ex(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0,
libctx, propq) == 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS);
goto err;
}
@ -261,8 +265,8 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
salt = sparam->salt->data;
saltlen = sparam->salt->length;
if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen)
== 0)
if (EVP_PBE_scrypt_ex(pass, passlen, salt, saltlen, N, r, p, 0, key,
keylen, libctx, propq) == 0)
goto err;
rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
err:
@ -271,4 +275,12 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
SCRYPT_PARAMS_free(sparam);
return rv;
}
int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de)
{
return PKCS5_v2_scrypt_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, NULL, NULL);
}
#endif /* OPENSSL_NO_SCRYPT */

View File

@ -217,6 +217,10 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md,
int en_de);
int PKCS5_v2_PBKDF2_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md,
int en_de, OSSL_LIB_CTX *libctx, const char *propq);
struct evp_Encode_Ctx_st {
/* number saved in a partial encode/decode */

View File

@ -10,6 +10,8 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/core.h>
#include <openssl/core_names.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include "crypto/evp.h"
@ -25,41 +27,42 @@ struct evp_pbe_st {
int cipher_nid;
int md_nid;
EVP_PBE_KEYGEN *keygen;
EVP_PBE_KEYGEN_EX *keygen_ex;
};
static STACK_OF(EVP_PBE_CTL) *pbe_algs;
static const EVP_PBE_CTL builtin_pbe[] = {
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen, NULL},
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen, NULL},
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen, NULL},
{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
NID_rc4, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen, &PKCS5_v2_PBE_keyivgen_ex},
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen, NULL},
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen, NULL},
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen, NULL},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
{EVP_PBE_TYPE_PRF, NID_hmac_md5, -1, NID_md5, 0},
@ -76,22 +79,27 @@ static const EVP_PBE_CTL builtin_pbe[] = {
NID_id_GostR3411_2012_512, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_224, -1, NID_sha512_224, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_256, -1, NID_sha512_256, 0},
{EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
{EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen, &PKCS5_v2_PBKDF2_keyivgen_ex},
#ifndef OPENSSL_NO_SCRYPT
{EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen}
{EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen, &PKCS5_v2_scrypt_keyivgen_ex}
#endif
};
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
int EVP_PBE_CipherInit_ex(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de,
OSSL_LIB_CTX *libctx, const char *propq)
{
const EVP_CIPHER *cipher;
const EVP_MD *md;
int cipher_nid, md_nid;
const EVP_CIPHER *cipher = NULL;
EVP_CIPHER *cipher_fetch = NULL;
const EVP_MD *md = NULL;
EVP_MD *md_fetch = NULL;
int ret = 0, cipher_nid, md_nid;
EVP_PBE_KEYGEN_EX *keygen_ex;
EVP_PBE_KEYGEN *keygen;
if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
&cipher_nid, &md_nid, &keygen)) {
if (!EVP_PBE_find_ex(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
&cipher_nid, &md_nid, &keygen, &keygen_ex)) {
char obj_tmp[80];
if (pbe_obj == NULL)
@ -100,7 +108,7 @@ int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), pbe_obj);
ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM,
"TYPE=%s", obj_tmp);
return 0;
goto err;
}
if (pass == NULL)
@ -108,28 +116,48 @@ int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
else if (passlen == -1)
passlen = strlen(pass);
if (cipher_nid == -1)
cipher = NULL;
else {
cipher = EVP_get_cipherbynid(cipher_nid);
if (!cipher) {
if (cipher_nid != -1) {
cipher = cipher_fetch = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(cipher_nid), propq);
/* Fallback to legacy method */
if (cipher == NULL)
cipher = EVP_get_cipherbynid(cipher_nid);
if (cipher == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER,
OBJ_nid2sn(cipher_nid));
return 0;
goto err;
}
}
if (md_nid == -1)
md = NULL;
else {
md = EVP_get_digestbynid(md_nid);
if (!md) {
if (md_nid != -1) {
md = md_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(md_nid), propq);
/* Fallback to legacy method */
if (md == NULL)
EVP_get_digestbynid(md_nid);
if (md == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST);
return 0;
goto err;
}
}
return keygen(ctx, pass, passlen, param, cipher, md, en_de);
/* Try extended keygen with libctx/propq first, fall back to legacy keygen */
if (keygen_ex != NULL)
ret = keygen_ex(ctx, pass, passlen, param, cipher, md, en_de, libctx, propq);
else
ret = keygen(ctx, pass, passlen, param, cipher, md, en_de);
err:
EVP_CIPHER_free(cipher_fetch);
EVP_MD_free(md_fetch);
return ret;
}
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
{
return EVP_PBE_CipherInit_ex(pbe_obj, pass, passlen, param, ctx, en_de, NULL, NULL);
}
DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
@ -205,8 +233,8 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
cipher_nid, md_nid, keygen);
}
int EVP_PBE_find(int type, int pbe_nid,
int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid,
EVP_PBE_KEYGEN **pkeygen, EVP_PBE_KEYGEN_EX **pkeygen_ex)
{
EVP_PBE_CTL *pbetmp = NULL, pbelu;
int i;
@ -225,15 +253,23 @@ int EVP_PBE_find(int type, int pbe_nid,
}
if (pbetmp == NULL)
return 0;
if (pcnid)
if (pcnid != NULL)
*pcnid = pbetmp->cipher_nid;
if (pmnid)
if (pmnid != NULL)
*pmnid = pbetmp->md_nid;
if (pkeygen)
if (pkeygen != NULL)
*pkeygen = pbetmp->keygen;
if (pkeygen_ex != NULL)
*pkeygen_ex = pbetmp->keygen_ex;
return 1;
}
int EVP_PBE_find(int type, int pbe_nid,
int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
{
return EVP_PBE_find_ex(type, pbe_nid, pcnid, pmnid, pkeygen, NULL);
}
static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
{
OPENSSL_free(pbe);

View File

@ -21,8 +21,7 @@
int ossl_pkcs5_pbkdf2_hmac_ex(const char *pass, int passlen,
const unsigned char *salt, int saltlen, int iter,
const EVP_MD *digest, int keylen,
unsigned char *out,
const EVP_MD *digest, int keylen, unsigned char *out,
OSSL_LIB_CTX *libctx, const char *propq)
{
const char *empty = "";
@ -108,13 +107,16 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
* them...
*/
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c,
const EVP_MD *md, int en_de)
int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c,
const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq)
{
PBE2PARAM *pbe2 = NULL;
const EVP_CIPHER *cipher;
EVP_PBE_KEYGEN *kdf;
char ciph_name[80];
const EVP_CIPHER *cipher = NULL;
EVP_CIPHER *cipher_fetch = NULL;
EVP_PBE_KEYGEN_EX *kdf;
int rv = 0;
@ -125,8 +127,8 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
}
/* See if we recognise the key derivation function */
if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
NULL, NULL, &kdf)) {
if (!EVP_PBE_find_ex(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
NULL, NULL, NULL, &kdf)) {
ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
goto err;
}
@ -134,10 +136,17 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
/*
* lets see if we recognise the encryption algorithm.
*/
if (OBJ_obj2txt(ciph_name, sizeof(ciph_name), pbe2->encryption->algorithm, 0) <= 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER);
goto err;
}
cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
cipher = cipher_fetch = EVP_CIPHER_fetch(libctx, ciph_name, propq);
/* Fallback to legacy method */
if (cipher == NULL)
cipher = EVP_get_cipherbyname(ciph_name);
if (!cipher) {
if (cipher == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER);
goto err;
}
@ -149,15 +158,24 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ERR_raise(ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR);
goto err;
}
rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de);
rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de, libctx, propq);
err:
EVP_CIPHER_free(cipher_fetch);
PBE2PARAM_free(pbe2);
return rv;
}
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de)
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c,
const EVP_MD *md, int en_de)
{
return PKCS5_v2_PBE_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, NULL, NULL);
}
int PKCS5_v2_PBKDF2_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq)
{
unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
int saltlen, iter, t;
@ -165,7 +183,8 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
unsigned int keylen = 0;
int prf_nid, hmac_md_nid;
PBKDF2PARAM *kdf = NULL;
const EVP_MD *prfmd;
const EVP_MD *prfmd = NULL;
EVP_MD *prfmd_fetch = NULL;
if (EVP_CIPHER_CTX_get0_cipher(ctx) == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
@ -207,7 +226,9 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
goto err;
}
prfmd = EVP_get_digestbynid(hmac_md_nid);
prfmd = prfmd_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(hmac_md_nid), propq);
if (prfmd == NULL)
prfmd = EVP_get_digestbynid(hmac_md_nid);
if (prfmd == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF);
goto err;
@ -222,12 +243,21 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
salt = kdf->salt->value.octet_string->data;
saltlen = kdf->salt->value.octet_string->length;
iter = ASN1_INTEGER_get(kdf->iter);
if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
keylen, key))
if (!ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, prfmd,
keylen, key, libctx, propq))
goto err;
rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
err:
OPENSSL_cleanse(key, keylen);
PBKDF2PARAM_free(kdf);
EVP_MD_free(prfmd_fetch);
return rv;
}
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de)
{
return PKCS5_v2_PBKDF2_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de,
NULL, NULL);
}

View File

@ -34,10 +34,11 @@
# define SCRYPT_MAX_MEM (1024 * 1024 * 32)
#endif
int EVP_PBE_scrypt(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen)
int EVP_PBE_scrypt_ex(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen,
OSSL_LIB_CTX *ctx, const char *propq)
{
const char *empty = "";
int rv = 1;
@ -63,7 +64,7 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
maxmem = SCRYPT_MAX_MEM;
/* Use OSSL_LIB_CTX_set0_default() if you need a library context */
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_SCRYPT, NULL);
kdf = EVP_KDF_fetch(ctx, OSSL_KDF_NAME_SCRYPT, propq);
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);
if (kctx == NULL)
@ -86,4 +87,13 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
return rv;
}
int EVP_PBE_scrypt(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen)
{
return EVP_PBE_scrypt_ex(pass, passlen, salt, saltlen, N, r, p, maxmem,
key, keylen, NULL, NULL);
}
#endif

View File

@ -9,8 +9,11 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/core.h>
#include <openssl/core_names.h>
#include <openssl/pkcs12.h>
#include "p12_local.h"
#include "crypto/pkcs7/pk7_local.h"
/* Pack an object into an OCTET STRING and turn into a safebag */
@ -80,15 +83,17 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags)
PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags,
OSSL_LIB_CTX *ctx, const char *propq)
{
PKCS7 *p7;
X509_ALGOR *pbe;
const EVP_CIPHER *pbe_ciph;
const EVP_CIPHER *pbe_ciph = NULL;
EVP_CIPHER *pbe_ciph_fetch = NULL;
if ((p7 = PKCS7_new()) == NULL) {
if ((p7 = PKCS7_new_ex(ctx, propq)) == NULL) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
return NULL;
}
@ -97,12 +102,16 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
goto err;
}
pbe_ciph = EVP_get_cipherbynid(pbe_nid);
pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
if (pbe_ciph == NULL)
pbe_ciph = EVP_get_cipherbynid(pbe_nid);
if (pbe_ciph)
pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
else
pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
if (pbe_ciph != NULL) {
pbe = PKCS5_pbe2_set_iv_ex(pbe_ciph, iter, salt, saltlen, NULL, -1, ctx);
} else {
ERR_clear_error();
pbe = PKCS5_pbe_set_ex(pbe_nid, iter, salt, saltlen, ctx);
}
if (pbe == NULL) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
@ -112,34 +121,52 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
p7->d.encrypted->enc_data->algorithm = pbe;
ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
if (!(p7->d.encrypted->enc_data->enc_data =
PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
passlen, bags, 1))) {
PKCS12_item_i2d_encrypt_ex(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
passlen, bags, 1, ctx, propq))) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR);
goto err;
}
EVP_CIPHER_free(pbe_ciph_fetch);
return p7;
err:
PKCS7_free(p7);
EVP_CIPHER_free(pbe_ciph_fetch);
return NULL;
}
PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags)
{
return PKCS12_pack_p7encdata_ex(pbe_nid, pass, passlen, salt, saltlen,
iter, bags, NULL, NULL);
}
STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
int passlen)
{
if (!PKCS7_type_is_encrypted(p7))
return NULL;
return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
return PKCS12_item_decrypt_d2i_ex(p7->d.encrypted->enc_data->algorithm,
ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
pass, passlen,
p7->d.encrypted->enc_data->enc_data, 1);
p7->d.encrypted->enc_data->enc_data, 1,
p7->ctx.libctx, p7->ctx.propq);
}
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey_ex(const PKCS12_SAFEBAG *bag,
const char *pass, int passlen,
OSSL_LIB_CTX *ctx, const char *propq)
{
return PKCS8_decrypt_ex(bag->value.shkeybag, pass, passlen, ctx, propq);
}
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag,
const char *pass, int passlen)
{
return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
return PKCS12_decrypt_skey_ex(bag, pass, passlen, NULL, NULL);
}
int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
@ -152,10 +179,25 @@ int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
{
STACK_OF(PKCS7) *p7s;
PKCS7 *p7;
int i;
if (!PKCS7_type_is_data(p12->authsafes)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
return ASN1_item_unpack(p12->authsafes->d.data,
ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
p7s = ASN1_item_unpack(p12->authsafes->d.data,
ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
if (p7s != NULL) {
for (i = 0; i < sk_PKCS7_num(p7s); i++) {
p7 = sk_PKCS7_value(p7s, i);
if (!ossl_pkcs7_ctx_propagate(p12->authsafes, p7))
goto err;
}
}
return p7s;
err:
sk_PKCS7_free(p7s);
return NULL;
}

View File

@ -9,6 +9,9 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/core.h>
#include <openssl/core_names.h>
#include "crypto/evp.h"
#include <openssl/pkcs12.h>
/* PKCS#12 PBE algorithms now in static table */
@ -17,21 +20,16 @@ void PKCS12_PBE_add(void)
{
}
int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de)
int PKCS12_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq)
{
PBEPARAM *pbe;
int saltlen, iter, ret;
unsigned char *salt;
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
int (*pkcs12_key_gen)(const char *pass, int passlen,
unsigned char *salt, int slen,
int id, int iter, int n,
unsigned char *out,
const EVP_MD *md_type);
pkcs12_key_gen = PKCS12_key_gen_utf8;
unsigned char *piv = iv;
if (cipher == NULL)
return 0;
@ -50,21 +48,36 @@ int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
iter = ASN1_INTEGER_get(pbe->iter);
salt = pbe->salt->data;
saltlen = pbe->salt->length;
if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
iter, EVP_CIPHER_key_length(cipher), key, md)) {
if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
iter, EVP_CIPHER_key_length(cipher), key, md,
libctx, propq)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_IV_ID,
iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
if (EVP_CIPHER_iv_length(cipher) > 0) {
if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_IV_ID,
iter, EVP_CIPHER_iv_length(cipher), iv, md,
libctx, propq)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
} else {
piv = NULL;
}
PBEPARAM_free(pbe);
ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, piv, en_de);
OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
return ret;
}
int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de)
{
return PKCS12_PBE_keyivgen_ex(ctx, pass, passlen, param, cipher, md, en_de,
NULL, NULL);
}

View File

@ -28,9 +28,10 @@ static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
return 1;
}
PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
int mac_iter, int keytype)
PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey,
X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert,
int iter, int mac_iter, int keytype,
OSSL_LIB_CTX *ctx, const char *propq)
{
PKCS12 *p12 = NULL;
STACK_OF(PKCS7) *safes = NULL;
@ -76,14 +77,16 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *
goto err;
}
if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
if (bags && !PKCS12_add_safe_ex(&safes, bags, nid_cert, iter, pass,
ctx, propq))
goto err;
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
bags = NULL;
if (pkey) {
bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
bag = PKCS12_add_key_ex(&bags, pkey, keytype, iter, nid_key, pass,
ctx, propq);
if (!bag)
goto err;
@ -105,7 +108,7 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
bags = NULL;
p12 = PKCS12_add_safes(safes, 0);
p12 = PKCS12_add_safes_ex(safes, 0, ctx, propq);
if (p12 == NULL)
goto err;
@ -128,6 +131,14 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *
}
PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
int mac_iter, int keytype)
{
return PKCS12_create_ex(pass, name, pkey, cert, ca, nid_key, nid_cert,
iter, mac_iter, keytype, NULL, NULL);
}
PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
{
PKCS12_SAFEBAG *bag = NULL;
@ -165,9 +176,10 @@ PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
}
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int nid_key, const char *pass)
PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int nid_key, const char *pass,
OSSL_LIB_CTX *ctx, const char *propq)
{
PKCS12_SAFEBAG *bag = NULL;
@ -179,8 +191,8 @@ PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
goto err;
if (nid_key != -1) {
bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, NULL, 0,
iter, p8);
bag = PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(nid_key, pass, -1, NULL, 0,
iter, p8, ctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8);
} else
bag = PKCS12_SAFEBAG_create0_p8inf(p8);
@ -199,6 +211,14 @@ PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
}
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int nid_key, const char *pass)
{
return PKCS12_add_key_ex(pbags, key, key_usage, iter, nid_key, pass,
NULL, NULL);
}
PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
int nid_type, const unsigned char *value, int len)
{
@ -217,8 +237,9 @@ PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
return NULL;
}
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int nid_safe, int iter, const char *pass)
int PKCS12_add_safe_ex(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int nid_safe, int iter, const char *pass,
OSSL_LIB_CTX *ctx, const char *propq)
{
PKCS7 *p7 = NULL;
int free_safes = 0;
@ -240,7 +261,7 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
if (nid_safe == -1)
p7 = PKCS12_pack_p7data(bags);
else
p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
p7 = PKCS12_pack_p7encdata_ex(nid_safe, pass, -1, NULL, 0, iter, bags, ctx, propq);
if (p7 == NULL)
goto err;
@ -256,7 +277,12 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
}
PKCS7_free(p7);
return 0;
}
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int nid_safe, int iter, const char *pass)
{
return PKCS12_add_safe_ex(psafes, bags, nid_safe, iter, pass, NULL, NULL);
}
static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
@ -285,13 +311,14 @@ static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
}
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
PKCS12 *PKCS12_add_safes_ex(STACK_OF(PKCS7) *safes, int nid_p7,
OSSL_LIB_CTX *ctx, const char *propq)
{
PKCS12 *p12;
if (nid_p7 <= 0)
nid_p7 = NID_pkcs7_data;
p12 = PKCS12_init(nid_p7);
p12 = PKCS12_init_ex(nid_p7, ctx, propq);
if (p12 == NULL)
return NULL;
@ -303,3 +330,8 @@ PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
return p12;
}
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
{
return PKCS12_add_safes_ex(safes, nid_p7, NULL, NULL);
}

View File

@ -16,10 +16,11 @@
* Encrypt/Decrypt a buffer based on password and algor, result in a
* OPENSSL_malloc'ed buffer
*/
unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
const char *pass, int passlen,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen, int en_de)
unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
const char *pass, int passlen,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen, int en_de,
OSSL_LIB_CTX *libctx, const char *propq)
{
unsigned char *out = NULL;
int outlen, i;
@ -32,8 +33,8 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
}
/* Process data */
if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
algor->parameter, ctx, en_de))
if (!EVP_PBE_CipherInit_ex(algor->algorithm, pass, passlen,
algor->parameter, ctx, en_de, libctx, propq))
goto err;
/*
@ -109,22 +110,33 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
}
unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
const char *pass, int passlen,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen, int en_de)
{
return PKCS12_pbe_crypt_ex(algor, pass, passlen, in, inlen, data, datalen,
en_de, NULL, NULL);
}
/*
* Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer
* after use.
*/
void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf)
void *PKCS12_item_decrypt_d2i_ex(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf,
OSSL_LIB_CTX *libctx,
const char *propq)
{
unsigned char *out = NULL;
const unsigned char *p;
void *ret;
int outlen = 0;
if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
&out, &outlen, 0))
if (!PKCS12_pbe_crypt_ex(algor, pass, passlen, oct->data, oct->length,
&out, &outlen, 0, libctx, propq))
return NULL;
p = out;
OSSL_TRACE_BEGIN(PKCS12_DECRYPT) {
@ -141,15 +153,25 @@ void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
return ret;
}
void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf)
{
return PKCS12_item_decrypt_d2i_ex(algor, it, pass, passlen, oct, zbuf,
NULL, NULL);
}
/*
* Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero
* encoding.
*/
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf)
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt_ex(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf,
OSSL_LIB_CTX *ctx,
const char *propq)
{
ASN1_OCTET_STRING *oct = NULL;
unsigned char *in = NULL;
@ -164,8 +186,8 @@ ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR);
goto err;
}
if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
&oct->length, 1)) {
if (!PKCS12_pbe_crypt_ex(algor, pass, passlen, in, inlen, &oct->data,
&oct->length, 1, ctx, propq)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR);
OPENSSL_free(in);
goto err;
@ -178,3 +200,11 @@ ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
ASN1_OCTET_STRING_free(oct);
return NULL;
}
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf)
{
return PKCS12_item_i2d_encrypt_ex(algor, it, pass, passlen, obj, zbuf, NULL, NULL);
}

View File

@ -10,11 +10,12 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/pkcs12.h>
#include "crypto/pkcs7.h"
#include "p12_local.h"
/* Initialise a PKCS12 structure to take data */
PKCS12 *PKCS12_init(int mode)
PKCS12 *PKCS12_init_ex(int mode, OSSL_LIB_CTX *ctx, const char *propq)
{
PKCS12 *pkcs12;
@ -25,6 +26,13 @@ PKCS12 *PKCS12_init(int mode)
if (!ASN1_INTEGER_set(pkcs12->version, 3))
goto err;
pkcs12->authsafes->type = OBJ_nid2obj(mode);
ossl_pkcs7_set0_libctx(pkcs12->authsafes, ctx);
if (!ossl_pkcs7_set1_propq(pkcs12->authsafes, propq)) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
goto err;
}
switch (mode) {
case NID_pkcs7_data:
if ((pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) {
@ -42,3 +50,9 @@ PKCS12 *PKCS12_init(int mode)
PKCS12_free(pkcs12);
return NULL;
}
PKCS12 *PKCS12_init(int mode)
{
return PKCS12_init_ex(mode, NULL, NULL);
}

View File

@ -16,9 +16,10 @@
#include <openssl/core_names.h>
#include "internal/provider.h"
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq)
{
int ret;
unsigned char *unipass;
@ -31,15 +32,24 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
return 0;
}
ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
id, iter, n, out, md_type);
ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter,
n, out, md_type, ctx, propq);
OPENSSL_clear_free(unipass, uniplen);
return ret > 0;
}
int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
{
return PKCS12_key_gen_asc_ex(pass, passlen, salt, saltlen, id, iter, n,
out, md_type, NULL, NULL);
}
int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq)
{
int ret;
unsigned char *unipass;
@ -52,15 +62,24 @@ int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
return 0;
}
ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
id, iter, n, out, md_type);
ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter,
n, out, md_type, ctx, propq);
OPENSSL_clear_free(unipass, uniplen);
return ret > 0;
}
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
{
return PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, id, iter, n,
out, md_type, NULL, NULL);
}
int PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *libctx, const char *propq)
{
int res = 0;
EVP_KDF *kdf;
@ -70,12 +89,7 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
if (n <= 0)
return 0;
/*
* The parameter query isn't available but the library context can be
* extracted from the passed digest.
*/
kdf = EVP_KDF_fetch(ossl_provider_libctx(EVP_MD_provider(md_type)),
"PKCS12KDF", NULL);
kdf = EVP_KDF_fetch(libctx, "PKCS12KDF", propq);
if (kdf == NULL)
return 0;
ctx = EVP_KDF_CTX_new(kdf);
@ -92,11 +106,9 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id);
*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter);
*p = OSSL_PARAM_construct_end();
if (!EVP_KDF_CTX_set_params(ctx, params))
goto err;
OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
BIO_printf(trc_out, "PKCS12_key_gen_uni(): ID %d, ITER %d\n", id, iter);
BIO_printf(trc_out, "PKCS12_key_gen_uni_ex(): ID %d, ITER %d\n", id, iter);
BIO_printf(trc_out, "Password (length %d):\n", passlen);
BIO_hex_string(trc_out, 0, passlen, pass, passlen);
BIO_printf(trc_out, "\n");
@ -105,7 +117,7 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
BIO_printf(trc_out, "\n");
} OSSL_TRACE_END(PKCS12_KEYGEN);
if (EVP_KDF_derive(ctx, out, (size_t)n, NULL)) {
if (EVP_KDF_derive(ctx, out, (size_t)n, params)) {
res = 1;
OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
BIO_printf(trc_out, "Output KEY (length %d)\n", n);
@ -113,7 +125,13 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
BIO_printf(trc_out, "\n");
} OSSL_TRACE_END(PKCS12_KEYGEN);
}
err:
EVP_KDF_CTX_free(ctx);
return res;
}
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type)
{
return PKCS12_key_gen_uni_ex(pass, passlen, salt, saltlen, id, iter, n, out, md_type, NULL, NULL);
}

View File

@ -82,18 +82,17 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
const EVP_MD *md_type))
{
int ret = 0;
const EVP_MD *md_type;
const EVP_MD *md;
EVP_MD *md_fetch;
HMAC_CTX *hmac = NULL;
unsigned char key[EVP_MAX_MD_SIZE], *salt;
int saltlen, iter;
char md_name[80];
int md_size = 0;
int md_type_nid;
int md_nid;
const X509_ALGOR *macalg;
const ASN1_OBJECT *macoid;
if (pkcs12_key_gen == NULL)
pkcs12_key_gen = PKCS12_key_gen_utf8;
if (!PKCS7_type_is_data(p12->authsafes)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
return 0;
@ -107,32 +106,51 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
iter = ASN1_INTEGER_get(p12->mac->iter);
X509_SIG_get0(p12->mac->dinfo, &macalg, NULL);
X509_ALGOR_get0(&macoid, NULL, NULL, macalg);
if ((md_type = EVP_get_digestbyobj(macoid)) == NULL) {
if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0)
return 0;
md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name,
p12->authsafes->ctx.propq);
if (md == NULL)
md = EVP_get_digestbynid(OBJ_obj2nid(macoid));
if (md == NULL) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
return 0;
}
md_size = EVP_MD_size(md_type);
md_type_nid = EVP_MD_type(md_type);
md_size = EVP_MD_size(md);
md_nid = EVP_MD_type(md);
if (md_size < 0)
return 0;
if ((md_type_nid == NID_id_GostR3411_94
|| md_type_nid == NID_id_GostR3411_2012_256
|| md_type_nid == NID_id_GostR3411_2012_512)
goto err;
if ((md_nid == NID_id_GostR3411_94
|| md_nid == NID_id_GostR3411_2012_256
|| md_nid == NID_id_GostR3411_2012_512)
&& ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) {
md_size = TK26_MAC_KEY_LEN;
if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter,
md_size, key, md_type)) {
md_size, key, md)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR);
goto err;
}
} else
if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID,
iter, md_size, key, md_type)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR);
goto err;
} else {
if (pkcs12_key_gen != NULL) {
if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID,
iter, md_size, key, md)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR);
goto err;
}
} else {
/* Default to UTF-8 password */
if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_MAC_ID,
iter, md_size, key, md,
p12->authsafes->ctx.libctx,
p12->authsafes->ctx.propq)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR);
goto err;
}
}
}
if ((hmac = HMAC_CTX_new()) == NULL
|| !HMAC_Init_ex(hmac, key, md_size, md_type, NULL)
|| !HMAC_Init_ex(hmac, key, md_size, md, NULL)
|| !HMAC_Update(hmac, p12->authsafes->d.data->data,
p12->authsafes->d.data->length)
|| !HMAC_Final(hmac, mac, maclen)) {
@ -143,6 +161,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
err:
OPENSSL_cleanse(key, sizeof(key));
HMAC_CTX_free(hmac);
EVP_MD_free(md_fetch);
return ret;
}
@ -163,8 +182,7 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT);
return 0;
}
if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
PKCS12_key_gen_utf8)) {
if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR);
return 0;
}
@ -198,8 +216,7 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
/*
* Note that output mac is forced to UTF-8...
*/
if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
PKCS12_key_gen_utf8)) {
if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR);
return 0;
}
@ -242,7 +259,8 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
}
p12->mac->salt->length = saltlen;
if (!salt) {
if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0)
if (RAND_bytes_ex(p12->authsafes->ctx.libctx, p12->mac->salt->data,
saltlen) <= 0)
return 0;
} else
memcpy(p12->mac->salt->data, salt, saltlen);

View File

@ -11,13 +11,22 @@
#include "internal/cryptlib.h"
#include <openssl/pkcs12.h>
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
int passlen)
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_ex(const X509_SIG *p8, const char *pass,
int passlen, OSSL_LIB_CTX *ctx,
const char *propq)
{
const X509_ALGOR *dalg;
const ASN1_OCTET_STRING *doct;
X509_SIG_get0(p8, &dalg, &doct);
return PKCS12_item_decrypt_d2i(dalg,
return PKCS12_item_decrypt_d2i_ex(dalg,
ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
passlen, doct, 1);
passlen, doct, 1, ctx, propq);
}
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
int passlen)
{
return PKCS8_decrypt_ex(p8, pass, passlen, NULL, NULL);
}

View File

@ -9,30 +9,34 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/core.h>
#include <openssl/pkcs12.h>
#include "crypto/x509.h"
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf)
X509_SIG *PKCS8_encrypt_ex(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *libctx, const char *propq)
{
X509_SIG *p8 = NULL;
X509_ALGOR *pbe;
if (pbe_nid == -1)
pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
pbe = PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, -1,
libctx);
else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid);
pbe = PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, pbe_nid,
libctx);
else {
ERR_clear_error();
pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
pbe = PKCS5_pbe_set_ex(pbe_nid, iter, salt, saltlen, libctx);
}
if (pbe == NULL) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
return NULL;
}
p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe);
p8 = PKCS8_set0_pbe_ex(pass, passlen, p8inf, pbe, libctx, propq);
if (p8 == NULL) {
X509_ALGOR_free(pbe);
return NULL;
@ -41,15 +45,25 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
return p8;
}
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf)
{
return PKCS8_encrypt_ex(pbe_nid, cipher, pass, passlen, salt, saltlen, iter,
p8inf, NULL, NULL);
}
X509_SIG *PKCS8_set0_pbe_ex(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe,
OSSL_LIB_CTX *ctx, const char *propq)
{
X509_SIG *p8;
ASN1_OCTET_STRING *enckey;
enckey =
PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
pass, passlen, p8inf, 1);
PKCS12_item_i2d_encrypt_ex(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
pass, passlen, p8inf, 1, ctx, propq);
if (!enckey) {
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR);
return NULL;
@ -67,3 +81,9 @@ X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
return p8;
}
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
{
return PKCS8_set0_pbe_ex(pass, passlen, p8inf, pbe, NULL, NULL);
}

View File

@ -198,6 +198,41 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
return bag;
}
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
const char *pass,
int passlen,
unsigned char *salt,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *ctx,
const char *propq)
{
PKCS12_SAFEBAG *bag = NULL;
const EVP_CIPHER *pbe_ciph = NULL;
EVP_CIPHER *pbe_ciph_fetch = NULL;
X509_SIG *p8;
pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
if (pbe_ciph == NULL)
pbe_ciph = EVP_get_cipherbynid(pbe_nid);
if (pbe_ciph != NULL)
pbe_nid = -1;
p8 = PKCS8_encrypt_ex(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
p8inf, ctx, propq);
if (p8 == NULL)
goto err;
bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
if (bag == NULL)
X509_SIG_free(p8);
err:
EVP_CIPHER_free(pbe_ciph_fetch);
return bag;
}
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
const char *pass,
int passlen,
@ -205,22 +240,7 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf)
{
PKCS12_SAFEBAG *bag;
const EVP_CIPHER *pbe_ciph;
X509_SIG *p8;
pbe_ciph = EVP_get_cipherbynid(pbe_nid);
if (pbe_ciph)
pbe_nid = -1;
p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
p8inf);
if (p8 == NULL)
return NULL;
bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
if (bag == NULL)
X509_SIG_free(p8);
return bag;
return PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(pbe_nid, pass, passlen,
salt, saltlen, iter, p8inf,
NULL, NULL);
}

View File

@ -469,6 +469,37 @@ const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7)
return p7 != NULL ? &p7->ctx : NULL;
}
void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx)
{
p7->ctx.libctx = ctx;
}
int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq)
{
if (p7->ctx.propq != NULL) {
OPENSSL_free(p7->ctx.propq);
p7->ctx.propq = NULL;
}
if (propq != NULL) {
p7->ctx.propq = OPENSSL_strdup(propq);
if (p7->ctx.propq == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
}
return 1;
}
int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to)
{
ossl_pkcs7_set0_libctx(to, from->ctx.libctx);
if (!ossl_pkcs7_set1_propq(to, from->ctx.propq))
return 0;
ossl_pkcs7_resolve_libctx(to);
return 1;
}
OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
{
return ctx != NULL ? ctx->libctx : NULL;

View File

@ -12,3 +12,5 @@
const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7);
OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx);
const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx);
int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to);

View File

@ -1118,6 +1118,10 @@ DEPEND[html/man3/EVP_OpenInit.html]=man3/EVP_OpenInit.pod
GENERATE[html/man3/EVP_OpenInit.html]=man3/EVP_OpenInit.pod
DEPEND[man/man3/EVP_OpenInit.3]=man3/EVP_OpenInit.pod
GENERATE[man/man3/EVP_OpenInit.3]=man3/EVP_OpenInit.pod
DEPEND[html/man3/EVP_PBE_CipherInit.html]=man3/EVP_PBE_CipherInit.pod
GENERATE[html/man3/EVP_PBE_CipherInit.html]=man3/EVP_PBE_CipherInit.pod
DEPEND[man/man3/EVP_PBE_CipherInit.3]=man3/EVP_PBE_CipherInit.pod
GENERATE[man/man3/EVP_PBE_CipherInit.3]=man3/EVP_PBE_CipherInit.pod
DEPEND[html/man3/EVP_PKEY2PKCS8.html]=man3/EVP_PKEY2PKCS8.pod
GENERATE[html/man3/EVP_PKEY2PKCS8.html]=man3/EVP_PKEY2PKCS8.pod
DEPEND[man/man3/EVP_PKEY2PKCS8.3]=man3/EVP_PKEY2PKCS8.pod
@ -1730,6 +1734,10 @@ DEPEND[html/man3/PEM_write_bio_PKCS7_stream.html]=man3/PEM_write_bio_PKCS7_strea
GENERATE[html/man3/PEM_write_bio_PKCS7_stream.html]=man3/PEM_write_bio_PKCS7_stream.pod
DEPEND[man/man3/PEM_write_bio_PKCS7_stream.3]=man3/PEM_write_bio_PKCS7_stream.pod
GENERATE[man/man3/PEM_write_bio_PKCS7_stream.3]=man3/PEM_write_bio_PKCS7_stream.pod
DEPEND[html/man3/PKCS12_PBE_keyivgen.html]=man3/PKCS12_PBE_keyivgen.pod
GENERATE[html/man3/PKCS12_PBE_keyivgen.html]=man3/PKCS12_PBE_keyivgen.pod
DEPEND[man/man3/PKCS12_PBE_keyivgen.3]=man3/PKCS12_PBE_keyivgen.pod
GENERATE[man/man3/PKCS12_PBE_keyivgen.3]=man3/PKCS12_PBE_keyivgen.pod
DEPEND[html/man3/PKCS12_SAFEBAG_create_cert.html]=man3/PKCS12_SAFEBAG_create_cert.pod
GENERATE[html/man3/PKCS12_SAFEBAG_create_cert.html]=man3/PKCS12_SAFEBAG_create_cert.pod
DEPEND[man/man3/PKCS12_SAFEBAG_create_cert.3]=man3/PKCS12_SAFEBAG_create_cert.pod
@ -1770,18 +1778,46 @@ DEPEND[html/man3/PKCS12_create.html]=man3/PKCS12_create.pod
GENERATE[html/man3/PKCS12_create.html]=man3/PKCS12_create.pod
DEPEND[man/man3/PKCS12_create.3]=man3/PKCS12_create.pod
GENERATE[man/man3/PKCS12_create.3]=man3/PKCS12_create.pod
DEPEND[html/man3/PKCS12_decrypt_skey.html]=man3/PKCS12_decrypt_skey.pod
GENERATE[html/man3/PKCS12_decrypt_skey.html]=man3/PKCS12_decrypt_skey.pod
DEPEND[man/man3/PKCS12_decrypt_skey.3]=man3/PKCS12_decrypt_skey.pod
GENERATE[man/man3/PKCS12_decrypt_skey.3]=man3/PKCS12_decrypt_skey.pod
DEPEND[html/man3/PKCS12_gen_mac.html]=man3/PKCS12_gen_mac.pod
GENERATE[html/man3/PKCS12_gen_mac.html]=man3/PKCS12_gen_mac.pod
DEPEND[man/man3/PKCS12_gen_mac.3]=man3/PKCS12_gen_mac.pod
GENERATE[man/man3/PKCS12_gen_mac.3]=man3/PKCS12_gen_mac.pod
DEPEND[html/man3/PKCS12_get_friendlyname.html]=man3/PKCS12_get_friendlyname.pod
GENERATE[html/man3/PKCS12_get_friendlyname.html]=man3/PKCS12_get_friendlyname.pod
DEPEND[man/man3/PKCS12_get_friendlyname.3]=man3/PKCS12_get_friendlyname.pod
GENERATE[man/man3/PKCS12_get_friendlyname.3]=man3/PKCS12_get_friendlyname.pod
DEPEND[html/man3/PKCS12_init.html]=man3/PKCS12_init.pod
GENERATE[html/man3/PKCS12_init.html]=man3/PKCS12_init.pod
DEPEND[man/man3/PKCS12_init.3]=man3/PKCS12_init.pod
GENERATE[man/man3/PKCS12_init.3]=man3/PKCS12_init.pod
DEPEND[html/man3/PKCS12_item_decrypt_d2i.html]=man3/PKCS12_item_decrypt_d2i.pod
GENERATE[html/man3/PKCS12_item_decrypt_d2i.html]=man3/PKCS12_item_decrypt_d2i.pod
DEPEND[man/man3/PKCS12_item_decrypt_d2i.3]=man3/PKCS12_item_decrypt_d2i.pod
GENERATE[man/man3/PKCS12_item_decrypt_d2i.3]=man3/PKCS12_item_decrypt_d2i.pod
DEPEND[html/man3/PKCS12_key_gen_utf8_ex.html]=man3/PKCS12_key_gen_utf8_ex.pod
GENERATE[html/man3/PKCS12_key_gen_utf8_ex.html]=man3/PKCS12_key_gen_utf8_ex.pod
DEPEND[man/man3/PKCS12_key_gen_utf8_ex.3]=man3/PKCS12_key_gen_utf8_ex.pod
GENERATE[man/man3/PKCS12_key_gen_utf8_ex.3]=man3/PKCS12_key_gen_utf8_ex.pod
DEPEND[html/man3/PKCS12_newpass.html]=man3/PKCS12_newpass.pod
GENERATE[html/man3/PKCS12_newpass.html]=man3/PKCS12_newpass.pod
DEPEND[man/man3/PKCS12_newpass.3]=man3/PKCS12_newpass.pod
GENERATE[man/man3/PKCS12_newpass.3]=man3/PKCS12_newpass.pod
DEPEND[html/man3/PKCS12_pack_p7encdata.html]=man3/PKCS12_pack_p7encdata.pod
GENERATE[html/man3/PKCS12_pack_p7encdata.html]=man3/PKCS12_pack_p7encdata.pod
DEPEND[man/man3/PKCS12_pack_p7encdata.3]=man3/PKCS12_pack_p7encdata.pod
GENERATE[man/man3/PKCS12_pack_p7encdata.3]=man3/PKCS12_pack_p7encdata.pod
DEPEND[html/man3/PKCS12_parse.html]=man3/PKCS12_parse.pod
GENERATE[html/man3/PKCS12_parse.html]=man3/PKCS12_parse.pod
DEPEND[man/man3/PKCS12_parse.3]=man3/PKCS12_parse.pod
GENERATE[man/man3/PKCS12_parse.3]=man3/PKCS12_parse.pod
DEPEND[html/man3/PKCS5_PBE_keyivgen.html]=man3/PKCS5_PBE_keyivgen.pod
GENERATE[html/man3/PKCS5_PBE_keyivgen.html]=man3/PKCS5_PBE_keyivgen.pod
DEPEND[man/man3/PKCS5_PBE_keyivgen.3]=man3/PKCS5_PBE_keyivgen.pod
GENERATE[man/man3/PKCS5_PBE_keyivgen.3]=man3/PKCS5_PBE_keyivgen.pod
DEPEND[html/man3/PKCS5_PBKDF2_HMAC.html]=man3/PKCS5_PBKDF2_HMAC.pod
GENERATE[html/man3/PKCS5_PBKDF2_HMAC.html]=man3/PKCS5_PBKDF2_HMAC.pod
DEPEND[man/man3/PKCS5_PBKDF2_HMAC.3]=man3/PKCS5_PBKDF2_HMAC.pod
@ -1814,6 +1850,10 @@ DEPEND[html/man3/PKCS7_verify.html]=man3/PKCS7_verify.pod
GENERATE[html/man3/PKCS7_verify.html]=man3/PKCS7_verify.pod
DEPEND[man/man3/PKCS7_verify.3]=man3/PKCS7_verify.pod
GENERATE[man/man3/PKCS7_verify.3]=man3/PKCS7_verify.pod
DEPEND[html/man3/PKCS8_encrypt.html]=man3/PKCS8_encrypt.pod
GENERATE[html/man3/PKCS8_encrypt.html]=man3/PKCS8_encrypt.pod
DEPEND[man/man3/PKCS8_encrypt.3]=man3/PKCS8_encrypt.pod
GENERATE[man/man3/PKCS8_encrypt.3]=man3/PKCS8_encrypt.pod
DEPEND[html/man3/PKCS8_pkey_add1_attr.html]=man3/PKCS8_pkey_add1_attr.pod
GENERATE[html/man3/PKCS8_pkey_add1_attr.html]=man3/PKCS8_pkey_add1_attr.pod
DEPEND[man/man3/PKCS8_pkey_add1_attr.3]=man3/PKCS8_pkey_add1_attr.pod
@ -2933,6 +2973,7 @@ html/man3/EVP_KEYMGMT.html \
html/man3/EVP_MAC.html \
html/man3/EVP_MD_meth_new.html \
html/man3/EVP_OpenInit.html \
html/man3/EVP_PBE_CipherInit.html \
html/man3/EVP_PKEY2PKCS8.html \
html/man3/EVP_PKEY_ASN1_METHOD.html \
html/man3/EVP_PKEY_CTX_ctrl.html \
@ -3086,6 +3127,7 @@ html/man3/PEM_read_bio_PrivateKey.html \
html/man3/PEM_read_bio_ex.html \
html/man3/PEM_write_bio_CMS_stream.html \
html/man3/PEM_write_bio_PKCS7_stream.html \
html/man3/PKCS12_PBE_keyivgen.html \
html/man3/PKCS12_SAFEBAG_create_cert.html \
html/man3/PKCS12_SAFEBAG_get0_attrs.html \
html/man3/PKCS12_SAFEBAG_get1_cert.html \
@ -3096,9 +3138,16 @@ html/man3/PKCS12_add_friendlyname_asc.html \
html/man3/PKCS12_add_localkeyid.html \
html/man3/PKCS12_add_safe.html \
html/man3/PKCS12_create.html \
html/man3/PKCS12_decrypt_skey.html \
html/man3/PKCS12_gen_mac.html \
html/man3/PKCS12_get_friendlyname.html \
html/man3/PKCS12_init.html \
html/man3/PKCS12_item_decrypt_d2i.html \
html/man3/PKCS12_key_gen_utf8_ex.html \
html/man3/PKCS12_newpass.html \
html/man3/PKCS12_pack_p7encdata.html \
html/man3/PKCS12_parse.html \
html/man3/PKCS5_PBE_keyivgen.html \
html/man3/PKCS5_PBKDF2_HMAC.html \
html/man3/PKCS7_decrypt.html \
html/man3/PKCS7_encrypt.html \
@ -3107,6 +3156,7 @@ html/man3/PKCS7_sign.html \
html/man3/PKCS7_sign_add_signer.html \
html/man3/PKCS7_type_is_other.html \
html/man3/PKCS7_verify.html \
html/man3/PKCS8_encrypt.html \
html/man3/PKCS8_pkey_add1_attr.html \
html/man3/RAND_add.html \
html/man3/RAND_bytes.html \
@ -3509,6 +3559,7 @@ man/man3/EVP_KEYMGMT.3 \
man/man3/EVP_MAC.3 \
man/man3/EVP_MD_meth_new.3 \
man/man3/EVP_OpenInit.3 \
man/man3/EVP_PBE_CipherInit.3 \
man/man3/EVP_PKEY2PKCS8.3 \
man/man3/EVP_PKEY_ASN1_METHOD.3 \
man/man3/EVP_PKEY_CTX_ctrl.3 \
@ -3662,6 +3713,7 @@ man/man3/PEM_read_bio_PrivateKey.3 \
man/man3/PEM_read_bio_ex.3 \
man/man3/PEM_write_bio_CMS_stream.3 \
man/man3/PEM_write_bio_PKCS7_stream.3 \
man/man3/PKCS12_PBE_keyivgen.3 \
man/man3/PKCS12_SAFEBAG_create_cert.3 \
man/man3/PKCS12_SAFEBAG_get0_attrs.3 \
man/man3/PKCS12_SAFEBAG_get1_cert.3 \
@ -3672,9 +3724,16 @@ man/man3/PKCS12_add_friendlyname_asc.3 \
man/man3/PKCS12_add_localkeyid.3 \
man/man3/PKCS12_add_safe.3 \
man/man3/PKCS12_create.3 \
man/man3/PKCS12_decrypt_skey.3 \
man/man3/PKCS12_gen_mac.3 \
man/man3/PKCS12_get_friendlyname.3 \
man/man3/PKCS12_init.3 \
man/man3/PKCS12_item_decrypt_d2i.3 \
man/man3/PKCS12_key_gen_utf8_ex.3 \
man/man3/PKCS12_newpass.3 \
man/man3/PKCS12_pack_p7encdata.3 \
man/man3/PKCS12_parse.3 \
man/man3/PKCS5_PBE_keyivgen.3 \
man/man3/PKCS5_PBKDF2_HMAC.3 \
man/man3/PKCS7_decrypt.3 \
man/man3/PKCS7_encrypt.3 \
@ -3683,6 +3742,7 @@ man/man3/PKCS7_sign.3 \
man/man3/PKCS7_sign_add_signer.3 \
man/man3/PKCS7_type_is_other.3 \
man/man3/PKCS7_verify.3 \
man/man3/PKCS8_encrypt.3 \
man/man3/PKCS8_pkey_add1_attr.3 \
man/man3/RAND_add.3 \
man/man3/RAND_bytes.3 \

View File

@ -0,0 +1,99 @@
=pod
=head1 NAME
EVP_PBE_CipherInit, EVP_PBE_CipherInit_ex,
EVP_PBE_find, EVP_PBE_find_ex - Password based encryption routines
=head1 SYNOPSIS
#include <openssl/evp.h>
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
int EVP_PBE_CipherInit_ex(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
EVP_PBE_KEYGEN **pkeygen);
int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid,
EVP_PBE_KEYGEN **pkeygen, EVP_PBE_KEYGEN_EX **keygen_ex);
=head1 DESCRIPTION
=head2 PBE operations
EVP_PBE_CipherInit() and EVP_PBE_CipherInit_ex() initialise an B<EVP_CIPHER_CTX>
I<ctx> for encryption (I<en_de>=1) or decryption (I<en_de>=0) using the password
I<pass> of length I<passlen>. The PBE algorithm type and parameters are extracted
from an OID I<pbe_obj> and parameters I<param>.
EVP_PBE_CipherInit_ex() also allows the application to specify a library context
I<libctx> and property query I<propq> to select appropriate algorithm
implementations.
=head2 PBE algorithm search
EVP_PBE_find() and EVP_PBE_find_ex() search for a matching algorithm using two parameters:
1. An algorithm type I<type> which can be:
=over 4
=item *
EVP_PBE_TYPE_OUTER - A PBE algorithm
=item *
EVP_PBE_TYPE_PRF - A pseudo-random function
=item *
EVP_PBE_TYPE_KDF - A key derivation function
=back
2. A I<pbe_nid> which can represent the algorithm identifier with parameters e.g.
B<NID_pbeWithSHA1AndRC2_CBC> or an algorithm class e.g. B<NID_pbes2>.
They return the algorithm's cipher ID I<pcnid>, digest ID I<pmnid> and a key
generation function for the algorithm I<pkeygen>. EVP_PBE_CipherInit_ex() also
returns an extended key generation function I<keygen_ex> which takes a library
context and property query.
If a NULL is supplied for any of I<pcnid>, I<pmnid>, I<pkeygen> or I<pkeygen_ex>
then this parameter is not returned.
=head1 NOTES
The arguments I<pbe_obj> and I<param> to EVP_PBE_CipherInit() and EVP_PBE_CipherInit_ex()
together form an B<X509_ALGOR> and can often be extracted directly from this structure.
=head1 RETURN VALUES
Return value is 1 for success and 0 if an error occurred.
=head1 SEE ALSO
L<PKCS5_PBE_keyivgen(3)>,
L<PKCS12_PBE_keyivgen_ex(3)>,
L<PKCS5_v2_PBE_keyivgen_ex(3)>,
L<PKCS12_pbe_crypt_ex(3)>,
L<PKCS12_create_ex(3)>
=head1 HISTORY
EVP_PBE_CipherInit_ex() and EVP_PBE_find_ex() were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,108 @@
=pod
=head1 NAME
PKCS12_PBE_keyivgen, PKCS12_PBE_keyivgen_ex,
PKCS12_pbe_crypt, PKCS12_pbe_crypt_ex - PKCS#12 Password based encryption
=head1 SYNOPSIS
#include <openssl/evp.h>
int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md_type, int en_de);
int PKCS12_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md_type, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
const char *pass, int passlen,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen,
int en_de);
unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
const char *pass, int passlen,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen,
int en_de, OSSL_LIB_CTX *libctx,
const char *propq);
=head1 DESCRIPTION
PKCS12_PBE_keyivgen() and PKCS12_PBE_keyivgen_ex() take a password I<pass> of
length I<passlen>, parameters I<param> and a message digest function I<md_type>
and perform a key derivation according to PKCS#12. The resulting key is
then used to initialise the cipher context I<ctx> with a cipher I<cipher> for
encryption (I<en_de>=1) or decryption (I<en_de>=0).
PKCS12_PBE_keyivgen_ex() also allows the application to specify a library context
I<libctx> and property query I<propq> to select appropriate algorithm
implementations.
PKCS12_pbe_crypt() and PKCS12_pbe_crypt_ex() will encrypt or decrypt a buffer
based on the algorithm in I<algor> and password I<pass> of length I<passlen>.
The input is from I<in> of length I<inlen> and output is into a malloc'd buffer
returned in I<*data> of length I<datalen>. The operation is determined by I<en_de>,
encryption (I<en_de>=1) or decryption (I<en_de>=0).
PKCS12_pbe_crypt_ex() allows the application to specify a library context
I<libctx> and property query I<propq> to select appropriate algorithm
implementations.
I<pass> is the password used in the derivation of length I<passlen>. I<pass>
is an optional parameter and can be NULL. If I<passlen> is -1, then the
function will calculate the length of I<pass> using strlen().
I<salt> is the salt used in the derivation of length I<saltlen>. If the
I<salt> is NULL, then I<saltlen> must be 0. The function will not
attempt to calculate the length of the I<salt> because it is not assumed to
be NULL terminated.
I<iter> is the iteration count and its value should be greater than or
equal to 1. RFC 2898 suggests an iteration count of at least 1000. Any
I<iter> less than 1 is treated as a single iteration.
I<digest> is the message digest function used in the derivation.
Functions ending in _ex() take optional parameters I<libctx> and I<propq> which
are used to select appropriate algorithm implementations.
=head1 NOTES
The functions are typically used in PKCS#12 to encrypt objects.
These functions make no assumption regarding the given password.
It will simply be treated as a byte sequence.
=head1 RETURN VALUES
PKCS12_PBE_keyivgen(), PKCS12_PBE_keyivgen_ex() return 1 on success or 0 on error.
PKCS12_pbe_crypt() and PKCS12_pbe_crypt_ex() return a buffer containing the
output or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<EVP_PBE_CipherInit_ex(3)>,
L<PKCS8_encrypt_ex(3)>,
L<passphrase-encoding(7)>
=head1 HISTORY
PKCS12_PBE_keyivgen_ex() and PKCS12_pbe_crypt_ex() were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2014-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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -4,8 +4,8 @@
PKCS12_SAFEBAG_create_cert, PKCS12_SAFEBAG_create_crl,
PKCS12_SAFEBAG_create_secret, PKCS12_SAFEBAG_create0_p8inf,
PKCS12_SAFEBAG_create0_pkcs8, PKCS12_SAFEBAG_create_pkcs8_encrypt - Create
PKCS#12 safeBag objects
PKCS12_SAFEBAG_create0_pkcs8, PKCS12_SAFEBAG_create_pkcs8_encrypt,
PKCS12_SAFEBAG_create_pkcs8_encrypt_ex - Create PKCS#12 safeBag objects
=head1 SYNOPSIS
@ -24,6 +24,14 @@ PKCS#12 safeBag objects
unsigned char *salt,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
const char *pass,
int passlen,
unsigned char *salt,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *ctx,
const char *propq);
=head1 DESCRIPTION
@ -34,7 +42,7 @@ PKCS12_SAFEBAG_create_crl() creates a new B<PKCS12_SAFEBAG> of type B<NID_crlBag
containing the supplied crl.
PKCS12_SAFEBAG_create_secret() creates a new B<PKCS12_SAFEBAG> of type
corresponding to a PKCS#12 I<secretBag>. The I<secretBag> contents are tagged as
corresponding to a PKCS#12 B<secretBag>. The B<secretBag> contents are tagged as
I<type> with an ASN1 value of type I<vtype> constructed using the bytes in
I<value> of length I<len>.
@ -50,6 +58,10 @@ If I<pbe_nid> is 0, a default encryption algorithm is used. I<pass> is the
passphrase and I<iter> is the iteration count. If I<iter> is zero then a default
value of 2048 is used. If I<salt> is NULL then a salt is generated randomly.
PKCS12_SAFEBAG_create_pkcs8_encrypt_ex() is identical to PKCS12_SAFEBAG_create_pkcs8_encrypt()
but allows for a library context I<ctx> and property query I<propq> to be used to select
algorithm implementations.
=head1 NOTES
PKCS12_SAFEBAG_create_pkcs8_encrypt() makes assumptions regarding the encoding of the given pass
@ -62,15 +74,23 @@ PKCS12_SAFEBAG_create_secret() was added in OpenSSL 3.0.
All of these functions return a valid B<PKCS12_SAFEBAG> structure or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<PKCS12_create(3)>,
L<PKCS12_add_safe(3)>,
L<PKCS12_add_safes(3)>
=head1 HISTORY
PKCS12_SAFEBAG_create_pkcs8_encrypt_ex() was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2019-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

View File

@ -2,7 +2,7 @@
=head1 NAME
PKCS12_add_cert, PKCS12_add_key,
PKCS12_add_cert, PKCS12_add_key, PKCS12_add_key_ex,
PKCS12_add_secret - Add an object to a set of PKCS#12 safeBags
=head1 SYNOPSIS
@ -13,6 +13,11 @@ PKCS12_add_secret - Add an object to a set of PKCS#12 safeBags
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int key_nid, const char *pass);
PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int key_nid, const char *pass,
OSSL_LIB_CTX *ctx, const char *propq);
PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
int nid_type, const unsigned char *value, int len);
@ -30,13 +35,17 @@ safeBags. If I<key_nid> is not -1 then the key is encrypted with the supplied
algorithm, using I<pass> as the passphrase and I<iter> as the iteration count. If
I<iter> is zero then a default value for iteration count of 2048 is used.
PKCS12_add_key_ex() is identical to PKCS12_add_key() but allows for a library
context I<ctx> and property query I<propq> to be used to select algorithm
implementations.
PKCS12_add_secret() creates a PKCS#12 secretBag with an OID corresponding to
the supplied B<nid_type> containing the supplied value as an ASN1 octet string.
the supplied I<nid_type> containing the supplied value as an ASN1 octet string.
This is then added to the set of PKCS#12 safeBags.
=head1 NOTES
If a certificate contains an B<alias> or a B<keyid> then this will be
If a certificate contains an I<alias> or a I<keyid> then this will be
used for the corresponding B<friendlyName> or B<localKeyID> in the
PKCS12 structure.
@ -44,19 +53,25 @@ PKCS12_add_key() makes assumptions regarding the encoding of the given pass
phrase.
See L<passphrase-encoding(7)> for more information.
PKCS12_add_secret() was added in OpenSSL 3.0.
=head1 RETURN VALUES
A valid B<PKCS12_SAFEBAG> structure or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<PKCS12_create(3)>
=head1 HISTORY
PKCS12_add_secret() and PKCS12_add_key_ex() were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2020-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

View File

@ -2,7 +2,8 @@
=head1 NAME
PKCS12_add_safe, PKCS12_add_safes - Create and add objects to a PKCS#12 structure
PKCS12_add_safe, PKCS12_add_safe_ex,
PKCS12_add_safes, PKCS12_add_safes_ex - Create and add objects to a PKCS#12 structure
=head1 SYNOPSIS
@ -10,7 +11,13 @@ PKCS12_add_safe, PKCS12_add_safes - Create and add objects to a PKCS#12 structur
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int safe_nid, int iter, const char *pass);
int PKCS12_add_safe_ex(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int safe_nid, int iter, const char *pass,
OSSL_LIB_CTX *ctx, const char *propq);
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
PKCS12 *PKCS12_add_safes_ex(STACK_OF(PKCS7) *safes, int p7_nid,
OSSL_LIB_CTX *ctx, const char *propq);
=head1 DESCRIPTION
@ -32,10 +39,18 @@ a default encryption algorithm, currently B<NID_pbe_WithSHA1And3_Key_TripleDES_C
=back
PKCS12_add_safe_ex() is identical to PKCS12_add_safe() but allows for a library
context I<ctx> and property query I<propq> to be used to select algorithm
implementations.
PKCS12_add_safes() creates a B<PKCS12> structure containing the supplied set of
PKCS7 contentInfos. The I<safes> are enclosed first within a PKCS7 contentInfo
of type I<p7_nid>. Currently the only supported type is B<NID_pkcs7_data>.
PKCS12_add_safes_ex() is identical to PKCS12_add_safes() but allows for a
library context I<ctx> and property query I<propq> to be used to select
algorithm implementations.
=head1 NOTES
PKCS12_add_safe() makes assumptions regarding the encoding of the given pass
@ -48,13 +63,21 @@ PKCS12_add_safe() returns a value of 1 indicating success or 0 for failure.
PKCS12_add_safes() returns a valid B<PKCS12> structure or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<PKCS12_create(3)>
=head1 HISTORY
PKCS12_add_safe_ex() and PKCS12_add_safes_ex() were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2020-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

View File

@ -2,7 +2,7 @@
=head1 NAME
PKCS12_create - create a PKCS#12 structure
PKCS12_create, PKCS12_create_ex - create a PKCS#12 structure
=head1 SYNOPSIS
@ -11,6 +11,10 @@ PKCS12_create - create a PKCS#12 structure
PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey,
X509 *cert, STACK_OF(X509) *ca,
int nid_key, int nid_cert, int iter, int mac_iter, int keytype);
PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey,
X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert,
int iter, int mac_iter, int keytype,
OSSL_LIB_CTX *ctx, const char *propq);
=head1 DESCRIPTION
@ -18,7 +22,7 @@ PKCS12_create() creates a PKCS#12 structure.
I<pass> is the passphrase to use. I<name> is the B<friendlyName> to use for
the supplied certificate and key. I<pkey> is the private key to include in
the structure and I<cert> its corresponding certificates. I<ca>, if not NULL
the structure and I<cert> its corresponding certificates. I<ca>, if not B<NULL>
is an optional set of certificates to also include in the structure.
I<nid_key> and I<nid_cert> are the encryption algorithms that should be used
@ -27,6 +31,9 @@ GCM, CCM, XTS, and OCB are unsupported. I<iter> is the encryption algorithm
iteration count to use and I<mac_iter> is the MAC iteration count to use.
I<keytype> is the type of key.
PKCS12_create_ex() is identical to PKCS12_create() but allows for a library context
I<ctx> and property query I<propq> to be used to select algorithm implementations.
=head1 NOTES
The parameters I<nid_key>, I<nid_cert>, I<iter>, I<mac_iter> and I<keytype>
@ -37,6 +44,10 @@ AES-256-CBC) for private keys and certificates, the PBKDF2 and MAC key
derivation iteration count of B<PKCS12_DEFAULT_ITER> (currently 2048), and
MAC algorithm HMAC with SHA2-256.
The default MAC iteration count is 1 in order to retain compatibility with
old software which did not interpret MAC iteration counts. If such compatibility
is not required then I<mac_iter> should be set to PKCS12_DEFAULT_ITER.
I<keytype> adds a flag to the store private key. This is a non standard extension
that is only currently interpreted by MSIE. If set to zero the flag is omitted,
if set to B<KEY_SIG> the key can be used for signing only, if set to B<KEY_EX>
@ -49,7 +60,7 @@ If a certificate contains an I<alias> or I<keyid> then this will be
used for the corresponding B<friendlyName> or B<localKeyID> in the
PKCS12 structure.
Either I<pkey>, I<cert> or both can be NULL to indicate that no key or
Either I<pkey>, I<cert> or both can be B<NULL> to indicate that no key or
certificate is required. In previous versions both had to be present or
a fatal error is returned.
@ -66,6 +77,10 @@ See L<passphrase-encoding(7)> for more information.
PKCS12_create() returns a valid B<PKCS12> structure or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<d2i_PKCS12(3)>,
@ -73,6 +88,8 @@ L<passphrase-encoding(7)>
=head1 HISTORY
PKCS12_create_ex() was added in OpenSSL 3.0.
The defaults for encryption algorithms, MAC algorithm, and the MAC key
derivation iteration count were changed in OpenSSL 3.0 to more modern
standards.

View File

@ -0,0 +1,55 @@
=pod
=head1 NAME
PKCS12_decrypt_skey, PKCS12_decrypt_skey_ex - PKCS12 shrouded keyBag
decrypt functions
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag,
const char *pass, int passlen);
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey_ex(const PKCS12_SAFEBAG *bag,
const char *pass, int passlen,
OSSL_LIB_CTX *ctx,
const char *propq);
=head1 DESCRIPTION
PKCS12_decrypt_skey() Decrypt the PKCS#8 shrouded keybag contained within I<bag>
using the supplied password I<pass> of length I<passlen>.
PKCS12_decrypt_skey_ex() is similar to the above but allows for a library context
I<ctx> and property query I<propq> to be used to select algorithm implementations.
=head1 RETURN VALUES
Both functions will return the decrypted key or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<PKCS8_decrypt_ex(3)>,
L<PKCS8_encrypt_ex(3)>,
L<PKCS12_add_key_ex(3)>,
L<PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(3)>
=head1 HISTORY
PKCS12_decrypt_skey_ex() was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,72 @@
=pod
=head1 NAME
PKCS12_gen_mac, PKCS12_setup_mac, PKCS12_set_mac,
PKCS12_verify_mac - Functions to create and manipulate a PKCS#12 structure
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *mac, unsigned int *maclen);
int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
const EVP_MD *md_type);
int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
int saltlen, const EVP_MD *md_type);
=head1 DESCRIPTION
PKCS12_gen_mac() generates an HMAC over the entire PKCS#12 object using the
supplied password along with a set of already configured paramters.
PKCS12_verify_mac() verifies the PKCS#12 object's HMAC using the supplied
password.
PKCS12_setup_mac() sets the MAC part of the PKCS#12 structure with the supplied
parameters.
PKCS12_set_mac() sets the MAC and MAC parameters into the PKCS#12 object.
I<pass> is the passphrase to use in the HMAC. I<salt> is the salt value to use,
I<iter> is the iteration count and I<md_type> is the message digest
function to use.
=head1 NOTES
If I<salt> is NULL then a suitable salt will be generated and used.
If I<iter> is 1 then an iteration count will be omitted from the PKCS#12
structure.
PKCS12_gen_mac(), PKCS12_verify_mac() and PKCS12_set_mac() make assumptions
regarding the encoding of the given passphrase. See L<passphrase-encoding(7)>
for more information.
=head1 RETURN VALUES
All functions return 1 on success and 0 if an error occurred.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<d2i_PKCS12(3)>,
L<PKCS12_create(3)>,
L<passphrase-encoding(7)>
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

48
doc/man3/PKCS12_init.pod Normal file
View File

@ -0,0 +1,48 @@
=pod
=head1 NAME
PKCS12_init, PKCS12_init_ex - Create a new empty PKCS#12 structure
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
PKCS12 *PKCS12_init(int mode);
PKCS12 *PKCS12_init_ex(int mode, OSSL_LIB_CTX *ctx, const char *propq);
=head1 DESCRIPTION
PKCS12_init() creates an empty PKCS#12 structure. Any PKCS#7 authSafes added
to this structure are enclosed first within a single PKCS#7 contentInfo
of type I<mode>. Currently the only supported type is B<NID_pkcs7_data>.
PKCS12_init_ex() creates an empty PKCS#12 structure and assigns the supplied
I<ctx> and I<propq> to be used to select algorithm implementations for
operations performed on the B<PKCS12> object.
=head1 RETURN VALUES
PKCS12_init() and PKCS12_init_ex() return a valid B<PKCS12> structure or NULL
if an error occurred.
=head1 SEE ALSO
L<d2i_PKCS12(3)>,
L<PKCS12_create(3)>,
L<passphrase-encoding(7)>
=head1 HISTORY
PKCS12_init_ex() was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,73 @@
=pod
=head1 NAME
PKCS12_item_decrypt_d2i, PKCS12_item_decrypt_d2i_ex,
PKCS12_item_i2d_encrypt, PKCS12_item_i2d_encrypt_ex - PKCS12 item
encrypt/decrypt functions
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf);
void *PKCS12_item_decrypt_d2i_ex(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf,
OSSL_LIB_CTX *libctx,
const char *propq);
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf);
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt_ex(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf,
OSSL_LIB_CTX *ctx,
const char *propq);
=head1 DESCRIPTION
PKCS12_item_decrypt_d2i() and PKCS12_item_decrypt_d2i_ex() decrypt an octet
string containing an ASN.1 encoded object using the algorithm I<algor> and
password I<pass> of length I<passlen>. If I<zbuf> is nonzero then the output
buffer will zeroed after the decrypt.
PKCS12_item_i2d_encrypt() and PKCS12_item_i2d_encrypt_ex() encrypt an ASN.1
object I<it> using the algorithm I<algor> and password I<pass> of length
I<passlen>, returning an encoded object in I<obj>. If I<zbuf> is nonzero then
the buffer containing the input encoding will be zeroed after the encrypt.
Functions ending in _ex() allow for a library context I<ctx> and property query
I<propq> to be used to select algorithm implementations.
=head1 RETURN VALUES
PKCS12_item_decrypt_d2i() and PKCS12_item_decrypt_d2i_ex() return the decrypted
object or NULL if an error occurred.
PKCS12_item_i2d_encrypt() and PKCS12_item_i2d_encrypt_ex() return the encrypted
data as an ASN.1 Octet String or NULL if an error occurred.
=head1 SEE ALSO
L<PKCS12_pbe_crypt_ex(3)>,
L<PKCS8_encrypt_ex(3)>
=head1 HISTORY
PKCS12_item_decrypt_d2i_ex() and PKCS12_item_i2d_encrypt_ex() were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,138 @@
=pod
=head1 NAME
PKCS12_key_gen_asc, PKCS12_key_gen_asc_ex,
PKCS12_key_gen_uni, PKCS12_key_gen_uni_ex,
PKCS12_key_gen_utf8, PKCS12_key_gen_utf8_ex - PKCS#12 Password based key derivation
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq);
=head1 DESCRIPTION
These methods perform a key derivation according to PKCS#12 (RFC7292)
with an input password I<pass> of length I<passlen>, a salt I<salt> of length
I<saltlen>, an iteration count I<iter> and a digest algorithm I<md_type>.
The ID byte I<id> determines how the resulting key is intended to be used:
=over 4
=item *
If ID=1, then the pseudorandom bits being produced are to be used
as key material for performing encryption or decryption.
=item *
If ID=2, then the pseudorandom bits being produced are to be used
as an IV (Initial Value) for encryption or decryption.
=item *
If ID=3, then the pseudorandom bits being produced are to be used
as an integrity key for MACing.
=back
The intended format of the supplied password is determined by the method chosen:
=over 4
=item *
PKCS12_key_gen_asc() and PKCS12_key_gen_asc_ex() expect an ASCII-formatted password.
=item *
PKCS12_key_gen_uni() and PKCS12_key_gen_uni_ex() expect a Unicode-formatted password.
=item *
PKCS12_key_gen_utf8() and PKCS12_key_gen_utf8_ex() expect a UTF-8 encoded password.
=back
I<pass> is the password used in the derivation of length I<passlen>. I<pass>
is an optional parameter and can be NULL. If I<passlen> is -1, then the
function will calculate the length of I<pass> using strlen().
I<salt> is the salt used in the derivation of length I<saltlen>. If the
I<salt> is NULL, then I<saltlen> must be 0. The function will not
attempt to calculate the length of the I<salt> because it is not assumed to
be NULL terminated.
I<iter> is the iteration count and its value should be greater than or
equal to 1. RFC 2898 suggests an iteration count of at least 1000. Any
I<iter> less than 1 is treated as a single iteration.
I<digest> is the message digest function used in the derivation.
The derived key will be written to I<out>. The size of the I<out> buffer
is specified via I<n>.
Functions ending in _ex() allow for a library context I<ctx> and property query
I<propq> to be used to select algorithm implementations.
=head1 NOTES
A typical application of this function is to derive keying material for an
encryption algorithm from a password in the I<pass>, a salt in I<salt>,
and an iteration count.
Increasing the I<iter> parameter slows down the algorithm which makes it
harder for an attacker to perform a brute force attack using a large number
of candidate passwords.
=head1 RETURN VALUES
Returns 1 on success or 0 on error.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<PKCS12_create_ex(3)>,
L<PKCS12_pbe_crypt_ex(3)>,
L<passphrase-encoding(7)>
=head1 HISTORY
PKCS12_key_gen_asc_ex(), PKCS12_key_gen_uni_ex() and PKCS12_key_gen_utf8_ex()
were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,59 @@
=pod
=head1 NAME
PKCS12_pack_p7encdata, PKCS12_pack_p7encdata_ex - Pack a set of PKCS#12 safeBags
into a PKCS#7 encrypted data object
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags);
PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags,
OSSL_LIB_CTX *ctx, const char *propq);
=head1 DESCRIPTION
PKCS12_pack_p7encdata() generates a PKCS#7 ContentInfo object of encrypted-data
type from the set of safeBags I<bags>. The algorithm ID in I<pbe_nid> can be
a PKCS#12 or PKCS#5 password based encryption algorithm, or a cipher algorithm.
If a cipher algorithm is passed, the PKCS#5 PBES2 algorithm will be used with
this cipher as a parameter.
The password I<pass> of length I<passlen>, salt I<salt> of length I<saltlen>
and iteration count I<iter> are inputs into the encryption operation.
PKCS12_pack_p7encdata_ex() operates similar to the above but allows for a
library context I<ctx> and property query I<propq> to be used to select the
algorithm implementation.
=head1 RETURN VALUES
A B<PKCS7> object if successful, or NULL if an error occurred.
=head1 CONFORMING TO
IETF RFC 2315 (L<https://tools.ietf.org/html/rfc2315>)
=head1 SEE ALSO
L<PKCS12_pbe_crypt_ex(3)>
=head1 HISTORY
PKCS12_pack_p7encdata_ex() was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,170 @@
=pod
=head1 NAME
PKCS5_PBE_keyivgen, PKCS5_pbe2_set, PKCS5_pbe2_set_iv,
PKCS5_pbe2_set_iv_ex, PKCS5_pbe_set, PKCS5_pbe_set_ex, PKCS5_pbe2_set_scrypt,
PKCS5_pbe_set0_algor, PKCS5_pbe_set0_algor_ex,
PKCS5_v2_PBE_keyivgen, PKCS5_v2_PBE_keyivgen_ex,
PKCS5_v2_scrypt_keyivgen, PKCS5_v2_scrypt_keyivgen_ex,
PKCS5_pbkdf2_set, PKCS5_pbkdf2_set_ex, EVP_PBE_scrypt, EVP_PBE_scrypt_ex
- PKCS#5 Password based encryption routines
=head1 SYNOPSIS
#include <openssl/evp.h>
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de);
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de);
int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
int EVP_PBE_scrypt(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen);
int EVP_PBE_scrypt_ex(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de);
int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
#include <openssl/x509.h>
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen);
int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid);
X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
const unsigned char *salt, int saltlen,
unsigned char *aiv, uint64_t N, uint64_t r,
uint64_t p);
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen);
X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen,
OSSL_LIB_CTX *libctx);
=head1 DESCRIPTION
=head2 Key Derivation
PKCS5_PBE_keyivgen() takes a password I<pass> of
length I<passlen>, parameters I<param> and a message digest function I<md_type>
and performs a key derivation according to PKCS#5 PBES1. The resulting key is
then used to initialise the cipher context I<ctx> with a cipher I<cipher> for
encryption (I<en_de>=1) or decryption (I<en_de>=0).
I<pass> is an optional parameter and can be NULL. If I<passlen> is -1, then the
function will calculate the length of I<pass> using strlen().
PKCS5_v2_PBE_keyivgen() and PKCS5_v2_PBE_keyivgen_ex() are similar to the above
but instead use PKCS#5 PBES2 as the encryption algorithm using the supplied
parameters.
PKCS5_v2_scrypt_keyivgen() and PKCS5_v2_scrypt_keyivgen_ex() use SCRYPT as the
key derivation part of the encryption algorithm.
I<salt> is the salt used in the derivation of length I<saltlen>. If the
I<salt> is NULL, then I<saltlen> must be 0. The function will not
attempt to calculate the length of the I<salt> because it is not assumed to
be NULL terminated.
I<iter> is the iteration count and its value should be greater than or
equal to 1. RFC 2898 suggests an iteration count of at least 1000. Any
I<iter> less than 1 is treated as a single iteration.
I<digest> is the message digest function used in the derivation.
Functions ending in _ex() take optional parameters I<libctx> and I<propq> which
are used to select appropriate algorithm implementations.
=head2 Algorithm Identifier Creation
PKCS5_pbe_set(), PKCS5_pbe_set_ex(), PKCS5_pbe2_set(), PKCS5_pbe2_set_iv(),
PKCS5_pbe2_set_iv_ex() and PKCS5_pbe2_set_scrypt() generate an B<X509_ALGOR>
object which represents an AlgorithmIdentifier containing the algorithm OID and
associated parameters for the PBE algorithm.
PKCS5_pbkdf2_set() and PKCS5_pbkdf2_set_ex() generate an B<X509_ALGOR>
object which represents an AlgorithmIdentifier containing the algorithm OID and
associated parameters for the PBKDF2 algorithm.
PKCS5_pbe_set0_algor() and PKCS5_pbe_set0_algor_ex() set the PBE algorithm OID and
parameters into the supplied B<X509_ALGOR>.
=head1 NOTES
The *_keyivgen() functions are typically used in PKCS#12 to encrypt objects.
These functions make no assumption regarding the given password.
It will simply be treated as a byte sequence.
=head1 RETURN VALUES
PKCS5_PBE_keyivgen(), PKCS5_v2_PBE_keyivgen(),
PKCS5_v2_PBE_keyivgen_ex(), PKCS5_v2_scrypt_keyivgen(),
PKCS5_v2_scrypt_keyivgen_ex(), PKCS5_pbe_set0_algor() and
PKCS5_pbe_set0_algor_ex() return 1 for success and 0 if an error occurs.
PKCS5_pbe_set(), PKCS5_pbe_set_ex(), PKCS5_pbe2_set(), PKCS5_pbe2_set_iv(),
PKCS5_pbe2_set_iv_ex(), PKCS5_pbe2_set_scrypt(),
PKCS5_pbkdf2_set() and PKCS5_pbkdf2_set_ex() return an B<X509_ALGOR> object or
NULL if an error occurs.
=head1 CONFORMING TO
IETF RFC 8018 (L<https://tools.ietf.org/html/rfc8018>)
=head1 SEE ALSO
L<EVP_PBE_CipherInit_ex(3)>,
L<PKCS12_pbe_crypt_ex(3)>,
L<passphrase-encoding(7)>
=head1 HISTORY
PKCS5_v2_PBE_keyivgen_ex(), EVP_PBE_scrypt_ex(), PKCS5_v2_scrypt_keyivgen_ex(),
PKCS5_pbe_set0_algor_ex(), PKCS5_pbe_set_ex(), PKCS5_pbe2_set_iv_ex() and
PKCS5_pbkdf2_set_ex() were added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -35,9 +35,8 @@ B<iter> is the iteration count and its value should be greater than or
equal to 1. RFC 2898 suggests an iteration count of at least 1000. Any
B<iter> less than 1 is treated as a single iteration.
B<digest> is the message digest function used in the derivation. Values include
any of the EVP_* message digests. PKCS5_PBKDF2_HMAC_SHA1() calls
PKCS5_PBKDF2_HMAC() with EVP_sha1().
B<digest> is the message digest function used in the derivation.
PKCS5_PBKDF2_HMAC_SHA1() calls PKCS5_PBKDF2_HMAC() with EVP_sha1().
The derived key will be written to B<out>. The size of the B<out> buffer
is specified via B<keylen>.

View File

@ -0,0 +1,78 @@
=pod
=head1 NAME
PKCS8_decrypt, PKCS8_decrypt_ex, PKCS8_encrypt, PKCS8_encrypt_ex,
PKCS8_set0_pbe, PKCS8_set0_pbe_ex - PKCS8 encrypt/decrypt functions
=head1 SYNOPSIS
#include <openssl/x509.h>
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
int passlen);
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_ex(const X509_SIG *p8, const char *pass,
int passlen, OSSL_LIB_CTX *ctx,
const char *propq);
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
X509_SIG *PKCS8_encrypt_ex(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8,
OSSL_LIB_CTX *ctx, const char *propq);
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe);
X509_SIG *PKCS8_set0_pbe_ex(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe,
OSSL_LIB_CTX *ctx);
=head1 DESCRIPTION
PKCS8_encrypt() and PKCS8_encrypt_ex() perform encryption of an object I<p8> using
the password I<pass> of length I<passlen>, salt I<salt> of length I<saltlen>
and iteration count I<iter>.
The resulting B<X509_SIG> contains the encoded algorithm parameters and encrypted
key.
PKCS8_decrypt() and PKCS8_decrypt_ex() perform decryption of an B<X509_SIG> in
I<p8> using the password I<pass> of length I<passlen> along with algorithm
parameters obtained from the I<p8>.
PKCS8_set0_pbe() and PKCS8_set0_pbe_ex() perform encryption of the I<p8inf>
using the password I<pass> of length I<passlen> and parameters I<pbe>.
Functions ending in _ex() allow for a library context I<ctx> and property query
I<propq> to be used to select algorithm implementations.
=head1 RETURN VALUES
PKCS8_encrypt(), PKCS8_encrypt_ex(), PKCS8_set0_pbe() and PKCS8_set0_pbe_ex()
return an encrypted key in a B<X509_SIG> structure or NULL if an error occurs.
PKCS8_decrypt() and PKCS8_decrypt_ex() return a B<PKCS8_PRIV_KEY_INFO> or NULL
if an error occurs.
=head1 CONFORMING TO
IETF RFC 7292 (L<https://tools.ietf.org/html/rfc7292>)
=head1 SEE ALSO
L<crypto(7)>
=head1 HISTORY
PKCS8_decrypt_ex(), PKCS8_encrypt_ex() and PKCS8_set0_pbe_ex() were added in
OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 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
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -13,4 +13,7 @@
void ossl_pkcs7_resolve_libctx(PKCS7 *p7);
void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx);
int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq);
#endif

View File

@ -207,7 +207,6 @@ extern "C" {
#define OSSL_KDF_PARAM_SSHKDF_SESSION_ID "session_id" /* octet string */
#define OSSL_KDF_PARAM_SSHKDF_TYPE "type" /* int */
#define OSSL_KDF_PARAM_SIZE "size" /* size_t */
#define OSSL_KDF_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */
#define OSSL_KDF_PARAM_CONSTANT "constant" /* octet string */
#define OSSL_KDF_PARAM_PKCS12_ID "id" /* int */
#define OSSL_KDF_PARAM_KBKDF_USE_L "use-l" /* int */

View File

@ -487,6 +487,11 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
const EVP_CIPHER *cipher, const EVP_MD *md,
int en_de);
typedef int (EVP_PBE_KEYGEN_EX) (EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *cipher, const EVP_MD *md,
int en_de, OSSL_LIB_CTX *libctx, const char *propq);
# ifndef OPENSSL_NO_DEPRECATED_3_0
# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
(rsa))
@ -1432,16 +1437,29 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de);
int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
#ifndef OPENSSL_NO_SCRYPT
int EVP_PBE_scrypt(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen);
int EVP_PBE_scrypt_ex(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de);
int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
#endif
void PKCS5_PBE_add(void);
@ -1449,6 +1467,10 @@ void PKCS5_PBE_add(void);
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
int EVP_PBE_CipherInit_ex(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
/* PBE type */
/* Can appear as the outermost AlgorithmIdentifier */
@ -1464,6 +1486,8 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
EVP_PBE_KEYGEN *keygen);
int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
EVP_PBE_KEYGEN **pkeygen);
int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid,
EVP_PBE_KEYGEN **pkeygen, EVP_PBE_KEYGEN_EX **pkeygen_ex);
void EVP_PBE_cleanup(void);
int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num);

View File

@ -23,6 +23,7 @@ use OpenSSL::stackhash qw(generate_stack_macros);
# endif
# include <openssl/bio.h>
# include <openssl/core.h>
# include <openssl/x509.h>
# include <openssl/pkcs12err.h>
@ -124,23 +125,50 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
unsigned char *salt,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
const char *pass,
int passlen,
unsigned char *salt,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *ctx,
const char *propq);
PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
int nid1, int nid2);
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
int passlen);
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_ex(const X509_SIG *p8, const char *pass,
int passlen, OSSL_LIB_CTX *ctx,
const char *propq);
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag,
const char *pass, int passlen);
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey_ex(const PKCS12_SAFEBAG *bag,
const char *pass, int passlen,
OSSL_LIB_CTX *ctx,
const char *propq);
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
X509_SIG *PKCS8_encrypt_ex(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int passlen, unsigned char *salt,
int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8,
OSSL_LIB_CTX *ctx, const char *propq);
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe);
X509_SIG *PKCS8_set0_pbe_ex(const char *pass, int passlen,
PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe,
OSSL_LIB_CTX *ctx, const char *propq);
PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags);
PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
STACK_OF(PKCS12_SAFEBAG) *bags,
OSSL_LIB_CTX *ctx, const char *propq);
STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
int passlen);
@ -172,26 +200,62 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen,
int en_de);
unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
const char *pass, int passlen,
const unsigned char *in, int inlen,
unsigned char **data, int *datalen,
int en_de, OSSL_LIB_CTX *libctx,
const char *propq);
void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf);
void *PKCS12_item_decrypt_d2i_ex(const X509_ALGOR *algor, const ASN1_ITEM *it,
const char *pass, int passlen,
const ASN1_OCTET_STRING *oct, int zbuf,
OSSL_LIB_CTX *libctx,
const char *propq);
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf);
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt_ex(X509_ALGOR *algor,
const ASN1_ITEM *it,
const char *pass, int passlen,
void *obj, int zbuf,
OSSL_LIB_CTX *ctx,
const char *propq);
PKCS12 *PKCS12_init(int mode);
PKCS12 *PKCS12_init_ex(int mode, OSSL_LIB_CTX *ctx, const char *propq);
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt,
int saltlen, int id, int iter, int n,
unsigned char *out, const EVP_MD *md_type,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md_type, int en_de);
int PKCS12_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md_type, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *mac, unsigned int *maclen);
int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
@ -221,16 +285,31 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey,
X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert,
int iter, int mac_iter, int keytype);
PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey,
X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert,
int iter, int mac_iter, int keytype,
OSSL_LIB_CTX *ctx, const char *propq);
PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int key_nid, const char *pass);
PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int key_nid, const char *pass,
OSSL_LIB_CTX *ctx, const char *propq);
PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
int nid_type, const unsigned char *value, int len);
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int safe_nid, int iter, const char *pass);
int PKCS12_add_safe_ex(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int safe_nid, int iter, const char *pass,
OSSL_LIB_CTX *ctx, const char *propq);
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
PKCS12 *PKCS12_add_safes_ex(STACK_OF(PKCS7) *safes, int p7_nid,
OSSL_LIB_CTX *ctx, const char *propq);
int i2d_PKCS12_bio(BIO *bp, const PKCS12 *p12);
# ifndef OPENSSL_NO_STDIO

View File

@ -1067,14 +1067,25 @@ DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS)
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen);
int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid);
X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid,
OSSL_LIB_CTX *libctx);
#ifndef OPENSSL_NO_SCRYPT
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
@ -1085,6 +1096,9 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen);
X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen,
OSSL_LIB_CTX *libctx);
/* PKCS#8 utilities */

View File

@ -22,7 +22,12 @@
#include "pkcs12.h" /* from the same directory */
/* Set this to > 0 write test data to file */
int write_files = 0;
static int write_files = 0;
static int legacy = 0;
static OSSL_LIB_CTX *test_ctx = NULL;
static const char *test_propq = NULL;
/* -------------------------------------------------------------------------
* Local function declarations
@ -40,6 +45,31 @@ static int check_asn1_string(const ASN1_TYPE *av, const char *txt);
static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs);
/* --------------------------------------------------------------------------
* Global settings
*/
void PKCS12_helper_set_write_files(int enable)
{
write_files = enable;
}
void PKCS12_helper_set_legacy(int enable)
{
legacy = enable;
}
void PKCS12_helper_set_libctx(OSSL_LIB_CTX *libctx)
{
test_ctx = libctx;
}
void PKCS12_helper_set_propq(const char *propq)
{
test_propq = propq;
}
/* --------------------------------------------------------------------------
* Test data load functions
*/
@ -116,6 +146,7 @@ void end_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
PKCS12 *p12;
EVP_MD *md = NULL;
if (!pb->success)
return;
@ -125,7 +156,10 @@ static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
pb->success = 0;
return;
}
p12 = PKCS12_add_safes(pb->safes, 0);
if (legacy)
p12 = PKCS12_add_safes(pb->safes, 0);
else
p12 = PKCS12_add_safes_ex(pb->safes, 0, test_ctx, test_propq);
if (!TEST_ptr(p12)) {
pb->success = 0;
goto err;
@ -133,8 +167,13 @@ static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
sk_PKCS7_pop_free(pb->safes, PKCS7_free);
if (mac != NULL) {
if (legacy)
md = (EVP_MD *)EVP_get_digestbynid(mac->nid);
else
md = EVP_MD_fetch(test_ctx, OBJ_nid2sn(mac->nid), test_propq);
if (!TEST_true(PKCS12_set_mac(p12, mac->pass, strlen(mac->pass),
NULL, 0, mac->iter, EVP_get_digestbynid(mac->nid)))) {
NULL, 0, mac->iter, md))) {
pb->success = 0;
goto err;
}
@ -145,6 +184,8 @@ static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
if (write_files)
write_p12(p12, pb->filename);
err:
if (!legacy && md != NULL)
EVP_MD_free(md);
PKCS12_free(p12);
}
@ -169,7 +210,13 @@ static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac)
{
PKCS12 *p12 = NULL;
p12 = d2i_PKCS12_bio(bio, NULL);
/* Supply a p12 with library context/propq to the d2i decoder*/
if (!legacy) {
p12 = PKCS12_init_ex(NID_pkcs7_data, test_ctx, test_propq);
if (!TEST_ptr(p12))
goto err;
}
p12 = d2i_PKCS12_bio(bio, &p12);
BIO_free(bio);
if (!TEST_ptr(p12))
goto err;
@ -245,10 +292,18 @@ void end_contentinfo(PKCS12_BUILDER *pb)
void end_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
{
if (pb->success) {
if (pb->bags
&& !TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, enc->nid, enc->iter, enc->pass))) {
pb->success = 0;
return;
if (pb->bags) {
if (legacy) {
if (!TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, enc->nid, enc->iter, enc->pass))) {
pb->success = 0;
return;
}
} else {
if (!TEST_true(PKCS12_add_safe_ex(&pb->safes, pb->bags, enc->nid, enc->iter, enc->pass, test_ctx, test_propq))) {
pb->success = 0;
return;
}
}
}
}
sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
@ -259,9 +314,13 @@ void end_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
static STACK_OF(PKCS12_SAFEBAG) *decode_contentinfo(STACK_OF(PKCS7) *safes, int idx, const PKCS12_ENC *enc)
{
STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
int bagnid;
PKCS7 *p7 = sk_PKCS7_value(safes, idx);
int bagnid = OBJ_obj2nid(p7->type);
if (!TEST_ptr(p7))
goto err;
bagnid = OBJ_obj2nid(p7->type);
if (enc) {
if (!TEST_int_eq(bagnid, NID_pkcs7_encrypted))
goto err;
@ -370,7 +429,11 @@ void add_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
return;
}
bag = PKCS12_add_key(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass);
if (legacy)
bag = PKCS12_add_key(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass);
else
bag = PKCS12_add_key_ex(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass,
test_ctx, test_propq);
if (!TEST_ptr(bag)) {
pb->success = 0;
goto err;
@ -550,7 +613,11 @@ void check_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
break;
case NID_pkcs8ShroudedKeyBag:
if (!TEST_ptr(p8 = PKCS12_decrypt_skey(bag, enc->pass, strlen(enc->pass)))) {
if (legacy)
p8 = PKCS12_decrypt_skey(bag, enc->pass, strlen(enc->pass));
else
p8 = PKCS12_decrypt_skey_ex(bag, enc->pass, strlen(enc->pass), test_ctx, test_propq);
if (!TEST_ptr(p8)) {
pb->success = 0;
goto err;
}
@ -601,7 +668,12 @@ void check_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret, con
void start_check_pkcs12(PKCS12_BUILDER *pb)
{
PKCS12 *p12 = from_bio_p12(pb->p12bio, NULL);
PKCS12 *p12;
if (!pb->success)
return;
p12 = from_bio_p12(pb->p12bio, NULL);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
@ -616,7 +688,12 @@ void start_check_pkcs12(PKCS12_BUILDER *pb)
void start_check_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
PKCS12 *p12 = from_bio_p12(pb->p12bio, mac);
PKCS12 *p12;
if (!pb->success)
return;
p12 = from_bio_p12(pb->p12bio, mac);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
@ -631,7 +708,12 @@ void start_check_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
void start_check_pkcs12_file(PKCS12_BUILDER *pb)
{
PKCS12 *p12 = read_p12(pb->filename, NULL);
PKCS12 *p12;
if (!pb->success)
return;
p12 = read_p12(pb->filename, NULL);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
@ -646,7 +728,12 @@ void start_check_pkcs12_file(PKCS12_BUILDER *pb)
void start_check_pkcs12_file_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
PKCS12 *p12 = read_p12(pb->filename, mac);
PKCS12 *p12;
if (!pb->success)
return;
p12 = read_p12(pb->filename, mac);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
@ -661,12 +748,18 @@ void start_check_pkcs12_file_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
void end_check_pkcs12(PKCS12_BUILDER *pb)
{
if (!pb->success)
return;
sk_PKCS7_pop_free(pb->safes, PKCS7_free);
}
void start_check_contentinfo(PKCS12_BUILDER *pb)
{
if (!pb->success)
return;
pb->bag_idx = 0;
pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, NULL);
if (!TEST_ptr(pb->bags)) {
@ -678,6 +771,9 @@ void start_check_contentinfo(PKCS12_BUILDER *pb)
void start_check_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
{
if (!pb->success)
return;
pb->bag_idx = 0;
pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, enc);
if (!TEST_ptr(pb->bags)) {
@ -690,6 +786,9 @@ void start_check_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc
void end_check_contentinfo(PKCS12_BUILDER *pb)
{
if (!pb->success)
return;
if (!TEST_int_eq(sk_PKCS12_SAFEBAG_num(pb->bags), pb->bag_idx))
pb->success = 0;
sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);

View File

@ -20,8 +20,6 @@
#include "../testutil.h"
/* Set this to > 0 write test data to file */
extern int write_files;
/* -------------------------------------------------------------------------
* PKCS#12 Test structures
@ -36,9 +34,9 @@ typedef struct pkcs12_attr {
/* Holds encryption parameters */
typedef struct pkcs12_enc {
int nid;
char *pass;
int iter;
int nid;
const char *pass;
int iter;
} PKCS12_ENC;
/* Set of variables required for constructing the PKCS#12 structure */
@ -57,6 +55,12 @@ typedef struct pkcs12_builder {
* PKCS#12 Test function declarations
*/
/* Global settings */
void PKCS12_helper_set_write_files(int enable);
void PKCS12_helper_set_legacy(int enable);
void PKCS12_helper_set_libctx(OSSL_LIB_CTX *libctx);
void PKCS12_helper_set_propq(const char *propq);
/* Allocate and initialise a PKCS#12 builder object */
PKCS12_BUILDER *new_pkcs12_builder(const char *filename);

View File

@ -21,6 +21,12 @@
#include "testutil.h"
#include "helpers/pkcs12.h"
static int default_libctx = 1;
static OSSL_LIB_CTX *testctx = NULL;
static OSSL_PROVIDER *nullprov = NULL;
static OSSL_PROVIDER *deflprov = NULL;
static OSSL_PROVIDER *lgcyprov = NULL;
/* --------------------------------------------------------------------------
* PKCS12 component test data
@ -200,7 +206,11 @@ static const PKCS12_ATTR ATTRS2[] = {
};
static const PKCS12_ENC enc_default = {
#ifndef OPENSSL_NO_DES
NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
#else
NID_aes_128_cbc,
#endif
"Password1",
1000
};
@ -211,6 +221,79 @@ static const PKCS12_ENC mac_default = {
1000
};
static const int enc_nids_all[] = {
/* NOTE: To use PBES2 we pass the desired cipher NID instead of NID_pbes2 */
NID_aes_128_cbc,
NID_aes_256_cbc,
#ifndef OPENSSL_NO_DES
NID_des_ede3_cbc,
NID_des_cbc,
#endif
#ifndef OPENSSL_NO_MD2
# ifndef OPENSSL_NO_DES
NID_pbeWithMD2AndDES_CBC,
# endif
# ifndef OPENSSL_NO_RC2
NID_pbeWithMD2AndRC2_CBC,
# endif
#endif
#ifndef OPENSSL_NO_MD5
# ifndef OPENSSL_NO_DES
NID_pbeWithMD5AndDES_CBC,
# endif
# ifndef OPENSSL_NO_RC2
NID_pbeWithMD5AndRC2_CBC,
# endif
#endif
#ifndef OPENSSL_NO_DES
NID_pbeWithSHA1AndDES_CBC,
#endif
#ifndef OPENSSL_NO_RC2
NID_pbe_WithSHA1And128BitRC2_CBC,
NID_pbe_WithSHA1And40BitRC2_CBC,
NID_pbeWithSHA1AndRC2_CBC,
#endif
#ifndef OPENSSL_NO_RC4
NID_pbe_WithSHA1And128BitRC4,
NID_pbe_WithSHA1And40BitRC4,
#endif
#ifndef OPENSSL_NO_DES
NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
#endif
};
static const int enc_nids_no_legacy[] = {
/* NOTE: To use PBES2 we pass the desired cipher NID instead of NID_pbes2 */
NID_aes_128_cbc,
NID_aes_256_cbc,
#ifndef OPENSSL_NO_DES
NID_des_ede3_cbc,
NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
#endif
};
static const int mac_nids[] = {
NID_sha1,
NID_md5,
NID_sha256,
NID_sha512,
NID_sha3_256,
NID_sha3_512
};
static const int iters[] = {
1,
1000
};
static const char *passwords[] = {
"Password1",
"",
};
/* --------------------------------------------------------------------------
* Local functions
@ -261,9 +344,79 @@ static int test_single_cert_no_attrs(void)
return end_pkcs12_builder(pb);
}
static int test_single_key(PKCS12_ENC *enc)
{
char fname[80];
PKCS12_BUILDER *pb;
sprintf(fname, "1key_ciph-%s_iter-%d.p12", OBJ_nid2sn(enc->nid), enc->iter);
pb = new_pkcs12_builder(fname);
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_keybag(pb, KEY1, sizeof(KEY1), NULL, enc);
end_contentinfo(pb);
end_pkcs12(pb);
/* Read/decode */
start_check_pkcs12(pb);
start_check_contentinfo(pb);
check_keybag(pb, KEY1, sizeof(KEY1), NULL, enc);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_single_key_enc_alg(int z)
{
PKCS12_ENC enc;
if (lgcyprov == NULL)
enc.nid = enc_nids_no_legacy[z];
else
enc.nid = enc_nids_all[z];
enc.pass = enc_default.pass;
enc.iter = enc_default.iter;
return test_single_key(&enc);
}
static int test_single_key_enc_pass(int z)
{
PKCS12_ENC enc;
enc.nid = enc_default.nid;
enc.pass = passwords[z];
enc.iter = enc_default.iter;
return test_single_key(&enc);
}
static int test_single_key_enc_iter(int z)
{
PKCS12_ENC enc;
enc.nid = enc_default.nid;
enc.pass = enc_default.pass;
enc.iter = iters[z];
return test_single_key(&enc);
}
static int test_single_key_with_attrs(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1key.p12");
PKCS12_BUILDER *pb = new_pkcs12_builder("1keyattrs.p12");
/* Generate/encode */
start_pkcs12(pb);
@ -290,6 +443,73 @@ static int test_single_key_with_attrs(void)
return end_pkcs12_builder(pb);
}
static int test_single_cert_mac(PKCS12_ENC *mac)
{
char fname[80];
PKCS12_BUILDER *pb;
sprintf(fname, "1cert_mac-%s_iter-%d.p12", OBJ_nid2sn(mac->nid), mac->iter);
pb = new_pkcs12_builder(fname);
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_certbag(pb, CERT1, sizeof(CERT1), NULL);
end_contentinfo(pb);
end_pkcs12_with_mac(pb, mac);
/* Read/decode */
start_check_pkcs12_with_mac(pb, mac);
start_check_contentinfo(pb);
check_certbag(pb, CERT1, sizeof(CERT1), NULL);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_single_cert_mac_alg(int z)
{
PKCS12_ENC mac;
mac.nid = mac_nids[z];
mac.pass = mac_default.pass;
mac.iter = mac_default.iter;
return test_single_cert_mac(&mac);
}
static int test_single_cert_mac_pass(int z)
{
PKCS12_ENC mac;
mac.nid = mac_default.nid;
mac.pass = passwords[z];
mac.iter = mac_default.iter;
return test_single_cert_mac(&mac);
}
static int test_single_cert_mac_iter(int z)
{
PKCS12_ENC mac;
mac.nid = mac_default.nid;
mac.pass = mac_default.pass;
mac.iter = iters[z];
return test_single_cert_mac(&mac);
}
static int test_cert_key_with_attrs_and_mac(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1cert1key.p12");
@ -430,11 +650,86 @@ static int test_multiple_contents(void)
return end_pkcs12_builder(pb);
}
typedef enum OPTION_choice {
OPT_ERR = -1,
OPT_EOF = 0,
OPT_WRITE,
OPT_LEGACY,
OPT_CONTEXT,
OPT_TEST_ENUM
} OPTION_CHOICE;
const OPTIONS *test_get_options(void)
{
static const OPTIONS options[] = {
OPT_TEST_OPTIONS_DEFAULT_USAGE,
{ "write", OPT_WRITE, '-', "Write PKCS12 objects to file" },
{ "legacy", OPT_LEGACY, '-', "Test the legacy APIs" },
{ "context", OPT_CONTEXT, '-', "Explicitly use a non-default library context" },
{ NULL }
};
return options;
}
int setup_tests(void)
{
OPTION_CHOICE o;
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
case OPT_WRITE:
PKCS12_helper_set_write_files(1);
break;
case OPT_LEGACY:
PKCS12_helper_set_legacy(1);
break;
case OPT_CONTEXT:
default_libctx = 0;
break;
case OPT_TEST_CASES:
break;
default:
return 0;
}
}
if (!default_libctx) {
testctx = OSSL_LIB_CTX_new();
if (!TEST_ptr(testctx))
return 0;
nullprov = OSSL_PROVIDER_load(NULL, "null");
if (!TEST_ptr(nullprov))
return 0;
}
deflprov = OSSL_PROVIDER_load(testctx, "default");
if (!TEST_ptr(deflprov))
return 0;
lgcyprov = OSSL_PROVIDER_load(testctx, "legacy");
PKCS12_helper_set_libctx(testctx);
/*
* Verify that the default and fips providers in the default libctx are not
* available if we are using a standalone context
*/
if (!default_libctx) {
if (!TEST_false(OSSL_PROVIDER_available(NULL, "default"))
|| !TEST_false(OSSL_PROVIDER_available(NULL, "fips")))
return 0;
}
ADD_TEST(test_single_cert_no_attrs);
if (lgcyprov == NULL)
ADD_ALL_TESTS(test_single_key_enc_alg, OSSL_NELEM(enc_nids_no_legacy));
else
ADD_ALL_TESTS(test_single_key_enc_alg, OSSL_NELEM(enc_nids_all));
ADD_ALL_TESTS(test_single_key_enc_pass, OSSL_NELEM(passwords));
ADD_ALL_TESTS(test_single_key_enc_iter, OSSL_NELEM(iters));
ADD_TEST(test_single_key_with_attrs);
ADD_ALL_TESTS(test_single_cert_mac_alg, OSSL_NELEM(mac_nids));
ADD_ALL_TESTS(test_single_cert_mac_pass, OSSL_NELEM(passwords));
ADD_ALL_TESTS(test_single_cert_mac_iter, OSSL_NELEM(iters));
ADD_TEST(test_cert_key_with_attrs_and_mac);
ADD_TEST(test_cert_key_encrypted_content);
ADD_TEST(test_single_secret_encrypted_content);
@ -442,3 +737,10 @@ int setup_tests(void)
return 1;
}
void cleanup_tests(void)
{
OSSL_PROVIDER_unload(nullprov);
OSSL_PROVIDER_unload(deflprov);
OSSL_PROVIDER_unload(lgcyprov);
OSSL_LIB_CTX_free(testctx);
}

View File

@ -16,9 +16,6 @@ use Encode;
setup("test_pkcs12");
plan skip_all => "The PKCS12 command line utility is not supported by this OpenSSL build"
if disabled("des");
my $pass = "σύνθημα γνώρισμα";
my $savedcp;
@ -57,10 +54,14 @@ if (eval { require Win32::API; 1; }) {
}
$ENV{OPENSSL_WIN32_UTF8}=1;
plan tests => 5;
plan tests => 7;
# Test different PKCS#12 formats
ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats");
# Test with legacy APIs
ok(run(test(["pkcs12_format_test", "-legacy"])), "test pkcs12 formats using legacy APIs");
# Test with a non-default library context (and no loaded providers in the default context)
ok(run(test(["pkcs12_format_test", "-context"])), "test pkcs12 formats using a non-default library context");
# just see that we can read shibboleth.pfx protected with $pass
ok(run(app(["openssl", "pkcs12", "-noout",
@ -82,13 +83,17 @@ ok(run(app(["openssl", "pkcs12", "-export", "-chain",
"test_pkcs12_chain_untrusted");
# Test the -passcerts option
ok(run(app(["openssl", "pkcs12", "-export",
SKIP: {
skip "Skipping PKCS#12 test because DES is disabled in this build", 1
if disabled("des");
ok(run(app(["openssl", "pkcs12", "-export",
"-in", srctop_file(@path, "ee-cert.pem"),
"-certfile", srctop_file(@path, "v3-certs-TDES.p12"),
"-passcerts", "pass:v3-certs",
"-nokeys", "-passout", "pass:v3-certs", "-descert",
"-out", $outfile2])),
"test_pkcs12_passcerts");
}
SKIP: {
skip "Skipping legacy PKCS#12 test because RC2 is disabled in this build", 1

View File

@ -5368,3 +5368,30 @@ EVP_SIGNATURE_name ? 3_0_0 EXIST::FUNCTION:
EVP_ASYM_CIPHER_name ? 3_0_0 EXIST::FUNCTION:
EVP_KEM_name ? 3_0_0 EXIST::FUNCTION:
EVP_KEYEXCH_name ? 3_0_0 EXIST::FUNCTION:
PKCS5_v2_PBE_keyivgen_ex ? 3_0_0 EXIST::FUNCTION:
EVP_PBE_scrypt_ex ? 3_0_0 EXIST::FUNCTION:SCRYPT
PKCS5_v2_scrypt_keyivgen_ex ? 3_0_0 EXIST::FUNCTION:SCRYPT
EVP_PBE_CipherInit_ex ? 3_0_0 EXIST::FUNCTION:
EVP_PBE_find_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_SAFEBAG_create_pkcs8_encrypt_ex ? 3_0_0 EXIST::FUNCTION:
PKCS8_decrypt_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_decrypt_skey_ex ? 3_0_0 EXIST::FUNCTION:
PKCS8_encrypt_ex ? 3_0_0 EXIST::FUNCTION:
PKCS8_set0_pbe_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_pack_p7encdata_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_pbe_crypt_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_item_decrypt_d2i_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_item_i2d_encrypt_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_init_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_key_gen_asc_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_key_gen_uni_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_key_gen_utf8_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_PBE_keyivgen_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_create_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_add_key_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_add_safe_ex ? 3_0_0 EXIST::FUNCTION:
PKCS12_add_safes_ex ? 3_0_0 EXIST::FUNCTION:
PKCS5_pbe_set0_algor_ex ? 3_0_0 EXIST::FUNCTION:
PKCS5_pbe_set_ex ? 3_0_0 EXIST::FUNCTION:
PKCS5_pbe2_set_iv_ex ? 3_0_0 EXIST::FUNCTION:
PKCS5_pbkdf2_set_ex ? 3_0_0 EXIST::FUNCTION:

View File

@ -650,13 +650,10 @@ EVP_CIPHER_set_asn1_iv(3)
EVP_KDF_ctrl(3)
EVP_MD_do_all(3)
EVP_MD_do_all_sorted(3)
EVP_PBE_CipherInit(3)
EVP_PBE_alg_add(3)
EVP_PBE_alg_add_type(3)
EVP_PBE_cleanup(3)
EVP_PBE_find(3)
EVP_PBE_get(3)
EVP_PBE_scrypt(3)
EVP_PKEY_CTX_get0_peerkey(3)
EVP_PKEY_CTX_get0_pkey(3)
EVP_PKEY_CTX_get_data(3)
@ -884,61 +881,22 @@ PKCS12_AUTHSAFES_it(3)
PKCS12_BAGS_it(3)
PKCS12_MAC_DATA_it(3)
PKCS12_PBE_add(3)
PKCS12_PBE_keyivgen(3)
PKCS12_SAFEBAGS_it(3)
PKCS12_SAFEBAG_create0_p8inf(3)
PKCS12_SAFEBAG_create0_pkcs8(3)
PKCS12_SAFEBAG_create_cert(3)
PKCS12_SAFEBAG_create_crl(3)
PKCS12_SAFEBAG_create_pkcs8_encrypt(3)
PKCS12_SAFEBAG_get0_attr(3)
PKCS12_SAFEBAG_get0_p8inf(3)
PKCS12_SAFEBAG_get0_pkcs8(3)
PKCS12_SAFEBAG_get0_safes(3)
PKCS12_SAFEBAG_get0_type(3)
PKCS12_SAFEBAG_get1_cert(3)
PKCS12_SAFEBAG_get1_crl(3)
PKCS12_SAFEBAG_get_bag_nid(3)
PKCS12_SAFEBAG_get_nid(3)
PKCS12_SAFEBAG_it(3)
PKCS12_add_cert(3)
PKCS12_add_key(3)
PKCS12_add_safe(3)
PKCS12_add_safes(3)
PKCS12_decrypt_skey(3)
PKCS12_gen_mac(3)
PKCS12_get0_mac(3)
PKCS12_get_attr(3)
PKCS12_init(3)
PKCS12_it(3)
PKCS12_item_decrypt_d2i(3)
PKCS12_item_i2d_encrypt(3)
PKCS12_item_pack_safebag(3)
PKCS12_key_gen_asc(3)
PKCS12_key_gen_uni(3)
PKCS12_key_gen_utf8(3)
PKCS12_mac_present(3)
PKCS12_pack_authsafes(3)
PKCS12_pack_p7data(3)
PKCS12_pack_p7encdata(3)
PKCS12_pbe_crypt(3)
PKCS12_set_mac(3)
PKCS12_setup_mac(3)
PKCS12_unpack_authsafes(3)
PKCS12_unpack_p7data(3)
PKCS12_unpack_p7encdata(3)
PKCS12_verify_mac(3)
PKCS1_MGF1(3)
PKCS5_PBE_add(3)
PKCS5_PBE_keyivgen(3)
PKCS5_pbe2_set(3)
PKCS5_pbe2_set_iv(3)
PKCS5_pbe2_set_scrypt(3)
PKCS5_pbe_set(3)
PKCS5_pbe_set0_algor(3)
PKCS5_pbkdf2_set(3)
PKCS5_v2_PBE_keyivgen(3)
PKCS5_v2_scrypt_keyivgen(3)
PKCS7_ATTR_SIGN_it(3)
PKCS7_ATTR_VERIFY_it(3)
PKCS7_DIGEST_it(3)
@ -995,12 +953,9 @@ PKCS7_stream(3)
PKCS7_to_TS_TST_INFO(3)
PKCS8_PRIV_KEY_INFO_it(3)
PKCS8_add_keyusage(3)
PKCS8_decrypt(3)
PKCS8_encrypt(3)
PKCS8_get_attr(3)
PKCS8_pkey_get0(3)
PKCS8_pkey_set0(3)
PKCS8_set0_pbe(3)
PKEY_USAGE_PERIOD_it(3)
POLICYINFO_it(3)
POLICYQUALINFO_it(3)