CMP: add support for central key generation
- add testcase for central keygen - add documentation Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/25132)
This commit is contained in:
parent
35b97122ea
commit
0048817523
37 changed files with 966 additions and 153 deletions
|
@ -85,6 +85,12 @@ OpenSSL 3.5
|
|||
|
||||
*David von Oheimb*
|
||||
|
||||
* Added support for central key generation in CMP.
|
||||
|
||||
This work was sponsored by Siemens AG.
|
||||
|
||||
*Rajeev Ranjan*
|
||||
|
||||
* Optionally allow the FIPS provider to use the `JITTER` entropy source.
|
||||
Note that using this option will require the resulting FIPS provider
|
||||
to undergo entropy source validation [ESV] by the [CMVP], without this
|
||||
|
|
116
apps/cmp.c
116
apps/cmp.c
|
@ -124,6 +124,8 @@ static char *opt_profile = NULL;
|
|||
/* certificate enrollment */
|
||||
static char *opt_newkey = NULL;
|
||||
static char *opt_newkeypass = NULL;
|
||||
static int opt_centralkeygen = 0;
|
||||
static char *opt_newkeyout = NULL;
|
||||
static char *opt_subject = NULL;
|
||||
static int opt_days = 0;
|
||||
static char *opt_reqexts = NULL;
|
||||
|
@ -199,6 +201,8 @@ static char *opt_srv_trusted = NULL;
|
|||
static char *opt_srv_untrusted = NULL;
|
||||
static char *opt_ref_cert = NULL;
|
||||
static char *opt_rsp_cert = NULL;
|
||||
static char *opt_rsp_key = NULL;
|
||||
static char *opt_rsp_keypass = NULL;
|
||||
static char *opt_rsp_crl = NULL;
|
||||
static char *opt_rsp_extracerts = NULL;
|
||||
static char *opt_rsp_capubs = NULL;
|
||||
|
@ -230,7 +234,8 @@ typedef enum OPTION_choice {
|
|||
OPT_CMD, OPT_INFOTYPE, OPT_PROFILE, OPT_GENINFO,
|
||||
OPT_TEMPLATE, OPT_KEYSPEC,
|
||||
|
||||
OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT,
|
||||
OPT_NEWKEY, OPT_NEWKEYPASS, OPT_CENTRALKEYGEN,
|
||||
OPT_NEWKEYOUT, OPT_SUBJECT,
|
||||
OPT_DAYS, OPT_REQEXTS,
|
||||
OPT_SANS, OPT_SAN_NODEFAULT,
|
||||
OPT_POLICIES, OPT_POLICY_OIDS, OPT_POLICY_OIDS_CRITICAL,
|
||||
|
@ -282,7 +287,8 @@ typedef enum OPTION_choice {
|
|||
OPT_SRV_REF, OPT_SRV_SECRET,
|
||||
OPT_SRV_CERT, OPT_SRV_KEY, OPT_SRV_KEYPASS,
|
||||
OPT_SRV_TRUSTED, OPT_SRV_UNTRUSTED,
|
||||
OPT_REF_CERT, OPT_RSP_CERT, OPT_RSP_CRL, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS,
|
||||
OPT_REF_CERT, OPT_RSP_CERT, OPT_RSP_KEY, OPT_RSP_KEYPASS,
|
||||
OPT_RSP_CRL, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS,
|
||||
OPT_RSP_NEWWITHNEW, OPT_RSP_NEWWITHOLD, OPT_RSP_OLDWITHNEW,
|
||||
OPT_POLL_COUNT, OPT_CHECK_AFTER,
|
||||
OPT_GRANT_IMPLICITCONF,
|
||||
|
@ -326,6 +332,10 @@ const OPTIONS cmp_options[] = {
|
|||
{"newkey", OPT_NEWKEY, 's',
|
||||
"Private or public key for the requested cert. Default: CSR key or client key"},
|
||||
{"newkeypass", OPT_NEWKEYPASS, 's', "New private key pass phrase source"},
|
||||
{"centralkeygen", OPT_CENTRALKEYGEN, '-',
|
||||
"Request central (server-side) key generation. Default is local generation"},
|
||||
{"newkeyout", OPT_NEWKEYOUT, 's',
|
||||
"File to save centrally generated key, in PEM format"},
|
||||
{"subject", OPT_SUBJECT, 's',
|
||||
"Distinguished Name (DN) of subject to use in the requested cert template"},
|
||||
{OPT_MORE_STR, 0, 0,
|
||||
|
@ -571,6 +581,12 @@ const OPTIONS cmp_options[] = {
|
|||
"Certificate to be expected for rr and any oldCertID in kur messages"},
|
||||
{"rsp_cert", OPT_RSP_CERT, 's',
|
||||
"Certificate to be returned as mock enrollment result"},
|
||||
{"rsp_key", OPT_RSP_KEY, 's',
|
||||
"Private key for the certificate to be returned as mock enrollment result"},
|
||||
{OPT_MORE_STR, 0, 0,
|
||||
"Key to be returned for central key pair generation"},
|
||||
{"rsp_keypass", OPT_RSP_KEYPASS, 's',
|
||||
"Response private key (and cert) pass phrase source"},
|
||||
{"rsp_crl", OPT_RSP_CRL, 's',
|
||||
"CRL to be returned in genp of type crls"},
|
||||
{"rsp_extracerts", OPT_RSP_EXTRACERTS, 's',
|
||||
|
@ -630,8 +646,8 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
|
|||
{&opt_cmd_s}, {&opt_infotype_s}, {&opt_profile}, {&opt_geninfo},
|
||||
{&opt_template}, {&opt_keyspec},
|
||||
|
||||
{&opt_newkey}, {&opt_newkeypass}, {&opt_subject},
|
||||
{(char **)&opt_days}, {&opt_reqexts},
|
||||
{&opt_newkey}, {&opt_newkeypass}, {(char **)&opt_centralkeygen},
|
||||
{&opt_newkeyout}, {&opt_subject}, {(char **)&opt_days}, {&opt_reqexts},
|
||||
{&opt_sans}, {(char **)&opt_san_nodefault},
|
||||
{&opt_policies}, {&opt_policy_oids}, {(char **)&opt_policy_oids_critical},
|
||||
{(char **)&opt_popo}, {&opt_csr},
|
||||
|
@ -683,8 +699,8 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
|
|||
{&opt_srv_ref}, {&opt_srv_secret},
|
||||
{&opt_srv_cert}, {&opt_srv_key}, {&opt_srv_keypass},
|
||||
{&opt_srv_trusted}, {&opt_srv_untrusted},
|
||||
{&opt_ref_cert}, {&opt_rsp_cert}, {&opt_rsp_crl},
|
||||
{&opt_rsp_extracerts}, {&opt_rsp_capubs},
|
||||
{&opt_ref_cert}, {&opt_rsp_cert}, {&opt_rsp_key}, {&opt_rsp_keypass},
|
||||
{&opt_rsp_crl}, {&opt_rsp_extracerts}, {&opt_rsp_capubs},
|
||||
{&opt_rsp_newwithnew}, {&opt_rsp_newwithold}, {&opt_rsp_oldwithnew},
|
||||
|
||||
{(char **)&opt_poll_count}, {(char **)&opt_check_after},
|
||||
|
@ -1197,11 +1213,25 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
|
|||
if (opt_rsp_cert == NULL) {
|
||||
CMP_warn("no -rsp_cert given for mock server");
|
||||
} else {
|
||||
if (!setup_cert(srv_ctx, opt_rsp_cert, opt_keypass,
|
||||
if (!setup_cert(srv_ctx, opt_rsp_cert, opt_rsp_keypass,
|
||||
"cert the mock server returns on certificate requests",
|
||||
(add_X509_fn_t)ossl_cmp_mock_srv_set1_certOut))
|
||||
goto err;
|
||||
}
|
||||
if (opt_rsp_key != NULL) {
|
||||
EVP_PKEY *pkey = load_key_pwd(opt_rsp_key, opt_keyform,
|
||||
opt_rsp_keypass, engine,
|
||||
"private key for enrollment cert");
|
||||
|
||||
if (pkey == NULL
|
||||
|| !ossl_cmp_mock_srv_set1_keyOut(srv_ctx, pkey)) {
|
||||
EVP_PKEY_free(pkey);
|
||||
goto err;
|
||||
}
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
cleanse(opt_rsp_keypass);
|
||||
|
||||
if (!setup_mock_crlout(srv_ctx, opt_rsp_crl,
|
||||
"CRL to be returned by the mock server"))
|
||||
goto err;
|
||||
|
@ -1672,11 +1702,27 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
|
|||
if (!set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer"))
|
||||
return 0;
|
||||
if (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR) {
|
||||
if (opt_reqin == NULL && opt_newkey == NULL
|
||||
if (opt_reqin == NULL && opt_newkey == NULL && !opt_centralkeygen
|
||||
&& opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) {
|
||||
CMP_err("missing -newkey (or -key) to be certified and no -csr, -oldcert, -cert, or -reqin option given, which could provide fallback public key");
|
||||
CMP_err("missing -newkey (or -key) to be certified and no -csr, -oldcert, -cert, or -reqin option given, which could provide fallback public key."
|
||||
" Neither central key generation is requested.");
|
||||
return 0;
|
||||
}
|
||||
if (opt_popo == OSSL_CRMF_POPO_NONE && !opt_centralkeygen) {
|
||||
CMP_info("POPO is disabled, which implies -centralkeygen");
|
||||
opt_centralkeygen = 1;
|
||||
}
|
||||
if (opt_centralkeygen) {
|
||||
if (opt_popo > OSSL_CRMF_POPO_NONE) {
|
||||
CMP_err1("-popo value %d is inconsistent with -centralkeygen", opt_popo);
|
||||
return 0;
|
||||
}
|
||||
if (opt_newkeyout == NULL) {
|
||||
CMP_err("-newkeyout not given, nowhere to save centrally generated key");
|
||||
return 0;
|
||||
}
|
||||
opt_popo = OSSL_CRMF_POPO_NONE;
|
||||
}
|
||||
if (opt_newkey == NULL
|
||||
&& opt_popo != OSSL_CRMF_POPO_NONE
|
||||
&& opt_popo != OSSL_CRMF_POPO_RAVERIFIED) {
|
||||
|
@ -1724,6 +1770,12 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
|
|||
CMP_warn1("-policies %s", msg);
|
||||
if (opt_policy_oids != NULL)
|
||||
CMP_warn1("-policy_oids %s", msg);
|
||||
if (opt_popo != OSSL_CRMF_POPO_NONE - 1)
|
||||
CMP_warn1("-popo %s", msg);
|
||||
if (opt_centralkeygen)
|
||||
CMP_warn1("-popo -1 or -centralkeygen %s", msg);
|
||||
if (opt_newkeyout != NULL)
|
||||
CMP_warn1("-newkeyout %s", msg);
|
||||
if (opt_cmd != CMP_P10CR) {
|
||||
if (opt_implicit_confirm)
|
||||
CMP_warn1("-implicit_confirm %s, and 'p10cr'", msg);
|
||||
|
@ -1828,13 +1880,14 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
|
|||
pkey = load_pubkey(file, format, 0, pass, engine, desc);
|
||||
priv = 0;
|
||||
}
|
||||
cleanse(opt_newkeypass);
|
||||
|
||||
if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, priv, pkey)) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
}
|
||||
} else if (opt_reqin != NULL
|
||||
&& opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) {
|
||||
&& opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL
|
||||
&& !opt_centralkeygen) {
|
||||
if (!set_fallback_pubkey(ctx))
|
||||
return 0;
|
||||
}
|
||||
|
@ -2922,13 +2975,18 @@ static int get_opts(int argc, char **argv)
|
|||
case OPT_KEYSPEC:
|
||||
opt_keyspec = opt_str();
|
||||
break;
|
||||
|
||||
case OPT_NEWKEY:
|
||||
opt_newkey = opt_str();
|
||||
break;
|
||||
case OPT_NEWKEYPASS:
|
||||
opt_newkeypass = opt_str();
|
||||
break;
|
||||
case OPT_CENTRALKEYGEN:
|
||||
opt_centralkeygen = 1;
|
||||
break;
|
||||
case OPT_NEWKEYOUT:
|
||||
opt_newkeyout = opt_str();
|
||||
break;
|
||||
case OPT_SUBJECT:
|
||||
opt_subject = opt_str();
|
||||
break;
|
||||
|
@ -3086,6 +3144,12 @@ static int get_opts(int argc, char **argv)
|
|||
case OPT_RSP_CERT:
|
||||
opt_rsp_cert = opt_str();
|
||||
break;
|
||||
case OPT_RSP_KEY:
|
||||
opt_rsp_key = opt_str();
|
||||
break;
|
||||
case OPT_RSP_KEYPASS:
|
||||
opt_rsp_keypass = opt_str();
|
||||
break;
|
||||
case OPT_RSP_CRL:
|
||||
opt_rsp_crl = opt_str();
|
||||
break;
|
||||
|
@ -3793,6 +3857,34 @@ int cmp_main(int argc, char **argv)
|
|||
if (save_free_certs(OSSL_CMP_CTX_get1_caPubs(cmp_ctx),
|
||||
opt_cacertsout, "CA") < 0)
|
||||
goto err;
|
||||
if (opt_centralkeygen) {
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
char *pass_string = NULL;
|
||||
BIO *out;
|
||||
int result = 1;
|
||||
EVP_PKEY *new_key = OSSL_CMP_CTX_get0_newPkey(cmp_ctx, 1 /* priv */);
|
||||
|
||||
if (new_key == NULL)
|
||||
goto err;
|
||||
if ((out = bio_open_owner(opt_newkeyout, FORMAT_PEM, 1)) == NULL)
|
||||
goto err;
|
||||
if (opt_newkeypass != NULL) {
|
||||
pass_string = get_passwd(opt_newkeypass,
|
||||
"Centrally generated private key password");
|
||||
cipher = EVP_CIPHER_fetch(app_get0_libctx(), SN_aes_256_cbc, app_get0_propq());
|
||||
}
|
||||
|
||||
CMP_info1("saving centrally generated key to file '%s'", opt_newkeyout);
|
||||
if (PEM_write_bio_PrivateKey(out, new_key, cipher, NULL, 0, NULL,
|
||||
(void *)pass_string) <= 0)
|
||||
result = 0;
|
||||
|
||||
BIO_free(out);
|
||||
clear_free(pass_string);
|
||||
EVP_CIPHER_free(cipher);
|
||||
if (!result)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!OSSL_CMP_CTX_reinit(cmp_ctx))
|
||||
goto err;
|
||||
|
|
|
@ -22,6 +22,7 @@ void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
|
|||
|
||||
int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
|
||||
int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
|
||||
int ossl_cmp_mock_srv_set1_keyOut(OSSL_CMP_SRV_CTX *srv_ctx, EVP_PKEY *pkey);
|
||||
int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx, X509_CRL *crl);
|
||||
int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
STACK_OF(X509) *chain);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
typedef struct {
|
||||
X509 *refCert; /* cert to expect for oldCertID in kur/rr msg */
|
||||
X509 *certOut; /* certificate to be returned in cp/ip/kup msg */
|
||||
EVP_PKEY *keyOut; /* Private key to be returned for central keygen */
|
||||
X509_CRL *crlOut; /* CRL to be returned in genp for crls */
|
||||
STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */
|
||||
STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */
|
||||
|
@ -87,6 +88,21 @@ static mock_srv_ctx *mock_srv_ctx_new(void)
|
|||
DEFINE_OSSL_SET1_CERT(refCert)
|
||||
DEFINE_OSSL_SET1_CERT(certOut)
|
||||
|
||||
int ossl_cmp_mock_srv_set1_keyOut(OSSL_CMP_SRV_CTX *srv_ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (pkey != NULL && !EVP_PKEY_up_ref(pkey))
|
||||
return 0;
|
||||
EVP_PKEY_free(ctx->keyOut);
|
||||
ctx->keyOut = pkey;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
X509_CRL *crl)
|
||||
{
|
||||
|
@ -273,8 +289,9 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
STACK_OF(X509) **caPubs)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
int bodytype;
|
||||
int bodytype, central_keygen;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
EVP_PKEY *keyOut = NULL;
|
||||
|
||||
if (ctx == NULL || cert_req == NULL
|
||||
|| certOut == NULL || chainOut == NULL || caPubs == NULL) {
|
||||
|
@ -358,6 +375,23 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
&& (*certOut = X509_dup(ctx->certOut)) == NULL)
|
||||
/* Should return a cert produced from request template, see FR #16054 */
|
||||
goto err;
|
||||
|
||||
central_keygen = OSSL_CRMF_MSG_centralkeygen_requested(crm, p10cr);
|
||||
if (central_keygen < 0)
|
||||
goto err;
|
||||
if (central_keygen == 1
|
||||
&& (ctx->keyOut == NULL
|
||||
|| (keyOut = EVP_PKEY_dup(ctx->keyOut)) == NULL
|
||||
|| !OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx),
|
||||
1 /* priv */, keyOut))) {
|
||||
EVP_PKEY_free(keyOut);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Note that this uses newPkey to return the private key
|
||||
* and does not check whether the 'popo' field is absent.
|
||||
*/
|
||||
|
||||
if (ctx->chainOut != NULL
|
||||
&& (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
|
||||
goto err;
|
||||
|
|
|
@ -891,7 +891,7 @@ ASN1_CHOICE(OSSL_CMP_CERTORENCCERT) = {
|
|||
/* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */
|
||||
ASN1_EXP(OSSL_CMP_CERTORENCCERT, value.certificate, X509, 0),
|
||||
ASN1_EXP(OSSL_CMP_CERTORENCCERT, value.encryptedCert,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE, 1),
|
||||
OSSL_CRMF_ENCRYPTEDKEY, 1),
|
||||
} ASN1_CHOICE_END(OSSL_CMP_CERTORENCCERT)
|
||||
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT)
|
||||
|
||||
|
@ -899,7 +899,7 @@ ASN1_SEQUENCE(OSSL_CMP_CERTIFIEDKEYPAIR) = {
|
|||
ASN1_SIMPLE(OSSL_CMP_CERTIFIEDKEYPAIR, certOrEncCert,
|
||||
OSSL_CMP_CERTORENCCERT),
|
||||
ASN1_EXP_OPT(OSSL_CMP_CERTIFIEDKEYPAIR, privateKey,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE, 0),
|
||||
OSSL_CRMF_ENCRYPTEDKEY, 0),
|
||||
ASN1_EXP_OPT(OSSL_CMP_CERTIFIEDKEYPAIR, publicationInfo,
|
||||
OSSL_CRMF_PKIPUBLICATIONINFO, 1)
|
||||
} ASN1_SEQUENCE_END(OSSL_CMP_CERTIFIEDKEYPAIR)
|
||||
|
|
|
@ -656,7 +656,7 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
|
|||
ossl_unused int req_type,
|
||||
ossl_unused int expected_type)
|
||||
{
|
||||
EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
|
||||
EVP_PKEY *rkey = NULL;
|
||||
int fail_info = 0; /* no failure */
|
||||
const char *txt = NULL;
|
||||
OSSL_CMP_CERTREPMESSAGE *crepmsg = NULL;
|
||||
|
@ -748,6 +748,7 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
|
|||
return 0;
|
||||
|
||||
subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
||||
rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
|
||||
if (rkey != NULL
|
||||
/* X509_check_private_key() also works if rkey is just public key */
|
||||
&& !(X509_check_private_key(ctx->newCert, rkey))) {
|
||||
|
|
|
@ -79,6 +79,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
|||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_EXPECTED_POLLREQ), "expected pollreq"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN),
|
||||
"failed building own chain"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY),
|
||||
"failed extracting central gen key"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
|
||||
"failed extracting pubkey"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM),
|
||||
|
@ -97,6 +99,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
|||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE),
|
||||
"invalid rootcakeyupdate"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CENTRAL_GEN_KEY),
|
||||
"missing central gen key"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CERTID), "missing certid"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION),
|
||||
"missing key input for creating protection"},
|
||||
|
@ -151,6 +155,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
|||
"transactionid unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CENTRAL_GEN_KEY),
|
||||
"unexpected central gen key"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE),
|
||||
"unexpected certprofile"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CRLSTATUSLIST),
|
||||
|
|
|
@ -311,7 +311,7 @@ typedef struct ossl_cmp_certorenccert_st {
|
|||
int type;
|
||||
union {
|
||||
X509 *certificate;
|
||||
OSSL_CRMF_ENCRYPTEDVALUE *encryptedCert;
|
||||
OSSL_CRMF_ENCRYPTEDKEY *encryptedCert;
|
||||
} value;
|
||||
} OSSL_CMP_CERTORENCCERT;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT)
|
||||
|
@ -326,7 +326,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT)
|
|||
*/
|
||||
typedef struct ossl_cmp_certifiedkeypair_st {
|
||||
OSSL_CMP_CERTORENCCERT *certOrEncCert;
|
||||
OSSL_CRMF_ENCRYPTEDVALUE *privateKey;
|
||||
OSSL_CRMF_ENCRYPTEDKEY *privateKey;
|
||||
OSSL_CRMF_PKIPUBLICATIONINFO *publicationInfo;
|
||||
} OSSL_CMP_CERTIFIEDKEYPAIR;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTIFIEDKEYPAIR)
|
||||
|
@ -952,7 +952,8 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int bodytype,
|
|||
const OSSL_CRMF_MSG *crm);
|
||||
OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
int certReqId, const OSSL_CMP_PKISI *si,
|
||||
X509 *cert, const X509 *encryption_recip,
|
||||
X509 *cert, const EVP_PKEY *pkey,
|
||||
const X509 *encryption_recip,
|
||||
STACK_OF(X509) *chain, STACK_OF(X509) *caPubs,
|
||||
int unprotectedErrors);
|
||||
OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
|
||||
|
@ -994,6 +995,7 @@ OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
|
|||
int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG *msg);
|
||||
|
||||
/* from cmp_protect.c */
|
||||
void ossl_cmp_set_own_chain(OSSL_CMP_CTX *ctx);
|
||||
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *msg);
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include <openssl/crmf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <internal/cms.h>
|
||||
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_new(OSSL_LIB_CTX *libctx, const char *propq)
|
||||
{
|
||||
|
@ -271,6 +274,8 @@ static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, int for_KUR,
|
|||
OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
|
||||
{
|
||||
OSSL_CRMF_MSG *crm = NULL;
|
||||
int central_keygen = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_POPO_METHOD)
|
||||
== OSSL_CRMF_POPO_NONE;
|
||||
X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->cert;
|
||||
/* refcert defaults to current client cert */
|
||||
EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
|
||||
|
@ -283,9 +288,10 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
|
|||
: X509_get_issuer_name(refcert);
|
||||
int crit = ctx->setSubjectAltNameCritical || subject == NULL;
|
||||
/* RFC5280: subjectAltName MUST be critical if subject is null */
|
||||
OSSL_CRMF_CERTTEMPLATE *tmpl;
|
||||
X509_EXTENSIONS *exts = NULL;
|
||||
|
||||
if (rkey == NULL) {
|
||||
if (rkey == NULL && !central_keygen) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY);
|
||||
return NULL;
|
||||
|
@ -297,6 +303,7 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
|
|||
}
|
||||
if ((crm = OSSL_CRMF_MSG_new()) == NULL)
|
||||
return NULL;
|
||||
tmpl = OSSL_CRMF_MSG_get0_tmpl(crm);
|
||||
if (!OSSL_CRMF_MSG_set_certReqId(crm, rid)
|
||||
/*
|
||||
* fill certTemplate, corresponding to CertificationRequestInfo
|
||||
|
@ -306,6 +313,10 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
|
|||
|| !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey,
|
||||
subject, issuer, NULL /* serial */))
|
||||
goto err;
|
||||
if (rkey != NULL && central_keygen)
|
||||
X509_PUBKEY_set0_public_key(OSSL_CRMF_CERTTEMPLATE_get0_publicKey(tmpl),
|
||||
NULL, 0);
|
||||
|
||||
if (ctx->days != 0) {
|
||||
time_t now = time(NULL);
|
||||
ASN1_TIME *notBefore = ASN1_TIME_adj(NULL, now, 0, 0);
|
||||
|
@ -441,9 +452,47 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
static OSSL_CRMF_ENCRYPTEDKEY *enc_privkey(OSSL_CMP_CTX *ctx, const EVP_PKEY *pkey)
|
||||
{
|
||||
OSSL_CRMF_ENCRYPTEDKEY *ek = NULL;
|
||||
CMS_EnvelopedData *envData = NULL;
|
||||
BIO *privbio = NULL;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
X509 *recip = ctx->validatedSrvCert; /* this is the client cert */
|
||||
STACK_OF(X509) *encryption_recips = sk_X509_new_reserve(NULL, 1);
|
||||
|
||||
if (encryption_recips == NULL
|
||||
|| !X509_add_cert(encryption_recips, recip, X509_ADD_FLAG_UP_REF))
|
||||
goto err;
|
||||
|
||||
privbio = BIO_new(BIO_s_mem());
|
||||
if (privbio == NULL || i2d_PrivateKey_bio(privbio, pkey) <= 0)
|
||||
goto err;
|
||||
ossl_cmp_set_own_chain(ctx);
|
||||
cipher = EVP_CIPHER_fetch(ctx->libctx, SN_aes_256_cbc, ctx->propq);
|
||||
envData = ossl_cms_sign_encrypt(privbio, ctx->cert, ctx->chain, ctx->pkey, CMS_BINARY,
|
||||
encryption_recips, cipher, CMS_BINARY,
|
||||
ctx->libctx, ctx->propq);
|
||||
EVP_CIPHER_free(cipher);
|
||||
if (envData == NULL)
|
||||
goto err;
|
||||
ek = OSSL_CRMF_ENCRYPTEDKEY_init_envdata(envData);
|
||||
|
||||
err:
|
||||
sk_X509_pop_free(encryption_recips, X509_free);
|
||||
BIO_free(privbio);
|
||||
if (ek == NULL)
|
||||
M_ASN1_free_of(envData, CMS_EnvelopedData);
|
||||
|
||||
return ek;
|
||||
}
|
||||
#endif
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
int certReqId, const OSSL_CMP_PKISI *si,
|
||||
X509 *cert, const X509 *encryption_recip,
|
||||
X509 *cert, const EVP_PKEY *pkey,
|
||||
const X509 *encryption_recip,
|
||||
STACK_OF(X509) *chain, STACK_OF(X509) *caPubs,
|
||||
int unprotectedErrors)
|
||||
{
|
||||
|
@ -487,6 +536,16 @@ OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
|||
if (!X509_up_ref(cert))
|
||||
goto err;
|
||||
resp->certifiedKeyPair->certOrEncCert->value.certificate = cert;
|
||||
|
||||
if (pkey != NULL) {
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
if ((resp->certifiedKeyPair->privateKey = enc_privkey(ctx, pkey)) == NULL)
|
||||
goto err;
|
||||
#else
|
||||
ERR_raise(ERR_LIB_CMP, ERR_R_UNSUPPORTED);
|
||||
goto err;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg->response, resp))
|
||||
|
@ -1042,22 +1101,51 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
|
|||
}
|
||||
|
||||
/*-
|
||||
* Retrieve the newly enrolled certificate from the given certResponse crep.
|
||||
* Uses libctx and propq from ctx, in case of indirect POPO also private key.
|
||||
* Retrieve newly enrolled certificate and key from the given certResponse crep.
|
||||
* Stores any centrally generated key in ctx->newPkey.
|
||||
* In case of indirect POPO uses ctx->newPkey to decrypt the new certificate.
|
||||
* Returns a pointer to a copy of the found certificate, or NULL if not found.
|
||||
*/
|
||||
X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_CERTRESPONSE *crep)
|
||||
X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx, const OSSL_CMP_CERTRESPONSE *crep)
|
||||
{
|
||||
OSSL_CMP_CERTORENCCERT *coec;
|
||||
X509 *crt = NULL;
|
||||
EVP_PKEY *pkey;
|
||||
OSSL_CRMF_ENCRYPTEDKEY *encr_key;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int central_keygen = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_POPO_METHOD)
|
||||
== OSSL_CRMF_POPO_NONE;
|
||||
|
||||
if (crep->certifiedKeyPair == NULL) {
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
encr_key = crep->certifiedKeyPair->privateKey;
|
||||
if (encr_key == NULL && central_keygen) {
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CENTRAL_GEN_KEY);
|
||||
return NULL;
|
||||
}
|
||||
if (encr_key != NULL) {
|
||||
if (!central_keygen) {
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CENTRAL_GEN_KEY);
|
||||
return NULL;
|
||||
}
|
||||
/* found encrypted private key, try to extract */
|
||||
pkey = OSSL_CRMF_ENCRYPTEDKEY_get1_pkey(encr_key, ctx->trusted,
|
||||
ctx->untrusted,
|
||||
ctx->pkey, ctx->cert,
|
||||
ctx->secretValue,
|
||||
ctx->libctx, ctx->propq);
|
||||
if (pkey == NULL) {
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY);
|
||||
return NULL;
|
||||
}
|
||||
OSSL_CMP_CTX_set0_newPkey((OSSL_CMP_CTX *)ctx, 1, pkey);
|
||||
}
|
||||
|
||||
if (!ossl_assert(crep != NULL && ctx != NULL))
|
||||
return NULL;
|
||||
|
||||
if (crep->certifiedKeyPair
|
||||
&& (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) {
|
||||
if ((coec = crep->certifiedKeyPair->certOrEncCert) != NULL) {
|
||||
switch (coec->type) {
|
||||
case OSSL_CMP_CERTORENCCERT_CERTIFICATE:
|
||||
crt = X509_dup(coec->value.certificate);
|
||||
|
@ -1070,10 +1158,8 @@ X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
|
|||
ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY);
|
||||
return NULL;
|
||||
}
|
||||
crt =
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert,
|
||||
ctx->libctx, ctx->propq,
|
||||
pkey);
|
||||
crt = OSSL_CRMF_ENCRYPTEDKEY_get1_encCert(coec->value.encryptedCert,
|
||||
ctx->libctx, ctx->propq, pkey, 0);
|
||||
break;
|
||||
default:
|
||||
ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE);
|
||||
|
|
|
@ -130,6 +130,25 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
void ossl_cmp_set_own_chain(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
return;
|
||||
/* if not yet done try to build chain using available untrusted certs */
|
||||
if (ctx->chain == NULL) {
|
||||
ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert");
|
||||
ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0,
|
||||
ctx->libctx, ctx->propq);
|
||||
if (ctx->chain != NULL) {
|
||||
ossl_cmp_debug(ctx, "success building chain for own CMP signer cert");
|
||||
} else {
|
||||
/* dump errors to avoid confusion when printing further ones */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
ossl_cmp_warn(ctx, "could not build chain for own CMP signer cert");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ctx is not const just because ctx->chain may get adapted */
|
||||
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
{
|
||||
|
@ -142,22 +161,7 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
|||
int prepend = X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
|
||||
| X509_ADD_FLAG_PREPEND | X509_ADD_FLAG_NO_SS;
|
||||
|
||||
/* if not yet done try to build chain using available untrusted certs */
|
||||
if (ctx->chain == NULL) {
|
||||
ossl_cmp_debug(ctx,
|
||||
"trying to build chain for own CMP signer cert");
|
||||
ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0,
|
||||
ctx->libctx, ctx->propq);
|
||||
if (ctx->chain != NULL) {
|
||||
ossl_cmp_debug(ctx,
|
||||
"success building chain for own CMP signer cert");
|
||||
} else {
|
||||
/* dump errors to avoid confusion when printing further ones */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
ossl_cmp_warn(ctx,
|
||||
"could not build chain for own CMP signer cert");
|
||||
}
|
||||
}
|
||||
ossl_cmp_set_own_chain(ctx);
|
||||
if (ctx->chain != NULL) {
|
||||
if (!ossl_x509_add_certs_new(&msg->extraCerts, ctx->chain, prepend))
|
||||
return 0;
|
||||
|
|
|
@ -216,11 +216,12 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
X509 *certOut = NULL;
|
||||
EVP_PKEY *keyOut = NULL;
|
||||
STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
|
||||
const OSSL_CRMF_MSG *crm = NULL;
|
||||
const X509_REQ *p10cr = NULL;
|
||||
int bodytype;
|
||||
int certReqId;
|
||||
int certReqId, central_keygen;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
@ -263,7 +264,11 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
}
|
||||
srv_ctx->certReqId = certReqId;
|
||||
|
||||
if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) {
|
||||
central_keygen = OSSL_CRMF_MSG_centralkeygen_requested(crm, p10cr);
|
||||
if (central_keygen < 0)
|
||||
return NULL;
|
||||
if (central_keygen == 0
|
||||
&& !ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) {
|
||||
/* Proof of possession could not be verified */
|
||||
si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
|
||||
|
@ -287,10 +292,13 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
/* do not set if polling starts: */
|
||||
&& certOut != NULL))
|
||||
goto err;
|
||||
if (central_keygen == 1
|
||||
&& srv_ctx->ctx->newPkey_priv && srv_ctx->ctx->newPkey != NULL)
|
||||
keyOut = srv_ctx->ctx->newPkey;
|
||||
}
|
||||
|
||||
msg = ossl_cmp_certrep_new(srv_ctx->ctx, bodytype, certReqId, si,
|
||||
certOut, NULL /* enc */, chainOut, caPubs,
|
||||
certOut, keyOut, NULL /* enc */, chainOut, caPubs,
|
||||
srv_ctx->sendUnprotectedErrors);
|
||||
/* When supporting OSSL_CRMF_POPO_KEYENC, "enc" will need to be set */
|
||||
if (msg == NULL)
|
||||
|
@ -299,6 +307,7 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
err:
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
X509_free(certOut);
|
||||
OSSL_CMP_CTX_set0_newPkey(srv_ctx->ctx, 0, NULL);
|
||||
OSSL_STACK_OF_X509_free(chainOut);
|
||||
OSSL_STACK_OF_X509_free(caPubs);
|
||||
return msg;
|
||||
|
|
|
@ -243,6 +243,7 @@ ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
|
|||
ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
|
||||
ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
|
||||
} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(CMS_EnvelopedData)
|
||||
|
||||
ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
|
||||
ASN1_EMBED(CMS_DigestedData, version, INT32),
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "internal/cryptlib.h"
|
||||
#include "crypto/x509.h"
|
||||
#include "cms_local.h"
|
||||
#include "internal/cms.h"
|
||||
|
||||
static STACK_OF(CMS_CertificateChoices)
|
||||
**cms_get0_certificate_choices(CMS_ContentInfo *cms);
|
||||
|
@ -769,3 +770,40 @@ int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
|
|||
*pkeyid = keyid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
CMS_EnvelopedData *ossl_cms_sign_encrypt(BIO *data, X509 *sign_cert, STACK_OF(X509) *certs,
|
||||
EVP_PKEY *sign_key, unsigned int sign_flags,
|
||||
STACK_OF(X509) *enc_recip, const EVP_CIPHER *cipher,
|
||||
unsigned int enc_flags, OSSL_LIB_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_EnvelopedData *evd = NULL;
|
||||
BIO *privbio = NULL, *signbio = NULL;
|
||||
CMS_ContentInfo *signcms = NULL, *evpcms = NULL;
|
||||
|
||||
if (data == NULL || sign_key == NULL || sign_cert == NULL || enc_recip == NULL) {
|
||||
ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
signcms = CMS_sign_ex(sign_cert, sign_key, certs, data, sign_flags, libctx, propq);
|
||||
if (signcms == NULL)
|
||||
goto err;
|
||||
|
||||
signbio = BIO_new(BIO_s_mem());
|
||||
if (signbio == NULL
|
||||
|| ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_SignedData), signbio, signcms->d.signedData) <= 0)
|
||||
goto err;
|
||||
|
||||
evpcms = CMS_encrypt_ex(enc_recip, signbio, cipher, enc_flags, libctx, propq);
|
||||
if (evpcms == NULL)
|
||||
goto err;
|
||||
evd = CMS_EnvelopedData_dup(evpcms->d.envelopedData);
|
||||
|
||||
err:
|
||||
BIO_free(privbio);
|
||||
BIO_free(signbio);
|
||||
CMS_ContentInfo_free(signcms);
|
||||
CMS_ContentInfo_free(evpcms);
|
||||
|
||||
return evd;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,21 @@ ASN1_SEQUENCE(OSSL_CRMF_ENCRYPTEDVALUE) = {
|
|||
} ASN1_SEQUENCE_END(OSSL_CRMF_ENCRYPTEDVALUE)
|
||||
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE)
|
||||
|
||||
/*
|
||||
* Note from CMP Updates defining CMPv3:
|
||||
* The EncryptedKey structure defined in CRMF [RFC4211] is reused
|
||||
* here, which makes the update backward compatible. Using the new
|
||||
* syntax with the untagged default choice EncryptedValue is bits-on-
|
||||
* the-wire compatible with the old syntax.
|
||||
*/
|
||||
ASN1_CHOICE(OSSL_CRMF_ENCRYPTEDKEY) = {
|
||||
ASN1_SIMPLE(OSSL_CRMF_ENCRYPTEDKEY, value.encryptedValue, OSSL_CRMF_ENCRYPTEDVALUE),
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
ASN1_IMP(OSSL_CRMF_ENCRYPTEDKEY, value.envelopedData, CMS_EnvelopedData, 0),
|
||||
#endif
|
||||
} ASN1_CHOICE_END(OSSL_CRMF_ENCRYPTEDKEY)
|
||||
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDKEY)
|
||||
|
||||
ASN1_SEQUENCE(OSSL_CRMF_SINGLEPUBINFO) = {
|
||||
ASN1_SIMPLE(OSSL_CRMF_SINGLEPUBINFO, pubMethod, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(OSSL_CRMF_SINGLEPUBINFO, pubLocation, GENERAL_NAME)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2024 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
|
||||
|
@ -18,44 +18,57 @@
|
|||
|
||||
static const ERR_STRING_DATA CRMF_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_BAD_PBM_ITERATIONCOUNT),
|
||||
"bad pbm iterationcount"},
|
||||
"bad pbm iterationcount"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CMS_NOT_SUPPORTED), "cms not supported"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CRMFERROR), "crmferror"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR), "error"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_CERTIFICATE),
|
||||
"error decoding certificate"},
|
||||
"error decoding certificate"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_ENCRYPTEDKEY),
|
||||
"error decoding encryptedkey"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_CERTIFICATE),
|
||||
"error decrypting certificate"},
|
||||
"error decrypting certificate"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY),
|
||||
"error decrypting encryptedkey"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE),
|
||||
"error decrypting encryptedvalue"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY),
|
||||
"error decrypting symmetric key"},
|
||||
"error decrypting symmetric key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_SETTING_PURPOSE),
|
||||
"error setting purpose"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY),
|
||||
"error verifying encryptedkey"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_FAILURE_OBTAINING_RANDOM),
|
||||
"failure obtaining random"},
|
||||
"failure obtaining random"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ITERATIONCOUNT_BELOW_100),
|
||||
"iterationcount below 100"},
|
||||
"iterationcount below 100"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED),
|
||||
"poposkinput not supported"},
|
||||
"poposkinput not supported"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN),
|
||||
"popo inconsistent central keygen"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
|
||||
"popo inconsistent public key"},
|
||||
"popo inconsistent public key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY),
|
||||
"popo missing public key"},
|
||||
"popo missing public key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT),
|
||||
"popo missing subject"},
|
||||
"popo missing subject"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED),
|
||||
"popo raverified not accepted"},
|
||||
"popo raverified not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE),
|
||||
"setting mac algor failure"},
|
||||
"setting mac algor failure"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE),
|
||||
"setting owf algor failure"},
|
||||
"setting owf algor failure"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM),
|
||||
"unsupported algorithm"},
|
||||
"unsupported algorithm"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER),
|
||||
"unsupported cipher"},
|
||||
"unsupported cipher"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO),
|
||||
"unsupported method for creating popo"},
|
||||
"unsupported method for creating popo"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD),
|
||||
"unsupported popo method"},
|
||||
"unsupported popo method"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <openssl/asn1t.h>
|
||||
|
||||
#include "crmf_local.h"
|
||||
#include "internal/constant_time.h"
|
||||
#include "internal/sizes.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/x509.h"
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include <openssl/crmf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/cms.h>
|
||||
|
||||
/*-
|
||||
* atyp = Attribute Type
|
||||
|
@ -542,6 +544,38 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CRMF_MSG_centralkeygen_requested(const OSSL_CRMF_MSG *crm, const X509_REQ *p10cr)
|
||||
{
|
||||
X509_PUBKEY *pubkey = NULL;
|
||||
const unsigned char *pk = NULL;
|
||||
int pklen, ret = 0;
|
||||
|
||||
if (crm == NULL && p10cr == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (crm != NULL)
|
||||
pubkey = OSSL_CRMF_CERTTEMPLATE_get0_publicKey(OSSL_CRMF_MSG_get0_tmpl(crm));
|
||||
else
|
||||
pubkey = p10cr->req_info.pubkey;
|
||||
|
||||
if (pubkey == NULL
|
||||
|| (X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey)
|
||||
&& pklen == 0))
|
||||
ret = 1;
|
||||
|
||||
/*
|
||||
* In case of CRMF, POPO MUST be absent if central key generation
|
||||
* is requested, otherwise MUST be present
|
||||
*/
|
||||
if (crm != NULL && ret != (crm->popo == NULL)) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN);
|
||||
return -2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
X509_PUBKEY
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_publicKey(const OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
{
|
||||
|
@ -612,46 +646,155 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Decrypts the certificate in the given encryptedValue using private key pkey.
|
||||
* This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
|
||||
*
|
||||
* returns a pointer to the decrypted certificate
|
||||
* returns NULL on error or if no certificate available
|
||||
*/
|
||||
X509
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey)
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
DECLARE_ASN1_ITEM(CMS_SignedData) /* copied from cms_local.h */
|
||||
|
||||
/* check for KGA authorization implied by CA flag or by explicit EKU cmKGA */
|
||||
static int check_cmKGA(ossl_unused const X509_PURPOSE *purpose, const X509 *x, int ca)
|
||||
{
|
||||
STACK_OF(ASN1_OBJECT) *ekus;
|
||||
int i, ret = 1;
|
||||
|
||||
if (ca)
|
||||
return ret;
|
||||
ekus = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL);
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(ekus); i++) {
|
||||
if (OBJ_obj2nid(sk_ASN1_OBJECT_value(ekus, i)) == NID_cmKGA)
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
sk_ASN1_OBJECT_pop_free(ekus, ASN1_OBJECT_free);
|
||||
return ret;
|
||||
}
|
||||
#endif /* OPENSSL_NO_CMS */
|
||||
|
||||
EVP_PKEY *OSSL_CRMF_ENCRYPTEDKEY_get1_pkey(const OSSL_CRMF_ENCRYPTEDKEY *encryptedKey,
|
||||
X509_STORE *ts, STACK_OF(X509) *extra, EVP_PKEY *pkey,
|
||||
X509 *cert, ASN1_OCTET_STRING *secret,
|
||||
OSSL_LIB_CTX *libctx, const char *propq)
|
||||
{
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
BIO *bio = NULL;
|
||||
CMS_SignedData *sd = NULL;
|
||||
BIO *pkey_bio = NULL;
|
||||
int purpose_id, bak_purpose_id;
|
||||
X509_VERIFY_PARAM *vpm;
|
||||
#endif
|
||||
EVP_PKEY *ret = NULL;
|
||||
|
||||
if (encryptedKey == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if (encryptedKey->type != OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA) {
|
||||
unsigned char *p;
|
||||
const unsigned char *p_copy;
|
||||
int len;
|
||||
|
||||
p = OSSL_CRMF_ENCRYPTEDVALUE_decrypt(encryptedKey->value.encryptedValue,
|
||||
libctx, propq, pkey, &len);
|
||||
if ((p_copy = p) != NULL)
|
||||
ret = d2i_AutoPrivateKey_ex(NULL, &p_copy, len, libctx, propq);
|
||||
OPENSSL_free(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
if (ts == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if ((bio = CMS_EnvelopedData_decrypt(encryptedKey->value.envelopedData,
|
||||
NULL, pkey, cert, secret, 0,
|
||||
libctx, propq)) == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY);
|
||||
goto end;
|
||||
}
|
||||
sd = ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_SignedData), bio, NULL);
|
||||
if (sd == NULL)
|
||||
goto end;
|
||||
|
||||
if ((purpose_id = X509_PURPOSE_get_by_sname(SN_cmKGA)) < 0) {
|
||||
purpose_id = X509_PURPOSE_get_unused_id(libctx);
|
||||
if (!X509_PURPOSE_add(purpose_id, X509_TRUST_COMPAT, 0, check_cmKGA,
|
||||
LN_cmKGA, SN_cmKGA, NULL))
|
||||
goto end;
|
||||
}
|
||||
if ((vpm = X509_STORE_get0_param(ts)) == NULL)
|
||||
goto end;
|
||||
|
||||
/* temporarily override X509_PURPOSE_SMIME_SIGN: */
|
||||
bak_purpose_id = X509_VERIFY_PARAM_get_purpose(vpm);
|
||||
if (!X509_STORE_set_purpose(ts, purpose_id)) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_SETTING_PURPOSE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkey_bio = CMS_SignedData_verify(sd, NULL, NULL /* scerts */, ts,
|
||||
extra, NULL, 0, libctx, propq);
|
||||
|
||||
if (!X509_STORE_set_purpose(ts, bak_purpose_id)) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_SETTING_PURPOSE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (pkey_bio == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* unpack AsymmetricKeyPackage */
|
||||
if ((ret = d2i_PrivateKey_ex_bio(pkey_bio, NULL, libctx, propq)) == NULL)
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_ENCRYPTEDKEY);
|
||||
|
||||
end:
|
||||
CMS_SignedData_free(sd);
|
||||
BIO_free(bio);
|
||||
BIO_free(pkey_bio);
|
||||
return ret;
|
||||
#else
|
||||
/* prevent warning on unused parameters: */
|
||||
((void)ts, (void)extra, (void)cert, (void)secret);
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_CMS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
#endif /* OPENSSL_NO_CMS */
|
||||
}
|
||||
|
||||
unsigned char
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_decrypt(const OSSL_CRMF_ENCRYPTEDVALUE *enc,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey, int *outlen)
|
||||
{
|
||||
X509 *cert = NULL; /* decrypted certificate */
|
||||
EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */
|
||||
unsigned char *ek = NULL; /* decrypted symmetric encryption key */
|
||||
size_t eksize = 0; /* size of decrypted symmetric encryption key */
|
||||
EVP_CIPHER *cipher = NULL; /* used cipher */
|
||||
int cikeysize = 0; /* key size from cipher */
|
||||
unsigned char *iv = NULL; /* initial vector for symmetric encryption */
|
||||
unsigned char *outbuf = NULL; /* decryption output buffer */
|
||||
const unsigned char *p = NULL; /* needed for decoding ASN1 */
|
||||
int n, outlen = 0;
|
||||
unsigned char *out = NULL; /* decryption output buffer */
|
||||
int n, ret = 0;
|
||||
EVP_PKEY_CTX *pkctx = NULL; /* private key context */
|
||||
char name[OSSL_MAX_NAME_SIZE];
|
||||
|
||||
if (ecert == NULL || ecert->symmAlg == NULL || ecert->encSymmKey == NULL
|
||||
|| ecert->encValue == NULL || pkey == NULL) {
|
||||
if (outlen == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
*outlen = 0;
|
||||
if (enc == NULL || enc->symmAlg == NULL || enc->encSymmKey == NULL
|
||||
|| enc->encValue == NULL || pkey == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* select symmetric cipher based on algorithm given in message */
|
||||
OBJ_obj2txt(name, sizeof(name), ecert->symmAlg->algorithm, 0);
|
||||
|
||||
OBJ_obj2txt(name, sizeof(name), enc->symmAlg->algorithm, 0);
|
||||
(void)ERR_set_mark();
|
||||
cipher = EVP_CIPHER_fetch(NULL, name, NULL);
|
||||
|
||||
cipher = EVP_CIPHER_fetch(libctx, name, propq);
|
||||
if (cipher == NULL)
|
||||
cipher = (EVP_CIPHER *)EVP_get_cipherbyname(name);
|
||||
|
||||
cipher = (EVP_CIPHER *)EVP_get_cipherbyobj(enc->symmAlg->algorithm);
|
||||
if (cipher == NULL) {
|
||||
(void)ERR_clear_last_mark();
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_CIPHER);
|
||||
|
@ -662,52 +805,141 @@ X509
|
|||
cikeysize = EVP_CIPHER_get_key_length(cipher);
|
||||
/* first the symmetric key needs to be decrypted */
|
||||
pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq);
|
||||
if (pkctx == NULL || EVP_PKEY_decrypt_init(pkctx) <= 0
|
||||
|| evp_pkey_decrypt_alloc(pkctx, &ek, &eksize, (size_t)cikeysize,
|
||||
ecert->encSymmKey->data,
|
||||
ecert->encSymmKey->length) <= 0)
|
||||
goto end;
|
||||
if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx) > 0) {
|
||||
ASN1_BIT_STRING *encKey = enc->encSymmKey;
|
||||
size_t failure;
|
||||
int retval;
|
||||
|
||||
if (EVP_PKEY_decrypt(pkctx, NULL, &eksize,
|
||||
encKey->data, encKey->length) <= 0
|
||||
|| (ek = OPENSSL_malloc(eksize)) == NULL)
|
||||
goto end;
|
||||
retval = EVP_PKEY_decrypt(pkctx, ek, &eksize, encKey->data, encKey->length);
|
||||
failure = ~constant_time_is_zero_s(constant_time_msb(retval)
|
||||
| constant_time_is_zero(retval));
|
||||
failure |= ~constant_time_eq_s(eksize, (size_t)cikeysize);
|
||||
if (failure) {
|
||||
ERR_clear_error(); /* error state may have sensitive information */
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
goto end;
|
||||
}
|
||||
if ((iv = OPENSSL_malloc(EVP_CIPHER_get_iv_length(cipher))) == NULL)
|
||||
goto end;
|
||||
if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv,
|
||||
if (ASN1_TYPE_get_octetstring(enc->symmAlg->parameter, iv,
|
||||
EVP_CIPHER_get_iv_length(cipher))
|
||||
!= EVP_CIPHER_get_iv_length(cipher)) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_MALFORMED_IV);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* d2i_X509 changes the given pointer, so use p for decoding the message and
|
||||
* keep the original pointer in outbuf so the memory can be freed later
|
||||
*/
|
||||
if ((p = outbuf = OPENSSL_malloc(ecert->encValue->length +
|
||||
EVP_CIPHER_get_block_size(cipher))) == NULL
|
||||
if ((out = OPENSSL_malloc(enc->encValue->length +
|
||||
EVP_CIPHER_get_block_size(cipher))) == NULL
|
||||
|| (evp_ctx = EVP_CIPHER_CTX_new()) == NULL)
|
||||
goto end;
|
||||
EVP_CIPHER_CTX_set_padding(evp_ctx, 0);
|
||||
|
||||
if (!EVP_DecryptInit(evp_ctx, cipher, ek, iv)
|
||||
|| !EVP_DecryptUpdate(evp_ctx, outbuf, &outlen,
|
||||
ecert->encValue->data,
|
||||
ecert->encValue->length)
|
||||
|| !EVP_DecryptFinal(evp_ctx, outbuf + outlen, &n)) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_CERTIFICATE);
|
||||
|| !EVP_DecryptUpdate(evp_ctx, out, outlen,
|
||||
enc->encValue->data,
|
||||
enc->encValue->length)
|
||||
|| !EVP_DecryptFinal(evp_ctx, out + *outlen, &n)) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE);
|
||||
goto end;
|
||||
}
|
||||
outlen += n;
|
||||
*outlen += n;
|
||||
ret = 1;
|
||||
|
||||
/* convert decrypted certificate from DER to internal ASN.1 structure */
|
||||
if ((cert = X509_new_ex(libctx, propq)) == NULL)
|
||||
goto end;
|
||||
if (d2i_X509(&cert, &p, outlen) == NULL)
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE);
|
||||
end:
|
||||
EVP_PKEY_CTX_free(pkctx);
|
||||
OPENSSL_free(outbuf);
|
||||
EVP_CIPHER_CTX_free(evp_ctx);
|
||||
EVP_CIPHER_free(cipher);
|
||||
OPENSSL_clear_free(ek, eksize);
|
||||
OPENSSL_free(iv);
|
||||
if (ret)
|
||||
return out;
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypts the certificate in the given encryptedValue using private key pkey.
|
||||
* This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
|
||||
*
|
||||
* returns a pointer to the decrypted certificate
|
||||
* returns NULL on error or if no certificate available
|
||||
*/
|
||||
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
unsigned char *buf = NULL;
|
||||
const unsigned char *p;
|
||||
int len;
|
||||
X509 *cert = NULL;
|
||||
|
||||
buf = OSSL_CRMF_ENCRYPTEDVALUE_decrypt(ecert, libctx, propq, pkey, &len);
|
||||
if ((p = buf) == NULL || (cert = X509_new_ex(libctx, propq)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (d2i_X509(&cert, &p, len) == NULL) {
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE);
|
||||
X509_free(cert);
|
||||
cert = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
OPENSSL_free(buf);
|
||||
return cert;
|
||||
}
|
||||
/*-
|
||||
* Decrypts the certificate in the given encryptedKey using private key pkey.
|
||||
* This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
|
||||
*
|
||||
* returns a pointer to the decrypted certificate
|
||||
* returns NULL on error or if no certificate available
|
||||
*/
|
||||
X509 *OSSL_CRMF_ENCRYPTEDKEY_get1_encCert(const OSSL_CRMF_ENCRYPTEDKEY *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey, unsigned int flags)
|
||||
{
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
BIO *bio;
|
||||
X509 *cert = NULL;
|
||||
#endif
|
||||
|
||||
if (ecert->type != OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA)
|
||||
return OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(ecert->value.encryptedValue,
|
||||
libctx, propq, pkey);
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
bio = CMS_EnvelopedData_decrypt(ecert->value.envelopedData, NULL,
|
||||
pkey, NULL /* cert */, NULL, flags,
|
||||
libctx, propq);
|
||||
if (bio == NULL)
|
||||
return NULL;
|
||||
cert = d2i_X509_bio(bio, NULL);
|
||||
if (cert == NULL)
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE);
|
||||
BIO_free(bio);
|
||||
return cert;
|
||||
#else
|
||||
(void)flags; /* prevent warning on unused parameter */
|
||||
ERR_raise(ERR_LIB_CRMF, CRMF_R_CMS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
#endif /* OPENSSL_NO_CMS */
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
OSSL_CRMF_ENCRYPTEDKEY *OSSL_CRMF_ENCRYPTEDKEY_init_envdata(CMS_EnvelopedData *envdata)
|
||||
{
|
||||
OSSL_CRMF_ENCRYPTEDKEY *ek = OSSL_CRMF_ENCRYPTEDKEY_new();
|
||||
|
||||
if (ek == NULL)
|
||||
return NULL;
|
||||
ek->type = OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA;
|
||||
ek->value.envelopedData = envdata;
|
||||
return ek;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# define OSSL_CRYPTO_CRMF_LOCAL_H
|
||||
|
||||
# include <openssl/crmf.h>
|
||||
# include <openssl/cms.h> /* for CMS_EnvelopedData and CMS_SignedData */
|
||||
# include <openssl/err.h>
|
||||
# include "internal/crmf.h" /* for ossl_crmf_attributetypeandvalue_st */
|
||||
|
||||
|
@ -52,6 +53,25 @@ struct ossl_crmf_encryptedvalue_st {
|
|||
ASN1_BIT_STRING *encValue;
|
||||
} /* OSSL_CRMF_ENCRYPTEDVALUE */;
|
||||
|
||||
/*
|
||||
* EncryptedKey ::= CHOICE {
|
||||
* encryptedValue EncryptedValue, -- Deprecated
|
||||
* envelopedData [0] EnvelopedData }
|
||||
* -- The encrypted private key MUST be placed in the envelopedData
|
||||
* -- encryptedContentInfo encryptedContent OCTET STRING.
|
||||
*/
|
||||
# define OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA 1
|
||||
|
||||
struct ossl_crmf_encryptedkey_st {
|
||||
int type;
|
||||
union {
|
||||
OSSL_CRMF_ENCRYPTEDVALUE *encryptedValue; /* 0 */ /* Deprecated */
|
||||
# ifndef OPENSSL_NO_CMS
|
||||
CMS_EnvelopedData *envelopedData; /* 1 */
|
||||
# endif
|
||||
} value;
|
||||
} /* OSSL_CRMF_ENCRYPTEDKEY */;
|
||||
|
||||
/*-
|
||||
* Attributes ::= SET OF Attribute
|
||||
* => X509_ATTRIBUTE
|
||||
|
|
|
@ -231,6 +231,7 @@ CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
|
|||
CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature
|
||||
CMP_R_EXPECTED_POLLREQ:104:expected pollreq
|
||||
CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain
|
||||
CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY:203:failed extracting central gen key
|
||||
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
|
||||
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
|
||||
CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range
|
||||
|
@ -243,6 +244,7 @@ CMP_R_INVALID_GENP:193:invalid genp
|
|||
CMP_R_INVALID_KEYSPEC:202:invalid keyspec
|
||||
CMP_R_INVALID_OPTION:174:invalid option
|
||||
CMP_R_INVALID_ROOTCAKEYUPDATE:195:invalid rootcakeyupdate
|
||||
CMP_R_MISSING_CENTRAL_GEN_KEY:204:missing central gen key
|
||||
CMP_R_MISSING_CERTID:165:missing certid
|
||||
CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\
|
||||
missing key input for creating protection
|
||||
|
@ -279,6 +281,7 @@ CMP_R_TOTAL_TIMEOUT:184:total timeout
|
|||
CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
|
||||
CMP_R_TRANSFER_ERROR:159:transfer error
|
||||
CMP_R_UNCLEAN_CTX:191:unclean ctx
|
||||
CMP_R_UNEXPECTED_CENTRAL_GEN_KEY:205:unexpected central gen key
|
||||
CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile
|
||||
CMP_R_UNEXPECTED_CRLSTATUSLIST:201:unexpected crlstatuslist
|
||||
CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
|
||||
|
@ -448,16 +451,23 @@ CONF_R_UNKNOWN_MODULE_NAME:113:unknown module name
|
|||
CONF_R_VARIABLE_EXPANSION_TOO_LONG:116:variable expansion too long
|
||||
CONF_R_VARIABLE_HAS_NO_VALUE:104:variable has no value
|
||||
CRMF_R_BAD_PBM_ITERATIONCOUNT:100:bad pbm iterationcount
|
||||
CRMF_R_CMS_NOT_SUPPORTED:122:cms not supported
|
||||
CRMF_R_CRMFERROR:102:crmferror
|
||||
CRMF_R_ERROR:103:error
|
||||
CRMF_R_ERROR_DECODING_CERTIFICATE:104:error decoding certificate
|
||||
CRMF_R_ERROR_DECODING_ENCRYPTEDKEY:123:error decoding encryptedkey
|
||||
CRMF_R_ERROR_DECRYPTING_CERTIFICATE:105:error decrypting certificate
|
||||
CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY:124:error decrypting encryptedkey
|
||||
CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE:125:error decrypting encryptedvalue
|
||||
CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY:106:error decrypting symmetric key
|
||||
CRMF_R_ERROR_SETTING_PURPOSE:126:error setting purpose
|
||||
CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY:127:error verifying encryptedkey
|
||||
CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random
|
||||
CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100
|
||||
CRMF_R_MALFORMED_IV:101:malformed iv
|
||||
CRMF_R_NULL_ARGUMENT:109:null argument
|
||||
CRMF_R_POPOSKINPUT_NOT_SUPPORTED:113:poposkinput not supported
|
||||
CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN:128:popo inconsistent central keygen
|
||||
CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key
|
||||
CRMF_R_POPO_MISSING:121:popo missing
|
||||
CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key
|
||||
|
|
56
doc/internal/man3/ossl_cms_sign_encrypt.pod
Normal file
56
doc/internal/man3/ossl_cms_sign_encrypt.pod
Normal file
|
@ -0,0 +1,56 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ossl_cms_sign_encrypt
|
||||
- Create CMS envelope
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_EnvelopedData *ossl_cms_sign_encrypt(BIO *data, X509 *sign_cert, STACK_OF(X509) *certs,
|
||||
EVP_PKEY *sign_key, unsigned int sign_flags,
|
||||
STACK_OF(X509) *enc_recip, const EVP_CIPHER *cipher,
|
||||
unsigned int enc_flags, OSSL_LIB_CTX *libctx,
|
||||
const char *propq);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
ossl_cms_sign_encrypt() creates a B<CMS_EnvelopedData> structure for recipients in
|
||||
I<enc_recip>.
|
||||
|
||||
I<data> is signed using I<signcert> and I<signkey> to create B<CMS_SignedData>
|
||||
and then encrypted using I<enc_recip> to create B<CMS_EnvelopedData>.
|
||||
The library context I<libctx> and the property query I<propq> are used
|
||||
when retrieving algorithms from providers.
|
||||
|
||||
I<certs> is an optional additional set of certificates to include in the
|
||||
B<CMS_SignedData> structure (e.g., any intermediate CAs in the chain of the signer certificate).
|
||||
|
||||
I<sign_flags> is an optional set of flags for the signing operation.
|
||||
See L<CMS_sign_ex(3)> for more information.
|
||||
|
||||
I<enc_flags> is an optional set of flags for the encryption operation.
|
||||
See L<CMS_encrypt_ex(3)> for more information.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
If the allocation fails, ossl_cms_sign_encrypt() returns NULL and
|
||||
sets an error code that can be obtained by L<ERR_get_error(3)>.
|
||||
Otherwise, it returns a pointer to the newly allocated structure.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
ossl_cms_sign_encrypt() was added in OpenSSL 3.5.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2023 - 2024 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
|
|
@ -26,6 +26,8 @@ Certificate enrollment options:
|
|||
|
||||
[B<-newkey> I<filename>|I<uri>]
|
||||
[B<-newkeypass> I<arg>]
|
||||
[B<-centralkeygen>
|
||||
[B<-newkeyout> I<filename>]
|
||||
[B<-subject> I<name>]
|
||||
[B<-days> I<number>]
|
||||
[B<-reqexts> I<name>]
|
||||
|
@ -140,6 +142,8 @@ Mock server options:
|
|||
[B<-srv_untrusted> I<filenames>|I<uris>]
|
||||
[B<-ref_cert> I<filename>|I<uri>]
|
||||
[B<-rsp_cert> I<filename>|I<uri>]
|
||||
[B<-rsp_key> I<filename>|I<uri>]
|
||||
[B<-rsp_keypass> I<filename>|I<uri>]
|
||||
[B<-rsp_crl> I<filename>|I<uri>]
|
||||
[B<-rsp_extracerts> I<filenames>|I<uris>]
|
||||
[B<-rsp_capubs> I<filenames>|I<uris>]
|
||||
|
@ -308,6 +312,15 @@ If not given here, the password will be prompted for if needed.
|
|||
For more information about the format of I<arg> see
|
||||
L<openssl-passphrase-options(1)>.
|
||||
|
||||
=item B<-centralkeygen>
|
||||
|
||||
Request central key generation for certificate enrollment.
|
||||
This applies to B<-cmd> I<ir|cr|kur|p10cr>.
|
||||
|
||||
=item B<-newkeyout> I<filename>
|
||||
|
||||
File to save centrally generated private key, in PEM format.
|
||||
|
||||
=item B<-subject> I<name>
|
||||
|
||||
X.509 Distinguished Name (DN) to use as subject field
|
||||
|
@ -380,7 +393,8 @@ Flag the policies given with B<-policy_oids> as critical.
|
|||
=item B<-popo> I<number>
|
||||
|
||||
Proof-of-possession (POPO) method to use for IR/CR/KUR; values: C<-1>..<2> where
|
||||
C<-1> = NONE, C<0> = RAVERIFIED, C<1> = SIGNATURE (default), C<2> = KEYENC.
|
||||
C<-1> = NONE, which implies central key generation,
|
||||
C<0> = RAVERIFIED, C<1> = SIGNATURE (default), C<2> = KEYENC.
|
||||
|
||||
Note that a signature-based POPO can only be produced if a private key
|
||||
is provided via the B<-newkey> or B<-key> options.
|
||||
|
@ -920,7 +934,7 @@ See L<openssl(1)/Format Options> for details.
|
|||
|
||||
Pass phrase source for certificate given with the B<-trusted>, B<-untrusted>,
|
||||
B<-own_trusted>, B<-srvcert>, B<-crlcert>, B<-out_trusted>, B<-extracerts>,
|
||||
B<-srv_trusted>, B<-srv_untrusted>, B<-ref_cert>, B<-rsp_cert>,
|
||||
B<-srv_trusted>, B<-srv_untrusted>, B<-ref_cert>,
|
||||
B<-rsp_extracerts>, B<-rsp_capubs>,
|
||||
B<-rsp_newwithnew>, B<-rsp_newwithold>, B<-rsp_oldwithnew>,
|
||||
B<-tls_extra>, and B<-tls_trusted> options.
|
||||
|
@ -1194,6 +1208,14 @@ Certificate to be expected for RR messages and any oldCertID in KUR messages.
|
|||
|
||||
Certificate to be returned as mock enrollment result.
|
||||
|
||||
=item B<-rsp_key> I<filename>|I<uri>
|
||||
|
||||
Private key to be returned as central key generation result.
|
||||
|
||||
=item B<-rsp_keypass> I<arg>
|
||||
|
||||
Pass phrase source for B<rsp_cert> and B<rsp_key>.
|
||||
|
||||
=item B<-rsp_crl> I<filename>|I<uri>
|
||||
|
||||
CRL to be returned in genp of type C<crls>.
|
||||
|
@ -1500,6 +1522,9 @@ The B<-profile> option was added in OpenSSL 3.3.
|
|||
B<-crlcert>, B<-oldcrl>, B<-crlout>, B<-crlform>
|
||||
and B<-rsp_crl> options were added in OpenSSL 3.4.
|
||||
|
||||
B<-centralkeygen>, b<-newkeyout>, B<-rsp_key> and
|
||||
B<-rsp_keypass> were added in OpenSSL 3.5.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
|
|
@ -57,19 +57,24 @@ The wrappers L<CMS_encrypt(3)> and L<CMS_decrypt(3)> are often used instead.
|
|||
=head1 RETURN VALUES
|
||||
|
||||
If the allocation fails, CMS_EnvelopedData_create_ex(),
|
||||
CMS_EnvelopedData_create(), CMS_AuthEnvelopedData_create_ex(), and
|
||||
CMS_AuthEnvelopedData_create() return NULL and set an error code that can be
|
||||
obtained by L<ERR_get_error(3)>. Otherwise they return a pointer to the newly
|
||||
allocated structure.
|
||||
CMS_EnvelopedData_create(), CMS_AuthEnvelopedData_create_ex(),
|
||||
CMS_AuthEnvelopedData_create(), CMS_AuthEnvelopedData_create(),
|
||||
and CMS_AuthEnvelopedData_create_ex() return NULL and set an
|
||||
error code that can be obtained by L<ERR_get_error(3)>.
|
||||
Otherwise, they return a pointer to the newly allocated structure.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<ERR_get_error(3)>, L<CMS_encrypt(3)>, L<CMS_decrypt(3)>, L<CMS_final(3)>
|
||||
L<ERR_get_error(3)>, L<CMS_encrypt(3)>, L<CMS_decrypt(3)>, L<CMS_final(3)>,
|
||||
L<CMS_sign_ex(3)>, L<CMS_encrypt_ex(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The CMS_EnvelopedData_create_ex() method was added in OpenSSL 3.0.
|
||||
|
||||
CMS_AuthEnvelopedData_create() and CMS_AuthEnvelopedData_create_ex()
|
||||
were added in OpenSSL 3.5.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
|
|
@ -273,7 +273,8 @@ The following options can be set:
|
|||
|
||||
Select the proof of possession method to use. Possible values are:
|
||||
|
||||
OSSL_CRMF_POPO_NONE - ProofOfPossession field omitted
|
||||
OSSL_CRMF_POPO_NONE - ProofOfPossession field omitted,
|
||||
which implies central key generation
|
||||
OSSL_CRMF_POPO_RAVERIFIED - assert that the RA has already
|
||||
verified the PoPo
|
||||
OSSL_CRMF_POPO_SIGNATURE - sign a value with private key,
|
||||
|
|
|
@ -10,8 +10,13 @@ OSSL_CRMF_CERTTEMPLATE_get0_serialNumber,
|
|||
OSSL_CRMF_CERTTEMPLATE_get0_extensions,
|
||||
OSSL_CRMF_CERTID_get0_serialNumber,
|
||||
OSSL_CRMF_CERTID_get0_issuer,
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_encCert,
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_pkey,
|
||||
OSSL_CRMF_ENCRYPTEDKEY_init_envdata,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_decrypt,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert,
|
||||
OSSL_CRMF_MSG_get_certReqId
|
||||
OSSL_CRMF_MSG_get_certReqId,
|
||||
OSSL_CRMF_MSG_centralkeygen_requested
|
||||
- functions reading from CRMF CertReqMsg structures
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
@ -34,12 +39,30 @@ OSSL_CRMF_MSG_get_certReqId
|
|||
*OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid);
|
||||
const X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid);
|
||||
|
||||
X509 *OSSL_CRMF_ENCRYPTEDKEY_get1_encCert(const OSSL_CRMF_ENCRYPTEDKEY *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey, unsigned int flags);
|
||||
EVP_PKEY
|
||||
*OSSL_CRMF_ENCRYPTEDKEY_get1_pkey(OSSL_CRMF_ENCRYPTEDKEY *encryptedKey,
|
||||
X509_STORE *ts, STACK_OF(X509) *extra,
|
||||
EVP_PKEY *pkey, X509 *cert,
|
||||
ASN1_OCTET_STRING *secret,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
OSSL_CRMF_ENCRYPTEDKEY
|
||||
*OSSL_CRMF_ENCRYPTEDKEY_init_envdata(CMS_EnvelopedData *envdata);
|
||||
|
||||
unsigned char
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_decrypt(const OSSL_CRMF_ENCRYPTEDVALUE *enc,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey, int *outlen);
|
||||
X509
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey);
|
||||
|
||||
int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm);
|
||||
int OSSL_CRMF_MSG_centralkeygen_requested(const OSSL_CRMF_MSG *crm,
|
||||
const X509_REQ *p10cr);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
@ -66,6 +89,33 @@ of the given CertId I<cid>.
|
|||
OSSL_CRMF_CERTID_get0_issuer retrieves the issuer name
|
||||
of the given CertId I<cid>, which must be of ASN.1 type GEN_DIRNAME.
|
||||
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_encCert() decrypts the certificate in the given
|
||||
encryptedKey I<ecert>, using the private key I<pkey>, library context
|
||||
I<libctx> and property query string I<propq> (see L<OSSL_LIB_CTX(3)>).
|
||||
This is needed for the indirect POPO method as in RFC 4210 section 5.2.8.2.
|
||||
The function returns the decrypted certificate as a copy, leaving its ownership
|
||||
with the caller, who is responsible for freeing it.
|
||||
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_pkey() decrypts the private key in I<encryptedKey>.
|
||||
If I<encryptedKey> is not of type B<OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA>,
|
||||
decryption uses the private key I<pkey>.
|
||||
The library context I<libctx> and property query I<propq> are taken into account as usual.
|
||||
The rest of this paragraph is relevant only if CMS support not disabled for the OpenSSL build
|
||||
and I<encryptedKey> is of type case B<OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA>.
|
||||
Decryption uses the I<secret> parameter if not NULL;
|
||||
otherwise uses the private key <pkey> and the certificate I<cert>
|
||||
related to I<pkey>, where I<cert> is recommended to be given if available.
|
||||
On success, the function verifies the decrypted data as signed data,
|
||||
using the trust store I<ts> and any untrusted certificates in I<extra>.
|
||||
Doing so, it checks for the purpose "CMP Key Generation Authority" (cmKGA).
|
||||
|
||||
OSSL_CRMF_ENCRYPTEDKEY_init_envdata() returns I<OSSL_CRMF_ENCRYPTEDKEY>, intialized with
|
||||
the enveloped data I<envdata>.
|
||||
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_decrypt() decrypts the encrypted value in the given
|
||||
encryptedValue I<enc>, using the private key I<pkey>, library context
|
||||
I<libctx> and property query string I<propq> (see L<OSSL_LIB_CTX(3)>).
|
||||
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert() decrypts the certificate in the given
|
||||
encryptedValue I<ecert>, using the private key I<pkey>, library context
|
||||
I<libctx> and property query string I<propq> (see L<OSSL_LIB_CTX(3)>).
|
||||
|
@ -75,11 +125,21 @@ with the caller, who is responsible for freeing it.
|
|||
|
||||
OSSL_CRMF_MSG_get_certReqId() retrieves the certReqId of I<crm>.
|
||||
|
||||
OSSL_CRMF_MSG_centralkeygen_requested() returns 1 if central key generation
|
||||
is requested i.e., the public key in the certificate request (I<crm> is taken if it is non-NULL,
|
||||
otherwise I<p10cr>) is NULL or has an empty key value (with length zero).
|
||||
In case I<crm> is non-NULL, this is checked for consistency with its B<popo> field
|
||||
(must be NULL if and only if central key generation is requested).
|
||||
Otherwise it returns 0, and on error a negative value.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_CRMF_MSG_get_certReqId() returns the certificate request ID as a
|
||||
nonnegative integer or -1 on error.
|
||||
|
||||
OSSL_CRMF_MSG_centralkeygen_requested() returns 1 if central key generation
|
||||
is requested, 0 if it is not requested, and a negative value on error.
|
||||
|
||||
All other functions return a pointer with the intended result or NULL on error.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
@ -92,6 +152,10 @@ The OpenSSL CRMF support was added in OpenSSL 3.0.
|
|||
|
||||
OSSL_CRMF_CERTTEMPLATE_get0_publicKey() was added in OpenSSL 3.2.
|
||||
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_encCert(), OSSL_CRMF_ENCRYPTEDKEY_get1_pkey(),
|
||||
OSSL_CRMF_ENCRYPTEDKEY_init_envdata(), OSSL_CRMF_ENCRYPTEDVALUE_decrypt()
|
||||
and OSSL_CRMF_MSG_centralkeygen_requested() were added in OpenSSL 3.5.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
|
|
@ -240,6 +240,9 @@ X509_VERIFY_PARAM_get_depth() returns the current verification depth.
|
|||
X509_VERIFY_PARAM_get_auth_level() returns the current authentication security
|
||||
level.
|
||||
|
||||
X509_VERIFY_PARAM_get_purpose() returns the current purpose,
|
||||
which may be B<X509_PURPOSE_DEFAULT_ANY> if unset.
|
||||
|
||||
=head1 VERIFICATION FLAGS
|
||||
|
||||
The verification flags consists of zero or more of the following flags
|
||||
|
|
|
@ -64,7 +64,8 @@ keyUsage, extendedKeyUsage, and basicConstraints.
|
|||
|
||||
X509_PURPOSE_get_count() returns the number of currently defined purposes.
|
||||
|
||||
X509_PURPOSE_get_unused_id() returns the smallest purpose id not yet used.
|
||||
X509_PURPOSE_get_unused_id() returns the smallest purpose id not yet used,
|
||||
which is guaranteed to be unique and larger than B<X509_PURPOSE_MAX>.
|
||||
The I<libctx> parameter should be used to provide the library context.
|
||||
It is currently ignored as the purpose mapping table is global.
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ CMS_ContentInfo_new,
|
|||
CMS_ContentInfo_new_ex,
|
||||
CMS_ContentInfo_print_ctx,
|
||||
CMS_EnvelopedData_it,
|
||||
CMS_EnvelopedData_dup,
|
||||
CMS_ReceiptRequest_free,
|
||||
CMS_ReceiptRequest_new,
|
||||
CMS_SignedData_free,
|
||||
|
@ -202,6 +203,9 @@ OSSL_CRMF_CERTTEMPLATE_new,
|
|||
OSSL_CRMF_CERTTEMPLATE_dup,
|
||||
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_dup,
|
||||
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free,
|
||||
OSSL_CRMF_ENCRYPTEDKEY_free,
|
||||
OSSL_CRMF_ENCRYPTEDKEY_it,
|
||||
OSSL_CRMF_ENCRYPTEDKEY_new,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_free,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_it,
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_new,
|
||||
|
@ -595,7 +599,9 @@ OSSL_TIME_SPEC_TIME_it(), OSSL_TIME_SPEC_TIME_new(),
|
|||
OSSL_TIME_SPEC_WEEKS_free(), OSSL_TIME_SPEC_WEEKS_it(),
|
||||
OSSL_TIME_SPEC_WEEKS_new(), OSSL_TIME_SPEC_X_DAY_OF_free(),
|
||||
OSSL_TIME_SPEC_X_DAY_OF_it(), OSSL_TIME_SPEC_X_DAY_OF_new(),
|
||||
OSSL_TIME_SPEC_free(), OSSL_TIME_SPEC_it(), OSSL_TIME_SPEC_new()
|
||||
OSSL_TIME_SPEC_free(), OSSL_TIME_SPEC_it(), OSSL_TIME_SPEC_new(),
|
||||
CMS_EnvelopedData_dup(), OSSL_CRMF_ENCRYPTEDKEY_free(),
|
||||
OSSL_CRMF_ENCRYPTEDKEY_it() and OSSL_CRMF_ENCRYPTEDKEY_new()
|
||||
were added in OpenSSL 3.5.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
|
|
@ -108,6 +108,7 @@ d2i_OSSL_CMP_PKIHEADER,
|
|||
d2i_OSSL_CMP_PKISI,
|
||||
d2i_OSSL_CRMF_CERTID,
|
||||
d2i_OSSL_CRMF_CERTTEMPLATE,
|
||||
d2i_OSSL_CRMF_ENCRYPTEDKEY,
|
||||
d2i_OSSL_CRMF_ENCRYPTEDVALUE,
|
||||
d2i_OSSL_CRMF_MSG,
|
||||
d2i_OSSL_CRMF_MSGS,
|
||||
|
@ -322,6 +323,7 @@ i2d_OSSL_CMP_PKIHEADER,
|
|||
i2d_OSSL_CMP_PKISI,
|
||||
i2d_OSSL_CRMF_CERTID,
|
||||
i2d_OSSL_CRMF_CERTTEMPLATE,
|
||||
i2d_OSSL_CRMF_ENCRYPTEDKEY,
|
||||
i2d_OSSL_CRMF_ENCRYPTEDVALUE,
|
||||
i2d_OSSL_CRMF_MSG,
|
||||
i2d_OSSL_CRMF_MSGS,
|
||||
|
@ -734,6 +736,7 @@ i2d_OSSL_ATTRIBUTE_VALUE_MAPPING(), i2d_OSSL_AUTHORITY_ATTRIBUTE_ID_SYNTAX(),
|
|||
i2d_OSSL_HASH(), i2d_OSSL_INFO_SYNTAX(),
|
||||
i2d_OSSL_INFO_SYNTAX_POINTER(), i2d_OSSL_PRIVILEGE_POLICY_ID(),
|
||||
i2d_OSSL_ROLE_SPEC_CERT_ID(), i2d_OSSL_ROLE_SPEC_CERT_ID_SYNTAX(),
|
||||
d2i_OSSL_CRMF_ENCRYPTEDKEY(), i2d_OSSL_CRMF_ENCRYPTEDKEY(),
|
||||
d2i_OSSL_DAY_TIME(), d2i_OSSL_DAY_TIME_BAND(), d2i_OSSL_NAMED_DAY(),
|
||||
d2i_OSSL_TIME_PERIOD(), d2i_OSSL_TIME_SPEC(),
|
||||
d2i_OSSL_TIME_SPEC_ABSOLUTE(), d2i_OSSL_TIME_SPEC_DAY(),
|
||||
|
|
22
include/internal/cms.h
Normal file
22
include/internal/cms.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2019-2024 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
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
#ifndef OSSL_INTERNAL_CMS_H
|
||||
# define OSSL_INTERNAL_CMS_H
|
||||
# pragma once
|
||||
|
||||
# include <openssl/cms.h>
|
||||
|
||||
# ifndef OPENSSL_NO_CMS
|
||||
CMS_EnvelopedData *ossl_cms_sign_encrypt(BIO *data, X509 *sign_cert, STACK_OF(X509) *certs,
|
||||
EVP_PKEY *sign_key, unsigned int sign_flags,
|
||||
STACK_OF(X509) *enc_recip, const EVP_CIPHER *cipher,
|
||||
unsigned int enc_flags, OSSL_LIB_CTX *libctx,
|
||||
const char *propq);
|
||||
# endif /* OPENSSL_NO_CMS */
|
||||
#endif /* OSSL_INTERNAL_CMS_H */
|
|
@ -57,6 +57,7 @@
|
|||
# define CMP_R_ERROR_VALIDATING_SIGNATURE 171
|
||||
# define CMP_R_EXPECTED_POLLREQ 104
|
||||
# define CMP_R_FAILED_BUILDING_OWN_CHAIN 164
|
||||
# define CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY 203
|
||||
# define CMP_R_FAILED_EXTRACTING_PUBKEY 141
|
||||
# define CMP_R_FAILURE_OBTAINING_RANDOM 110
|
||||
# define CMP_R_FAIL_INFO_OUT_OF_RANGE 129
|
||||
|
@ -69,6 +70,7 @@
|
|||
# define CMP_R_INVALID_KEYSPEC 202
|
||||
# define CMP_R_INVALID_OPTION 174
|
||||
# define CMP_R_INVALID_ROOTCAKEYUPDATE 195
|
||||
# define CMP_R_MISSING_CENTRAL_GEN_KEY 204
|
||||
# define CMP_R_MISSING_CERTID 165
|
||||
# define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130
|
||||
# define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE 142
|
||||
|
@ -103,6 +105,7 @@
|
|||
# define CMP_R_TRANSACTIONID_UNMATCHED 152
|
||||
# define CMP_R_TRANSFER_ERROR 159
|
||||
# define CMP_R_UNCLEAN_CTX 191
|
||||
# define CMP_R_UNEXPECTED_CENTRAL_GEN_KEY 205
|
||||
# define CMP_R_UNEXPECTED_CERTPROFILE 196
|
||||
# define CMP_R_UNEXPECTED_CRLSTATUSLIST 201
|
||||
# define CMP_R_UNEXPECTED_PKIBODY 133
|
||||
|
|
|
@ -57,6 +57,8 @@ DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
|
|||
DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
|
||||
|
||||
DECLARE_ASN1_DUP_FUNCTION(CMS_EnvelopedData)
|
||||
|
||||
CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
|
||||
|
||||
# define CMS_SIGNERINFO_ISSUER_SERIAL 0
|
||||
|
|
|
@ -27,6 +27,7 @@ use OpenSSL::stackhash qw(generate_stack_macros);
|
|||
# include <openssl/safestack.h>
|
||||
# include <openssl/crmferr.h>
|
||||
# include <openssl/x509v3.h> /* for GENERAL_NAME etc. */
|
||||
# include <openssl/cms.h>
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
# include <openssl/types.h>
|
||||
|
@ -45,8 +46,11 @@ extern "C" {
|
|||
# define OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT 0
|
||||
# define OSSL_CRMF_SUBSEQUENTMESSAGE_CHALLENGERESP 1
|
||||
typedef struct ossl_crmf_encryptedvalue_st OSSL_CRMF_ENCRYPTEDVALUE;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE)
|
||||
|
||||
typedef struct ossl_crmf_encryptedkey_st OSSL_CRMF_ENCRYPTEDKEY;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDKEY)
|
||||
|
||||
typedef struct ossl_crmf_msg_st OSSL_CRMF_MSG;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSG)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_MSG)
|
||||
|
@ -177,10 +181,24 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
|||
const X509_NAME *subject,
|
||||
const X509_NAME *issuer,
|
||||
const ASN1_INTEGER *serial);
|
||||
X509
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey);
|
||||
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey);
|
||||
X509 *OSSL_CRMF_ENCRYPTEDKEY_get1_encCert(const OSSL_CRMF_ENCRYPTEDKEY *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey, unsigned int flags);
|
||||
unsigned char
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_decrypt(const OSSL_CRMF_ENCRYPTEDVALUE *enc,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey, int *outlen);
|
||||
EVP_PKEY *OSSL_CRMF_ENCRYPTEDKEY_get1_pkey(const OSSL_CRMF_ENCRYPTEDKEY *encryptedKey,
|
||||
X509_STORE *ts, STACK_OF(X509) *extra, EVP_PKEY *pkey,
|
||||
X509 *cert, ASN1_OCTET_STRING *secret,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
int OSSL_CRMF_MSG_centralkeygen_requested(const OSSL_CRMF_MSG *crm, const X509_REQ *p10cr);
|
||||
# ifndef OPENSSL_NO_CMS
|
||||
OSSL_CRMF_ENCRYPTEDKEY *OSSL_CRMF_ENCRYPTEDKEY_init_envdata(CMS_EnvelopedData *envdata);
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -24,16 +24,23 @@
|
|||
* CRMF reason codes.
|
||||
*/
|
||||
# define CRMF_R_BAD_PBM_ITERATIONCOUNT 100
|
||||
# define CRMF_R_CMS_NOT_SUPPORTED 122
|
||||
# define CRMF_R_CRMFERROR 102
|
||||
# define CRMF_R_ERROR 103
|
||||
# define CRMF_R_ERROR_DECODING_CERTIFICATE 104
|
||||
# define CRMF_R_ERROR_DECODING_ENCRYPTEDKEY 123
|
||||
# define CRMF_R_ERROR_DECRYPTING_CERTIFICATE 105
|
||||
# define CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY 124
|
||||
# define CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE 125
|
||||
# define CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY 106
|
||||
# define CRMF_R_ERROR_SETTING_PURPOSE 126
|
||||
# define CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY 127
|
||||
# define CRMF_R_FAILURE_OBTAINING_RANDOM 107
|
||||
# define CRMF_R_ITERATIONCOUNT_BELOW_100 108
|
||||
# define CRMF_R_MALFORMED_IV 101
|
||||
# define CRMF_R_NULL_ARGUMENT 109
|
||||
# define CRMF_R_POPOSKINPUT_NOT_SUPPORTED 113
|
||||
# define CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN 128
|
||||
# define CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY 117
|
||||
# define CRMF_R_POPO_MISSING 121
|
||||
# define CRMF_R_POPO_MISSING_PUBLIC_KEY 118
|
||||
|
|
|
@ -32,6 +32,8 @@ plan skip_all => "These tests are not supported in a no-sock build"
|
|||
if disabled("sock");
|
||||
plan skip_all => "These tests are not supported in a no-http build"
|
||||
if disabled("http");
|
||||
plan skip_all => "These tests are not supported in a no-cms build"
|
||||
if disabled("cms"); # central key pair generation
|
||||
|
||||
plan skip_all => "Tests involving local HTTP server not available on Windows or VMS"
|
||||
if $^O =~ /^(VMS|MSWin32|msys)$/;
|
||||
|
|
|
@ -12,6 +12,7 @@ no_cache_extracerts = 1
|
|||
|
||||
ref_cert = signer_only.crt
|
||||
rsp_cert = signer_only.crt
|
||||
rsp_key = new.key
|
||||
rsp_crl = newcrl.pem
|
||||
rsp_capubs = trusted.crt
|
||||
rsp_extracerts = signer_issuing.crt
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
Issuer: CN=Root CA
|
||||
Validity
|
||||
Not Before: Jan 14 22:29:46 2016 GMT
|
||||
Not After : Jan 15 22:29:46 2116 GMT
|
||||
Not Before: Aug 8 13:28:36 2024 GMT
|
||||
Not After : Apr 11 13:28:36 2127 GMT
|
||||
Subject: CN=server.example
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDJTCCAg2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||
IENBMCAXDTE2MDExNDIyMjk0NloYDzIxMTYwMTE1MjIyOTQ2WjAZMRcwFQYDVQQD
|
||||
DA5zZXJ2ZXIuZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
ANVdYGrf/GHuSKqMEUhDpW22Ul2qmEmxYZI1sfw6BCUMbXn/tNXJ6VwcO+Crs7h9
|
||||
o95tveDd11q/FEcRQl6mgtBhwX/dE0bmCYUHDvLU/Bpk0gqtIKsga5bwrczEGVNV
|
||||
3AEdpLPvirRJU12KBRzx3OFEv8XX4ncZV1yXC3XuiENxD8pswbSyUKd3RmxYDxG/
|
||||
8XYkWq45QrdRZynh0FUwbxfkkeqt+CjCQ2+iZKn7nZiSYkg+6w1PgkqK/z9y7pa1
|
||||
rqHBmLrvfZB1bf9aUp6r9cB+0IdD24UHBw99OHr90dPuZR3T6jlqhzfuStPgDW71
|
||||
cKzCvfFu85KVXqnwoWWVk40CAwEAAaN9MHswHQYDVR0OBBYEFMDnhL/oWSczELBS
|
||||
T1FSLwbWwHrNMB8GA1UdIwQYMBaAFHB/Lq6DaFmYBCMqzes+F80k3QFJMAkGA1Ud
|
||||
EwQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4
|
||||
YW1wbGUwDQYJKoZIhvcNAQELBQADggEBAHvTBEN1ig8RrsT716Ginv4gGNX0LzGI
|
||||
RrZ1jO7lm5emuaPNYJpGw0iX5Zdo91qGNXPZaZ75X3S55pQTActq3OPEBOll2pyk
|
||||
iyjz+Zp/v5cfRZLlBbFW5gv2R94eibYr4U3fSn4B0yPcl4xH/l/HzJhGDsSDW8qK
|
||||
8VIJvmvsPwmL0JMCv+FR59F+NFYZdND/KCXet59WUpF9ICmFCoBEX3EyJXEPwhbi
|
||||
X2sdPzJbCjx0HLli8e0HUKNttLQxCsBTRGo6iISLLamwN47mGDa9miBADwGSiz2q
|
||||
YeeuLO02zToHhnQ6KbPXOrQAqcL1kngO4g+j/ru+4AZThFkdkGnltvk=
|
||||
MIIDVDCCAjygAwIBAgIUMoDahWpYk1B1WIjOwkom4s27V/EwDQYJKoZIhvcNAQEL
|
||||
BQAwEjEQMA4GA1UEAwwHUm9vdCBDQTAgFw0yNDA4MDgxMzI4MzZaGA8yMTI3MDQx
|
||||
MTEzMjgzNlowGTEXMBUGA1UEAwwOc2VydmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQDVXWBq3/xh7kiqjBFIQ6VttlJdqphJsWGSNbH8
|
||||
OgQlDG15/7TVyelcHDvgq7O4faPebb3g3ddavxRHEUJepoLQYcF/3RNG5gmFBw7y
|
||||
1PwaZNIKrSCrIGuW8K3MxBlTVdwBHaSz74q0SVNdigUc8dzhRL/F1+J3GVdclwt1
|
||||
7ohDcQ/KbMG0slCnd0ZsWA8Rv/F2JFquOUK3UWcp4dBVMG8X5JHqrfgowkNvomSp
|
||||
+52YkmJIPusNT4JKiv8/cu6Wta6hwZi6732QdW3/WlKeq/XAftCHQ9uFBwcPfTh6
|
||||
/dHT7mUd0+o5aoc37krT4A1u9XCswr3xbvOSlV6p8KFllZONAgMBAAGjgZgwgZUw
|
||||
CQYDVR0TBAIwADAdBgNVHQ4EFgQUwOeEv+hZJzMQsFJPUVIvBtbAes0wHwYDVR0j
|
||||
BBgwFoAUcH8uroNoWZgEIyrN6z4XzSTdAUkwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud
|
||||
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDIDAZBgNVHREEEjAQgg5zZXJ2ZXIuZXhh
|
||||
bXBsZTANBgkqhkiG9w0BAQsFAAOCAQEAPRQ87zMFGrcQau8h8wDULU2PPgo1nifQ
|
||||
1Vs+4WD7bPzk5GHl3M3OE2ZwhzYfO+ACcJa29Ahu7GRC660lXKlwONnQYuTTLqPD
|
||||
KylY9ZJQUyP+CA5oZsDtnOcfrTy837jKq18NQ3ZxbRDpoVIATNHf9J2qe9yIkxYe
|
||||
9p+aXGdvfDsNrhkz/m76V+KmioventOEKsRg64FfGKEZP8EfoBiNJipBdmN1I+GE
|
||||
VTW91jjpgBTdCmyncmVn/CaV1d5S4ed4oQMLlLc+KsqDe97bF2TssFxcMmnyxgqb
|
||||
bKDZOfzPI1HTs22tj6eLcZTIkcAuFET+uxcmFQcDsjYEf0G+iZLGWw==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -135,5 +135,17 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty
|
|||
1,reqout_only ir - no server, -section,, -cmd,ir,,-reqout_only,_RESULT_DIR/ir2.der,,BLANK,,BLANK, -server,""""
|
||||
0,reqout_only non-existing directory and file, -section,, -cmd,ir,,-reqout_only,idontexist/idontexist,,BLANK,,BLANK, -server,""""
|
||||
0,reqin ir - no newkey, -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir2.der,,-newkey,"""",-newkey,"""",-key,"""",-cert,"""",-secret,_PBM_SECRET
|
||||
1,reqin ir and rspout - no newkey but -popo -1, -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir2.der,,-rspout,_RESULT_DIR/ip2.der,-newkey,"""",--key,"""",-cert,"""",-secret,_PBM_SECRET,-popo,-1
|
||||
1,reqin ip and rspin - no newkey but -popo -1, -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir2.der,,-rspin,_RESULT_DIR/ip2.der,,-newkey,"""",-key,"""",-cert,"""",-secret,_PBM_SECRET,-popo,-1, -server,"""",-disable_confirm
|
||||
1,reqin ir and rspout - using no newkey and -popo 0 as workaround, -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir2.der,,-rspout,_RESULT_DIR/ip2.der,-newkey,"""", -popo,0
|
||||
1,reqin ip and rspin - using no newkey and -popo 0 as workaround, -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir2.der,,-rspin,_RESULT_DIR/ip2.der,,-newkey,"""",-server,"""",-disable_confirm, -popo,0
|
||||
1,reqout_only ir - no server with -popo -1 (same as -centralkeygen), -section,, -cmd,ir,,-reqout_only,_RESULT_DIR/ir3.der,,BLANK,,BLANK, -server,"""", -popo,-1, -newkeyout,_RESULT_DIR/dummyout.pem
|
||||
1,reqin ir and rspout - using no newkey and -popo -1 (same as -centralkeygen), -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir3.der,,-rspout,_RESULT_DIR/ip3.der,-newkey,"""", -popo,-1, -newkeyout,_RESULT_DIR/newkeyout.pem
|
||||
1,reqin ip and rspin - using no newkey and -popo -1 (same as -centralkeygen), -section,, -cmd,ir,,-reqin,_RESULT_DIR/ir3.der,,-rspin,_RESULT_DIR/ip3.der,,-newkey,"""",-server,"""",-disable_confirm, -popo,-1, -newkeyout,_RESULT_DIR/newkeyout.pem
|
||||
,,,,,,,,,,,,,,,,,,,
|
||||
1,central key generation, -section,, -cmd,cr,, -centralkeygen, -newkeyout,_RESULT_DIR/newkeyout1.pem
|
||||
0,central key generation missing newkeyout, -section,, -cmd,cr,, -centralkeygen,,BLANK,,BLANK,,BLANK,,BLANK,
|
||||
0,using popo 1 with -centralkeygen, -section,, -cmd,cr,, -centralkeygen, -popo,1, -newkeyout,_RESULT_DIR/newkeyout.pem
|
||||
1, using popo -1 redundantly with -centralkeygen, -section,, -cmd,cr,, -centralkeygen, -popo,-1, -newkeyout,_RESULT_DIR/newkeyout2.pem
|
||||
1, using popo -1 alternatively to -centralkeygen, -section,, -cmd,cr,, -popo,-1, -newkeyout,_RESULT_DIR/newkeyout3.pem, -newkeypass,pass:12345, -certout,_RESULT_DIR/test.cert3.pem
|
||||
1, using centrally generated key (and cert) , -section,, -cmd,cr,,-cert,_RESULT_DIR/test.cert3.pem, -key,_RESULT_DIR/newkeyout3.pem, -keypass,pass:12345
|
||||
0, using centrally generated key with wrong password, -section,, -cmd,cr,,-cert,_RESULT_DIR/test.cert3.pem, -key,_RESULT_DIR/newkeyout3.pem, -keypass,pass:wrong
|
||||
0, using popo -1 (instead of -centralkeygen) without -newkeyout, -section,, -cmd,cr,, -popo,-1,,BLANK,,BLANK,,BLANK,,BLANK
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -5734,6 +5734,17 @@ EVP_CIPHER_CTX_get_algor 5861 3_4_0 EXIST::FUNCTION:
|
|||
EVP_PKEY_CTX_set_algor_params 5862 3_4_0 EXIST::FUNCTION:
|
||||
EVP_PKEY_CTX_get_algor_params 5863 3_4_0 EXIST::FUNCTION:
|
||||
EVP_PKEY_CTX_get_algor 5864 3_4_0 EXIST::FUNCTION:
|
||||
d2i_OSSL_CRMF_ENCRYPTEDKEY ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
i2d_OSSL_CRMF_ENCRYPTEDKEY ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_ENCRYPTEDKEY_free ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_ENCRYPTEDKEY_new ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_ENCRYPTEDKEY_it ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_encCert ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_ENCRYPTEDVALUE_decrypt ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_ENCRYPTEDKEY_get1_pkey ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
OSSL_CRMF_MSG_centralkeygen_requested ? 3_5_0 EXIST::FUNCTION:CRMF
|
||||
CMS_EnvelopedData_dup ? 3_5_0 EXIST::FUNCTION:CMS
|
||||
OSSL_CRMF_ENCRYPTEDKEY_init_envdata ? 3_5_0 EXIST::FUNCTION:CMS,CRMF
|
||||
EVP_get1_default_properties ? 3_5_0 EXIST::FUNCTION:
|
||||
X509_PURPOSE_get_unused_id ? 3_5_0 EXIST::FUNCTION:
|
||||
d2i_OSSL_AUTHORITY_ATTRIBUTE_ID_SYNTAX ? 3_5_0 EXIST::FUNCTION:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue