CMP: add support for requesting cert template using genm/genp

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/24409)
This commit is contained in:
Rajeev Ranjan 2024-05-15 13:11:09 +02:00 committed by Dr. David von Oheimb
parent e2a4d68a03
commit 6a3579e190
24 changed files with 834 additions and 45 deletions

View File

@ -97,6 +97,8 @@ static char *opt_oldwithnew = NULL;
static char *opt_crlcert = NULL;
static char *opt_oldcrl = NULL;
static char *opt_crlout = NULL;
static char *opt_template = NULL;
static char *opt_keyspec = NULL;
/* client authentication */
static char *opt_ref = NULL;
@ -225,6 +227,7 @@ typedef enum OPTION_choice {
OPT_CONFIG, OPT_SECTION, OPT_VERBOSITY,
OPT_CMD, OPT_INFOTYPE, OPT_PROFILE, OPT_GENINFO,
OPT_TEMPLATE, OPT_KEYSPEC,
OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT,
OPT_DAYS, OPT_REQEXTS,
@ -313,6 +316,10 @@ const OPTIONS cmp_options[] = {
"Comma-separated list of OID and value to place in generalInfo PKIHeader"},
{OPT_MORE_STR, 0, 0,
"of form <OID>:int:<n> or <OID>:str:<s>, e.g. \'1.2.3.4:int:56789, id-kp:str:name'"},
{ "template", OPT_TEMPLATE, 's',
"File to save certTemplate received in genp of type certReqTemplate"},
{ "keyspec", OPT_KEYSPEC, 's',
"Optional file to save Key specification received in genp of type certReqTemplate"},
OPT_SECTION("Certificate enrollment"),
{"newkey", OPT_NEWKEY, 's',
@ -620,6 +627,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
{&opt_config}, {&opt_section}, {(char **)&opt_verbosity},
{&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},
@ -2176,6 +2184,17 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
if (opt_oldwithnew != NULL)
CMP_warn1("-oldwithnew %s", msg);
}
if (opt_cmd != CMP_GENM || opt_infotype != NID_id_it_certReqTemplate) {
const char *msg = "option is ignored unless -cmd 'genm' and -infotype 'certReqTemplate' is given";
if (opt_template != NULL)
CMP_warn1("-template %s", msg);
if (opt_keyspec != NULL)
CMP_warn1("-keyspec %s", msg);
} else {
if (opt_template == NULL)
CMP_err("missing -template option for genm with infotype certReqTemplate");
}
if (!setup_verification_ctx(ctx))
goto err;
@ -2420,6 +2439,57 @@ static int save_crl_or_delete(X509_CRL *crl, const char *file, const char *desc)
return (crl == NULL) ? delete_file(file, desc) : save_crl(crl, file, desc);
}
static int save_template(const char *file, const OSSL_CRMF_CERTTEMPLATE *tmpl)
{
BIO *bio = BIO_new_file(file, "wb");
if (bio == NULL) {
CMP_err1("error saving certTemplate from genp: cannot open file %s",
file);
return 0;
}
if (!ASN1_i2d_bio_of(OSSL_CRMF_CERTTEMPLATE, i2d_OSSL_CRMF_CERTTEMPLATE,
bio, tmpl)) {
CMP_err1("error saving certTemplate from genp: cannot write file %s",
file);
return 0;
} else {
CMP_info1("stored certTemplate from genp to file '%s'", file);
}
BIO_free(bio);
return 1;
}
static int save_keyspec(const char *file, const OSSL_CMP_ATAVS *keyspec)
{
BIO *bio = BIO_new_file(file, "wb");
if (bio == NULL) {
CMP_err1("error saving keySpec from genp: cannot open file %s", file);
return 0;
}
if (!ASN1_i2d_bio_of(OSSL_CMP_ATAVS, i2d_OSSL_CMP_ATAVS, bio, keyspec)) {
CMP_err1("error saving keySpec from genp: cannot write file %s", file);
return 0;
} else {
CMP_info1("stored keySpec from genp to file '%s'", file);
}
BIO_free(bio);
return 1;
}
static const char *nid_name(int nid)
{
const char *name = OBJ_nid2ln(nid);
if (name == NULL)
name = OBJ_nid2sn(nid);
if (name == NULL)
name = "<unknown OID>";
return name;
}
static int print_itavs(const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i, ret = 1;
@ -2845,6 +2915,12 @@ static int get_opts(int argc, char **argv)
case OPT_GENINFO:
opt_geninfo = opt_str();
break;
case OPT_TEMPLATE:
opt_template = opt_str();
break;
case OPT_KEYSPEC:
opt_keyspec = opt_str();
break;
case OPT_NEWKEY:
opt_newkey = opt_str();
@ -3154,6 +3230,71 @@ static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx)
}
#endif
static void print_keyspec(OSSL_CMP_ATAVS *keySpec)
{
const char *desc = "specifications contained in keySpec from genp";
BIO *mem;
int i;
const char *p;
long len;
if (keySpec == NULL) {
CMP_info1("No %s", desc);
return;
}
mem = BIO_new(BIO_s_mem());
if (mem == NULL) {
CMP_err1("Out of memory - cannot dump key %s", desc);
return;
}
BIO_printf(mem, "Key %s:\n", desc);
for (i = 0; i < sk_OSSL_CMP_ATAV_num(keySpec); i++) {
OSSL_CMP_ATAV *atav = sk_OSSL_CMP_ATAV_value(keySpec, i);
ASN1_OBJECT *type = OSSL_CMP_ATAV_get0_type(atav /* may be NULL */);
int nid = OBJ_obj2nid(type);
switch (nid) {
case NID_id_regCtrl_algId:
{
X509_ALGOR *alg = OSSL_CMP_ATAV_get0_algId(atav);
const ASN1_OBJECT *oid;
int paramtype;
const void *param;
X509_ALGOR_get0(&oid, &paramtype, &param, alg);
BIO_printf(mem, "Key algorithm: ");
i2a_ASN1_OBJECT(mem, oid);
if (paramtype == V_ASN1_UNDEF || alg->parameter == NULL) {
BIO_printf(mem, "\n");
} else {
BIO_printf(mem, " - ");
ASN1_item_print(mem, (ASN1_VALUE *)alg,
0, ASN1_ITEM_rptr(X509_ALGOR), NULL);
}
}
break;
case NID_id_regCtrl_rsaKeyLen:
BIO_printf(mem, "Key algorithm: RSA %d\n",
OSSL_CMP_ATAV_get_rsaKeyLen(atav));
break;
default:
BIO_printf(mem, "Invalid key spec: %s\n", nid_name(nid));
break;
}
}
BIO_printf(mem, "End of key %s", desc);
len = BIO_get_mem_data(mem, &p);
if (len > INT_MAX)
CMP_err1("Info too large - cannot dump key %s", desc);
else
CMP_info2("%.*s", (int)len, p);
BIO_free(mem);
return;
}
static void print_status(void)
{
/* print PKIStatusInfo */
@ -3300,6 +3441,42 @@ static int do_genm(OSSL_CMP_CTX *ctx)
X509_CRL_free(crl);
return res;
} else if (opt_infotype == NID_id_it_certReqTemplate) {
OSSL_CRMF_CERTTEMPLATE *certTemplate;
OSSL_CMP_ATAVS *keySpec;
int res = 0;
if (!OSSL_CMP_get1_certReqTemplate(ctx, &certTemplate, &keySpec))
return 0;
if (certTemplate == NULL) {
CMP_warn("no certificate request template available");
if (!delete_file(opt_template, "certTemplate from genp"))
return 0;
if (opt_keyspec != NULL
&& !delete_file(opt_keyspec, "keySpec from genp"))
return 0;
return 1;
}
if (!save_template(opt_template, certTemplate))
goto tmpl_end;
print_keyspec(keySpec);
if (opt_keyspec != NULL) {
if (keySpec == NULL) {
CMP_warn("no key specifications available");
if (!delete_file(opt_keyspec, "keySpec from genp"))
goto tmpl_end;
} else if (!save_keyspec(opt_keyspec, keySpec)) {
goto tmpl_end;
}
}
res = 1;
tmpl_end:
OSSL_CRMF_CERTTEMPLATE_free(certTemplate);
sk_OSSL_CMP_ATAV_pop_free(keySpec, OSSL_CMP_ATAV_free);
return res;
} else {
OSSL_CMP_ITAV *req;
STACK_OF(OSSL_CMP_ITAV) *itavs;

View File

@ -451,7 +451,7 @@ static int check_client_crl(const STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList,
static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
const OSSL_CMP_ITAV *req)
{
OSSL_CMP_ITAV *rsp;
OSSL_CMP_ITAV *rsp = NULL;
switch (req_nid) {
case NID_id_it_caCerts:
@ -490,6 +490,48 @@ static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
rsp = OSSL_CMP_ITAV_new_crls(res == 0 ? NULL : ctx->crlOut);
}
break;
case NID_id_it_certReqTemplate:
{
OSSL_CRMF_CERTTEMPLATE *reqtemp;
OSSL_CMP_ATAVS *keyspec = NULL;
X509_ALGOR *keyalg = NULL;
OSSL_CMP_ATAV *rsakeylen, *eckeyalg;
int ok = 0;
if ((reqtemp = OSSL_CRMF_CERTTEMPLATE_new()) == NULL)
return NULL;
if (!OSSL_CRMF_CERTTEMPLATE_fill(reqtemp, NULL, NULL,
X509_get_issuer_name(ctx->refCert),
NULL))
goto crt_err;
if ((keyalg = X509_ALGOR_new()) == NULL)
goto crt_err;
(void)X509_ALGOR_set0(keyalg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
V_ASN1_UNDEF, NULL); /* cannot fail */
eckeyalg = OSSL_CMP_ATAV_new_algId(keyalg);
rsakeylen = OSSL_CMP_ATAV_new_rsaKeyLen(4096);
ok = OSSL_CMP_ATAV_push1(&keyspec, eckeyalg)
&& OSSL_CMP_ATAV_push1(&keyspec, rsakeylen);
OSSL_CMP_ATAV_free(eckeyalg);
OSSL_CMP_ATAV_free(rsakeylen);
X509_ALGOR_free(keyalg);
if (!ok)
goto crt_err;
rsp = OSSL_CMP_ITAV_new0_certReqTemplate(reqtemp, keyspec);
return rsp;
crt_err:
OSSL_CRMF_CERTTEMPLATE_free(reqtemp);
OSSL_CMP_ATAVS_free(keyspec);
return NULL;
}
break;
default:
rsp = OSSL_CMP_ITAV_dup(req);
}

View File

@ -12,6 +12,7 @@
#include <openssl/asn1t.h>
#include "cmp_local.h"
#include "internal/crmf.h"
/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/cmp.h>
@ -117,6 +118,9 @@ ASN1_ADB(OSSL_CMP_ITAV) = {
ADB_ENTRY(NID_id_it_rootCaKeyUpdate,
ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaKeyUpdate,
OSSL_CMP_ROOTCAKEYUPDATE)),
ADB_ENTRY(NID_id_it_certReqTemplate,
ASN1_OPT(OSSL_CMP_ITAV, infoValue.certReqTemplate,
OSSL_CMP_CERTREQTEMPLATE)),
ADB_ENTRY(NID_id_it_certProfile,
ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile,
ASN1_UTF8STRING)),
@ -143,6 +147,19 @@ ASN1_SEQUENCE(OSSL_CMP_ROOTCAKEYUPDATE) = {
} ASN1_SEQUENCE_END(OSSL_CMP_ROOTCAKEYUPDATE)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE)
ASN1_ITEM_TEMPLATE(OSSL_CMP_ATAVS) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
OSSL_CMP_ATAVS, OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
ASN1_ITEM_TEMPLATE_END(OSSL_CMP_ATAVS)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ATAVS)
ASN1_SEQUENCE(OSSL_CMP_CERTREQTEMPLATE) = {
ASN1_SIMPLE(OSSL_CMP_CERTREQTEMPLATE, certTemplate, OSSL_CRMF_CERTTEMPLATE),
ASN1_SEQUENCE_OF_OPT(OSSL_CMP_CERTREQTEMPLATE, keySpec,
OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
} ASN1_SEQUENCE_END(OSSL_CMP_CERTREQTEMPLATE)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTREQTEMPLATE)
ASN1_CHOICE(OSSL_CMP_CRLSOURCE) = {
ASN1_EXP(OSSL_CMP_CRLSOURCE, value.dpn, DIST_POINT_NAME, 0),
ASN1_EXP(OSSL_CMP_CRLSOURCE, value.issuer, GENERAL_NAMES, 1),
@ -358,6 +375,220 @@ int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav,
return 1;
}
OSSL_CMP_ITAV
*OSSL_CMP_ITAV_new0_certReqTemplate(OSSL_CRMF_CERTTEMPLATE *certTemplate,
OSSL_CMP_ATAVS *keySpec)
{
OSSL_CMP_ITAV *itav;
OSSL_CMP_CERTREQTEMPLATE *tmpl;
if (certTemplate == NULL && keySpec != NULL) {
ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
if ((itav = OSSL_CMP_ITAV_new()) == NULL)
return NULL;
itav->infoType = OBJ_nid2obj(NID_id_it_certReqTemplate);
if (certTemplate == NULL)
return itav;
if ((tmpl = OSSL_CMP_CERTREQTEMPLATE_new()) == NULL) {
OSSL_CMP_ITAV_free(itav);
return NULL;
}
itav->infoValue.certReqTemplate = tmpl;
tmpl->certTemplate = certTemplate;
tmpl->keySpec = keySpec;
return itav;
}
int OSSL_CMP_ITAV_get1_certReqTemplate(const OSSL_CMP_ITAV *itav,
OSSL_CRMF_CERTTEMPLATE **certTemplate,
OSSL_CMP_ATAVS **keySpec)
{
OSSL_CMP_CERTREQTEMPLATE *tpl;
if (itav == NULL || certTemplate == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
*certTemplate = NULL;
if (keySpec != NULL)
*keySpec = NULL;
if (OBJ_obj2nid(itav->infoType) != NID_id_it_certReqTemplate) {
ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
tpl = itav->infoValue.certReqTemplate;
if (tpl == NULL) /* no requirements available */
return 1;
if ((*certTemplate = OSSL_CRMF_CERTTEMPLATE_dup(tpl->certTemplate)) == NULL)
return 0;
if (keySpec != NULL && tpl->keySpec != NULL) {
int i, n = sk_OSSL_CMP_ATAV_num(tpl->keySpec);
*keySpec = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_reserve(NULL, n);
if (*keySpec == NULL)
goto err;
for (i = 0; i < n; i++) {
OSSL_CMP_ATAV *atav = sk_OSSL_CMP_ATAV_value(tpl->keySpec, i);
ASN1_OBJECT *type = OSSL_CMP_ATAV_get0_type(atav /* may be NULL */);
int nid;
const char *name;
if (type == NULL) {
ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_KEYSPEC,
"keySpec with index %d in certReqTemplate does not exist",
i);
goto err;
}
nid = OBJ_obj2nid(type);
if (nid != NID_id_regCtrl_algId
&& nid != NID_id_regCtrl_rsaKeyLen) {
name = OBJ_nid2ln(nid);
if (name == NULL)
name = OBJ_nid2sn(nid);
if (name == NULL)
name = "<undef>";
ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_KEYSPEC,
"keySpec with index %d in certReqTemplate has invalid type %s",
i, name);
goto err;
}
OSSL_CMP_ATAV_push1(keySpec, atav);
}
}
return 1;
err:
OSSL_CRMF_CERTTEMPLATE_free(*certTemplate);
*certTemplate = NULL;
sk_OSSL_CMP_ATAV_pop_free(*keySpec, OSSL_CMP_ATAV_free);
if (keySpec != NULL)
*keySpec = NULL;
return 0;
}
OSSL_CMP_ATAV *OSSL_CMP_ATAV_create(ASN1_OBJECT *type, ASN1_TYPE *value)
{
OSSL_CMP_ATAV *atav;
if ((atav = OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new()) == NULL)
return NULL;
OSSL_CMP_ATAV_set0(atav, type, value);
return atav;
}
void OSSL_CMP_ATAV_set0(OSSL_CMP_ATAV *atav, ASN1_OBJECT *type,
ASN1_TYPE *value)
{
atav->type = type;
atav->value.other = value;
}
ASN1_OBJECT *OSSL_CMP_ATAV_get0_type(const OSSL_CMP_ATAV *atav)
{
if (atav == NULL)
return NULL;
return atav->type;
}
OSSL_CMP_ATAV *OSSL_CMP_ATAV_new_algId(const X509_ALGOR *alg)
{
X509_ALGOR *dup;
OSSL_CMP_ATAV *res;
if (alg == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
if ((dup = X509_ALGOR_dup(alg)) == NULL)
return NULL;
res = OSSL_CMP_ATAV_create(OBJ_nid2obj(NID_id_regCtrl_algId),
(ASN1_TYPE *)dup);
if (res == NULL)
X509_ALGOR_free(dup);
return res;
}
X509_ALGOR *OSSL_CMP_ATAV_get0_algId(const OSSL_CMP_ATAV *atav)
{
if (atav == NULL || OBJ_obj2nid(atav->type) != NID_id_regCtrl_algId)
return NULL;
return atav->value.algId;
}
OSSL_CMP_ATAV *OSSL_CMP_ATAV_new_rsaKeyLen(int len)
{
ASN1_INTEGER *aint;
OSSL_CMP_ATAV *res = NULL;
if (len <= 0) {
ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
if ((aint = ASN1_INTEGER_new()) == NULL)
return NULL;
if (!ASN1_INTEGER_set(aint, len)
|| (res = OSSL_CMP_ATAV_create(OBJ_nid2obj(NID_id_regCtrl_rsaKeyLen),
(ASN1_TYPE *)aint)) == NULL)
ASN1_INTEGER_free(aint);
return res;
}
int OSSL_CMP_ATAV_get_rsaKeyLen(const OSSL_CMP_ATAV *atav)
{
int64_t val;
if (atav == NULL || OBJ_obj2nid(atav->type) != NID_id_regCtrl_rsaKeyLen
|| !ASN1_INTEGER_get_int64(&val, atav->value.rsaKeyLen))
return -1;
if (val <= 0 || val > INT_MAX)
return -2;
return (int)val;
}
ASN1_TYPE *OSSL_CMP_ATAV_get0_value(const OSSL_CMP_ATAV *atav)
{
if (atav == NULL)
return NULL;
return atav->value.other;
}
int OSSL_CMP_ATAV_push1(OSSL_CMP_ATAVS **sk_p, const OSSL_CMP_ATAV *atav)
{
int created = 0;
OSSL_CMP_ATAV *dup;
if (sk_p == NULL || atav == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
goto err;
}
if (*sk_p == NULL) {
if ((*sk_p = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null()) == NULL)
goto err;
created = 1;
}
if ((dup = OSSL_CRMF_ATTRIBUTETYPEANDVALUE_dup((OSSL_CRMF_ATTRIBUTETYPEANDVALUE *)atav)) == NULL)
goto err;
if (sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(*sk_p, dup))
return 1;
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(dup);
err:
if (created) {
sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(*sk_p);
*sk_p = NULL;
}
return 0;
}
OSSL_CMP_ITAV
*OSSL_CMP_ITAV_new0_crlStatusList(STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList)
{

View File

@ -85,12 +85,15 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
"failure obtaining random"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE),
"fail info out of range"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CERTREQTEMPLATE),
"generate certreqtemplate"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CRLSTATUS),
"error creating crlstatus"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GETTING_GENP), "getting genp"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GET_ITAV), "get itav"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_GENP), "invalid genp"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_KEYSPEC), "invalid keyspec"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE),
"invalid rootcakeyupdate"},

View File

@ -406,3 +406,36 @@ int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert,
OSSL_CMP_ITAV_free(itav);
return res;
}
int OSSL_CMP_get1_certReqTemplate(OSSL_CMP_CTX *ctx,
OSSL_CRMF_CERTTEMPLATE **certTemplate,
OSSL_CMP_ATAVS **keySpec)
{
OSSL_CMP_ITAV *req, *itav = NULL;
int res = 0;
if (keySpec != NULL)
*keySpec = NULL;
if (certTemplate == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
*certTemplate = NULL;
if ((req = OSSL_CMP_ITAV_new0_certReqTemplate(NULL, NULL)) == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_GENERATE_CERTREQTEMPLATE);
return 0;
}
if ((itav = get_genm_itav(ctx, req, NID_id_it_certReqTemplate,
"certReqTemplate")) == NULL)
return 0;
if (!OSSL_CMP_ITAV_get1_certReqTemplate(itav, certTemplate, keySpec))
goto end;
res = 1;
end:
OSSL_CMP_ITAV_free(itav);
return res;
}

View File

@ -294,6 +294,8 @@ struct ossl_cmp_itav_st {
X509 *rootCaCert;
/* NID_id_it_rootCaKeyUpdate - Root CA Certificate Update */
OSSL_CMP_ROOTCAKEYUPDATE *rootCaKeyUpdate;
/* NID_id_it_certReqTemplate - Certificate Request Template */
OSSL_CMP_CERTREQTEMPLATE *certReqTemplate;
/* NID_id_it_crlStatusList - CRL Update Retrieval */
STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList;
/* NID_id_it_crls - Certificate Status Lists */
@ -800,6 +802,17 @@ struct ossl_cmp_rootcakeyupdate_st {
} /* OSSL_CMP_ROOTCAKEYUPDATE */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE)
/*-
* CertReqTemplateContent ::= SEQUENCE {
* certTemplate CertTemplate,
* keySpec Controls OPTIONAL
* }
*/
struct ossl_cmp_certreqtemplate_st {
OSSL_CRMF_CERTTEMPLATE *certTemplate;
OSSL_CMP_ATAVS *keySpec;
} /* OSSL_CMP_CERTREQTEMPLATE */;
/* from cmp_asn.c */
int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);

View File

@ -146,6 +146,12 @@ ASN1_ADB(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = {
ADB_ENTRY(NID_id_regCtrl_protocolEncrKey,
ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE,
value.protocolEncrKey, X509_PUBKEY)),
ADB_ENTRY(NID_id_regCtrl_algId,
ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE,
value.algId, X509_ALGOR)),
ADB_ENTRY(NID_id_regCtrl_rsaKeyLen,
ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE,
value.rsaKeyLen, ASN1_INTEGER)),
ADB_ENTRY(NID_id_regInfo_utf8Pairs,
ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE,
value.utf8Pairs, ASN1_UTF8STRING)),
@ -194,6 +200,7 @@ ASN1_SEQUENCE(OSSL_CRMF_CERTTEMPLATE) = {
X509_EXTENSION, 9),
} ASN1_SEQUENCE_END(OSSL_CRMF_CERTTEMPLATE)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE)
IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTTEMPLATE)
ASN1_SEQUENCE(OSSL_CRMF_CERTREQUEST) = {
ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certReqId, ASN1_INTEGER),

View File

@ -16,6 +16,7 @@
# include <openssl/crmf.h>
# include <openssl/err.h>
# include "internal/crmf.h" /* for ossl_crmf_attributetypeandvalue_st */
/* explicit #includes not strictly needed since implied by the above: */
# include <openssl/types.h>
@ -335,37 +336,6 @@ struct ossl_crmf_certrequest_st {
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST)
struct ossl_crmf_attributetypeandvalue_st {
ASN1_OBJECT *type;
union {
/* NID_id_regCtrl_regToken */
ASN1_UTF8STRING *regToken;
/* NID_id_regCtrl_authenticator */
ASN1_UTF8STRING *authenticator;
/* NID_id_regCtrl_pkiPublicationInfo */
OSSL_CRMF_PKIPUBLICATIONINFO *pkiPublicationInfo;
/* NID_id_regCtrl_oldCertID */
OSSL_CRMF_CERTID *oldCertID;
/* NID_id_regCtrl_protocolEncrKey */
X509_PUBKEY *protocolEncrKey;
/* NID_id_regInfo_utf8Pairs */
ASN1_UTF8STRING *utf8Pairs;
/* NID_id_regInfo_certReq */
OSSL_CRMF_CERTREQUEST *certReq;
ASN1_TYPE *other;
} value;
} /* OSSL_CRMF_ATTRIBUTETYPEANDVALUE */;
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
DEFINE_STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
/*-
* CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
* CertReqMsg ::= SEQUENCE {

View File

@ -234,11 +234,13 @@ CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain
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
CMP_R_GENERATE_CERTREQTEMPLATE:197:generate certreqtemplate
CMP_R_GENERATE_CRLSTATUS:198:error creating crlstatus
CMP_R_GETTING_GENP:192:getting genp
CMP_R_GET_ITAV:199:get itav
CMP_R_INVALID_ARGS:100:invalid args
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_CERTID:165:missing certid

View File

@ -1599,6 +1599,10 @@ DEPEND[html/man3/OSSL_CALLBACK.html]=man3/OSSL_CALLBACK.pod
GENERATE[html/man3/OSSL_CALLBACK.html]=man3/OSSL_CALLBACK.pod
DEPEND[man/man3/OSSL_CALLBACK.3]=man3/OSSL_CALLBACK.pod
GENERATE[man/man3/OSSL_CALLBACK.3]=man3/OSSL_CALLBACK.pod
DEPEND[html/man3/OSSL_CMP_ATAV_set0.html]=man3/OSSL_CMP_ATAV_set0.pod
GENERATE[html/man3/OSSL_CMP_ATAV_set0.html]=man3/OSSL_CMP_ATAV_set0.pod
DEPEND[man/man3/OSSL_CMP_ATAV_set0.3]=man3/OSSL_CMP_ATAV_set0.pod
GENERATE[man/man3/OSSL_CMP_ATAV_set0.3]=man3/OSSL_CMP_ATAV_set0.pod
DEPEND[html/man3/OSSL_CMP_CTX_new.html]=man3/OSSL_CMP_CTX_new.pod
GENERATE[html/man3/OSSL_CMP_CTX_new.html]=man3/OSSL_CMP_CTX_new.pod
DEPEND[man/man3/OSSL_CMP_CTX_new.3]=man3/OSSL_CMP_CTX_new.pod
@ -3379,6 +3383,7 @@ html/man3/OPENSSL_secure_malloc.html \
html/man3/OPENSSL_strcasecmp.html \
html/man3/OSSL_ALGORITHM.html \
html/man3/OSSL_CALLBACK.html \
html/man3/OSSL_CMP_ATAV_set0.html \
html/man3/OSSL_CMP_CTX_new.html \
html/man3/OSSL_CMP_HDR_get0_transactionID.html \
html/man3/OSSL_CMP_ITAV_new_caCerts.html \
@ -4036,6 +4041,7 @@ man/man3/OPENSSL_secure_malloc.3 \
man/man3/OPENSSL_strcasecmp.3 \
man/man3/OSSL_ALGORITHM.3 \
man/man3/OSSL_CALLBACK.3 \
man/man3/OSSL_CMP_ATAV_set0.3 \
man/man3/OSSL_CMP_CTX_new.3 \
man/man3/OSSL_CMP_HDR_get0_transactionID.3 \
man/man3/OSSL_CMP_ITAV_new_caCerts.3 \

View File

@ -19,6 +19,8 @@ Generic message options:
[B<-infotype> I<name>]
[B<-profile> I<name>]
[B<-geninfo> I<values>]
[B<-template> I<filename>]
[B<-keyspec> I<filename>]
Certificate enrollment options:
@ -252,8 +254,8 @@ ITAV B<infoType>s is printed to stdout.
Set InfoType name to use for requesting specific info in B<genm>,
e.g., C<signKeyPairTypes>.
So far, there is specific support for C<caCerts>, C<rootCaCert>
and C<crlStatusList>.
There is specific support for C<caCerts>, C<rootCaCert>,
C<certReqTemplate>, and C<crlStatusList> (CRL update retrieval).
=item B<-profile> I<name>
@ -268,6 +270,18 @@ Each InfoTypeAndValue gives an OID and an integer or string value
of the form I<OID>:int:I<number> or I<OID>:str:I<text>,
e.g., C<'1.2.3.4:int:56789, id-kp:str:name'>.
=item B<-template> I<filename>
The file to save any CRMF certTemplate in DER format
received in a genp message with id-it-certReqTemplate.
=item B<-keyspec> I<filename>
It is optional and used to specify the file to save any keySpec if
present in a genp message with id-it-keyGenParameters.
Note: any keySpec field contents received are logged as INFO.
=back
=head2 Certificate enrollment options

View File

@ -0,0 +1,118 @@
=pod
=head1 NAME
OSSL_CMP_ATAV,
OSSL_CMP_ATAV_create,
OSSL_CMP_ATAV_set0,
OSSL_CMP_ATAV_get0_type,
OSSL_CMP_ATAV_get0_value,
OSSL_CMP_ATAV_new_algId,
OSSL_CMP_ATAV_get0_algId,
OSSL_CMP_ATAV_new_rsaKeyLen,
OSSL_CMP_ATAV_get_rsaKeyLen,
OSSL_CMP_ATAVS,
OSSL_CMP_ATAV_push1,
OSSL_CMP_ATAV_free
- OSSL_CMP_ATAV utility functions
=head1 SYNOPSIS
#include <openssl/cmp.h>
typedef OSSL_CRMF_ATTRIBUTETYPEANDVALUE OSSL_CMP_ATAV;
OSSL_CMP_ATAV *OSSL_CMP_ATAV_create(ASN1_OBJECT *type, ASN1_TYPE *value);
void OSSL_CMP_ATAV_set0(OSSL_CMP_ATAV *atav, ASN1_OBJECT *type,
ASN1_TYPE *value);
ASN1_OBJECT *OSSL_CMP_ATAV_get0_type(const OSSL_CMP_ATAV *atav);
ASN1_TYPE *OSSL_CMP_ATAV_get0_value(const OSSL_CMP_ATAV *atav);
OSSL_CMP_ATAV *OSSL_CMP_ATAV_new_algId(const X509_ALGOR *alg);
X509_ALGOR *OSSL_CMP_ATAV_get0_algId(const OSSL_CMP_ATAV *atav);
OSSL_CMP_ATAV *OSSL_CMP_ATAV_new_rsaKeyLen(int len);
int OSSL_CMP_ATAV_get_rsaKeyLen(const OSSL_CMP_ATAV *atav);
typedef STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) OSSL_CMP_ATAVS;
int OSSL_CMP_ATAV_push1(OSSL_CMP_ATAVS **sk_p, const OSSL_CMP_ATAV *atav);
void OSSL_CMP_ATAV_free(OSSL_CMP_ATAV *atav);
=head1 DESCRIPTION
B<OSSL_CMP_ATAV> is a short hand of B<OSSL_CRMF_ATTRIBUTETYPEANDVALUE>,
defined in RFC 4211 Appendix B.
It is typically used in CertRequest structures,
but also in CertReqTemplateContent structures for key specifications.
OSSL_CMP_ATAV_create() creates a new B<OSSL_CMP_ATAV> structure and fills it in.
It combines OSSL_CMP_ATAV_new() and OSSL_CMP_ATAV_set0().
OSSL_CMP_ATAV_set0() sets the I<atav> with an infoType of I<type> and an
infoValue of I<value>.
The pointers I<type> and I<value> may be NULL, otherwise
they must B<not> be freed up after the call because their ownership
is transferred to I<atav>. The I<itav> pointer must not be NULL.
OSSL_CMP_ATAV_get0_type() returns a direct pointer to the infoType
in the I<atav> unless it is NULL.
OSSL_CMP_ATAV_get0_value() returns a direct pointer to the infoValue
in the I<atav> as generic B<ASN1_TYPE> pointer unless I<atav> is NULL.
OSSL_CMP_ATAV_new_algId() creates a new B<OSSL_CMP_ATAV> structure of type
B<algId> and fills it in with a copy of the given I<alg>.
OSSL_CMP_ATAV_get0_algId() returns
a direct pointer to the algId infoValue in the I<atav> of type B<X509_ALGOR>
or NULL if I<atav> is NULL or does not contain an algId.
OSSL_CMP_ATAV_new_rsaKeyLen() creates a new B<OSSL_CMP_ATAV> structure of type
B<rsaKeyLen> and fills it in with the given I<len>, which must be positive.
OSSL_CMP_ATAV_get_rsaKeyLen() returns
the RSA key length in rsaKeyLen infoValue in the I<atav>,
-1 if I<atav> is NULL or does not contain an rsaKeyLen or cannot be parsed,
or -2 if the value is less than 1 or is greater than INT_MAX.
OSSL_CMP_ATAV_push1() pushes a copy of I<atav> to the stack of B<OSSL_CMP_ATAV>
pointed to by I<*sk_p>. It creates a new stack if I<*sk_p> points to NULL.
OSSL_CMP_ATAV_free() deallocates I<atav>. It is defined as a macro.
=head1 NOTES
CMP is defined in RFC 4210. CRMF is defined in RFC 4211.
=head1 RETURN VALUES
OSSL_CMP_ATAV_create(),
OSSL_CMP_ATAV_new_algId(), and OSSL_CMP_ATAV_new_rsaKeyLen()
return a pointer to the ATAV structure on success, or NULL on error.
OSSL_CMP_ATAV_set0() and OSSL_CMP_ATAV_free() do not return a value.
OSSL_CMP_ATAV_get0_type(), OSSL_CMP_ATAV_get0_value(), and
OSSL_CMP_ATAV_get0_algId()
return the respective pointer or NULL if their input is NULL.
OSSL_CMP_ATAV_get_rsaKeyLen() return a key length in bits or < 0 on error.
OSSL_CMP_ATAV_push1() returns 1 on success, 0 on error.
=head1 SEE ALSO
L<OSSL_CMP_ITAV_new0_certReqTemplate(3)>, L<ASN1_TYPE_set(3)>
=head1 HISTORY
The B<OSSL_CMP_ATAV> type and related functions were added in OpenSSL 3.4.
=head1 COPYRIGHT
Copyright 2022 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

@ -14,7 +14,9 @@ OSSL_CMP_CRLSTATUS_get0,
OSSL_CMP_ITAV_new0_crlStatusList,
OSSL_CMP_ITAV_get0_crlStatusList,
OSSL_CMP_ITAV_new_crls,
OSSL_CMP_ITAV_get0_crls
OSSL_CMP_ITAV_get0_crls,
OSSL_CMP_ITAV_new0_certReqTemplate,
OSSL_CMP_ITAV_get1_certReqTemplate
- CMP utility functions for handling specific genm and genp messages
=head1 SYNOPSIS
@ -48,6 +50,12 @@ OSSL_CMP_ITAV_get0_crls
STACK_OF(OSSL_CMP_CRLSTATUS) **out);
OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crl);
int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *itav, STACK_OF(X509_CRL) **out);
OSSL_CMP_ITAV
*OSSL_CMP_ITAV_new0_certReqTemplate(OSSL_CRMF_CERTTEMPLATE *certTemplate,
OSSL_CMP_ATAVS *keySpec);
int OSSL_CMP_ITAV_get1_certReqTemplate(const OSSL_CMP_ITAV *itav,
OSSL_CRMF_CERTTEMPLATE **certTemplate,
OSSL_CMP_ATAVS **keySpec);
=head1 DESCRIPTION
@ -100,6 +108,27 @@ Data from I<cert>, if present, is preferred over data from I<crl>.
If no distribution point names are available,
candidate issuer names are taken from following sources, as far as present:
OSSL_CMP_ITAV_new0_certReqTemplate() creates an B<OSSL_CMP_ITAV> structure
of type B<certReqTemplate>.
If I<certTemplate> is NULL then also I<keySpec> must be NULL,
and the resulting ITAV can be used in a B<genm> message to obtain the
requirements a PKI has on the certificate template used to request certificates,
or in a B<genp> message stating that there are no such requirements.
Otherwise the resulting ITAV includes a CertReqTemplateValue structure
with I<certTemplate> of type B<OSSL_CRMF_CERTTEMPLATE> and an optional list
of key specifications I<keySpec>, each being of type B<OSSL_CMP_ATAV>, and
the resulting ATAV can be used in a B<genp> message to provide requirements.
OSSL_CMP_ITAV_get1_certReqTemplate()
requires that I<itav> has type B<certReqTemplate>.
If assigns NULL to I<*certTemplate> if no B<OSSL_CRMF_CERTTEMPLATE> structure
with a certificate template value is in I<itav>,
otherwise a copy of the certTemplate field value.
If I<keySpec> is not NULL, it is assigned NULL
if the structure is not present in I<itav> or the keySpec field is absent.
Otherwise, the function checks that all elements of keySpec field are of type
B<algId> or B<rsaKeyLen> and assigns to I<*keySpec> a copy of the keySpec field.
=over 4
=item the list of distribution points in the first cRLDistributionPoints
@ -150,13 +179,14 @@ CMP is defined in RFC 4210.
OSSL_CMP_ITAV_new_caCerts(), OSSL_CMP_ITAV_new_rootCaCert(),
OSSL_CMP_ITAV_new_rootCaKeyUpdate(), OSSL_CMP_CRLSTATUS_new1(),
OSSL_CMP_CRLSTATUS_create(), OSSL_CMP_ITAV_new0_crlStatusList()
and OSSL_CMP_ITAV_new_crls()
OSSL_CMP_CRLSTATUS_create(), OSSL_CMP_ITAV_new0_crlStatusList(),
OSSL_CMP_ITAV_new_crls() and OSSL_CMP_ITAV_new0_certReqTemplate()
return a pointer to the new ITAV structure on success, or NULL on error.
OSSL_CMP_ITAV_get0_caCerts(), OSSL_CMP_ITAV_get0_rootCaCert(),
OSSL_CMP_ITAV_get0_rootCaKeyUpdate(), OSSL_CMP_CRLSTATUS_get0(),
OSSL_CMP_ITAV_get0_crlStatusList() and OSSL_CMP_ITAV_get0_crls()
OSSL_CMP_ITAV_get0_crlStatusList(), OSSL_CMP_ITAV_get0_crls()
and OSSL_CMP_ITAV_get1_certReqTemplate()
return 1 on success, 0 on error.
=head1 SEE ALSO
@ -172,8 +202,9 @@ were added in OpenSSL 3.2.
OSSL_CMP_CRLSTATUS_new1(), OSSL_CMP_CRLSTATUS_create(),
OSSL_CMP_CRLSTATUS_get0(), OSSL_CMP_ITAV_new0_crlStatusList(),
OSSL_CMP_ITAV_get0_crlStatusList(), OSSL_CMP_ITAV_new_crls()
and OSSL_CMP_ITAV_get0_crls() were added in OpenSSL 3.4.
OSSL_CMP_ITAV_get0_crlStatusList(), OSSL_CMP_ITAV_new_crls(),
OSSL_CMP_ITAV_get0_crls(), OSSL_CMP_ITAV_new0_certReqTemplate()
and OSSL_CMP_ITAV_get1_certReqTemplate() were added in OpenSSL 3.4.
=head1 COPYRIGHT

View File

@ -16,7 +16,8 @@ OSSL_CMP_exec_RR_ses,
OSSL_CMP_exec_GENM_ses,
OSSL_CMP_get1_caCerts,
OSSL_CMP_get1_rootCaKeyUpdate,
OSSL_CMP_get1_crlUpdate
OSSL_CMP_get1_crlUpdate,
OSSL_CMP_get1_certReqTemplate
- functions implementing CMP client transactions
=head1 SYNOPSIS
@ -45,7 +46,9 @@ OSSL_CMP_get1_crlUpdate
int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert,
const X509_CRL *last_crl,
X509_CRL **crl);
int OSSL_CMP_get1_certReqTemplate(OSSL_CMP_CTX *ctx,
OSSL_CRMF_CERTTEMPLATE **certTemplate,
OSSL_CMP_ATAVS **keySpec);
=head1 DESCRIPTION
This is the OpenSSL API for doing CMP (Certificate Management Protocol)
@ -169,6 +172,15 @@ On success it assigns to I<*crl> the CRL received.
NULL means that no CRL was provided by the server.
The CRL obtained this way must be freed by the caller.
OSSL_CMP_get1_certReqTemplate() uses a genm request message with
infoType certReqTemplate to obtain a certificate request template from the
CMP server referenced by I<ctx>. On success it assigns to I<*certTemplate>
the certificate template received. NULL output means that no certificate
request template was provided by the server.
The optional I<keySpec> output parameter is assigned the key specification
if received, otherwise it set to NULL.
Both must be freed by the caller.
=head1 NOTES
CMP is defined in RFC 4210 (and CRMF in RFC 4211).
@ -205,7 +217,8 @@ and the output parameter I<checkAfter> has been used to
assign the received value unless I<checkAfter> is NULL.
OSSL_CMP_exec_RR_ses(), OSSL_CMP_get1_caCerts(),
OSSL_CMP_get1_rootCaKeyUpdate() and OSSL_CMP_get1_crlUpdate()
OSSL_CMP_get1_rootCaKeyUpdate(), OSSL_CMP_get1_crlUpdate()
and OSSL_CMP_get1_certReqTemplate()
return 1 on success, 0 on error.
OSSL_CMP_exec_GENM_ses() returns NULL on error,
@ -235,7 +248,8 @@ were added in OpenSSL 3.2.
Support for delayed delivery of all types of response messages
was added in OpenSSL 3.3.
OSSL_CMP_get1_crlUpdate() was added in OpenSSL 3.4.
OSSL_CMP_get1_crlUpdate() and OSSL_CMP_get1_certReqTemplate()
were added in OpenSSL 3.4.
=head1 COPYRIGHT

View File

@ -41,7 +41,6 @@ OSSL_CRMF_MSG_get_certReqId
int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm);
=head1 DESCRIPTION
OSSL_CRMF_MSG_get0_tmpl() retrieves the certificate template of I<crm>.

View File

@ -136,6 +136,9 @@ OCSP_SIGNATURE_free,
OCSP_SIGNATURE_new,
OCSP_SINGLERESP_free,
OCSP_SINGLERESP_new,
OSSL_CMP_ATAVS_new,
OSSL_CMP_ATAVS_free,
OSSL_CMP_ATAVS_it,
OSSL_CMP_CRLSTATUS_free,
OSSL_CMP_ITAV_dup,
OSSL_CMP_ITAV_free,
@ -157,6 +160,9 @@ OSSL_CRMF_CERTID_new,
OSSL_CRMF_CERTTEMPLATE_free,
OSSL_CRMF_CERTTEMPLATE_it,
OSSL_CRMF_CERTTEMPLATE_new,
OSSL_CRMF_CERTTEMPLATE_dup,
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_dup,
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free,
OSSL_CRMF_ENCRYPTEDVALUE_free,
OSSL_CRMF_ENCRYPTEDVALUE_it,
OSSL_CRMF_ENCRYPTEDVALUE_new,

View File

@ -89,6 +89,7 @@ d2i_OCSP_REVOKEDINFO,
d2i_OCSP_SERVICELOC,
d2i_OCSP_SIGNATURE,
d2i_OCSP_SINGLERESP,
d2i_OSSL_CMP_ATAVS,
d2i_OSSL_CMP_MSG,
d2i_OSSL_CMP_PKIHEADER,
d2i_OSSL_CMP_PKISI,
@ -270,6 +271,7 @@ i2d_OCSP_REVOKEDINFO,
i2d_OCSP_SERVICELOC,
i2d_OCSP_SIGNATURE,
i2d_OCSP_SINGLERESP,
i2d_OSSL_CMP_ATAVS,
i2d_OSSL_CMP_MSG,
i2d_OSSL_CMP_PKIHEADER,
i2d_OSSL_CMP_PKISI,

51
include/internal/crmf.h Normal file
View File

@ -0,0 +1,51 @@
/*
* 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_CRYPTO_CRMF_H
# define OSSL_CRYPTO_CRMF_H
# pragma once
# include <openssl/crmf.h>
struct ossl_crmf_attributetypeandvalue_st {
ASN1_OBJECT *type;
union {
/* NID_id_regCtrl_regToken */
ASN1_UTF8STRING *regToken;
/* NID_id_regCtrl_authenticator */
ASN1_UTF8STRING *authenticator;
/* NID_id_regCtrl_pkiPublicationInfo */
OSSL_CRMF_PKIPUBLICATIONINFO *pkiPublicationInfo;
/* NID_id_regCtrl_oldCertID */
OSSL_CRMF_CERTID *oldCertID;
/* NID_id_regCtrl_protocolEncrKey */
X509_PUBKEY *protocolEncrKey;
/* NID_id_regCtrl_algId */
X509_ALGOR *algId;
/* NID_id_regCtrl_rsaKeyLen */
ASN1_INTEGER *rsaKeyLen;
/* NID_id_regInfo_utf8Pairs */
ASN1_UTF8STRING *utf8Pairs;
/* NID_id_regInfo_certReq */
OSSL_CRMF_CERTREQUEST *certReq;
ASN1_TYPE *other;
} value;
} /* OSSL_CRMF_ATTRIBUTETYPEANDVALUE */;
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
#endif /* OSSL_CRYPTO_CRMF_H */

View File

@ -234,6 +234,16 @@ typedef struct ossl_cmp_crlstatus_st OSSL_CMP_CRLSTATUS;
generate_stack_macros("OSSL_CMP_CRLSTATUS");
-}
typedef OSSL_CRMF_ATTRIBUTETYPEANDVALUE OSSL_CMP_ATAV;
# define OSSL_CMP_ATAV_free OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free
typedef STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) OSSL_CMP_ATAVS;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ATAVS)
# define stack_st_OSSL_CMP_ATAV stack_st_OSSL_CRMF_ATTRIBUTETYPEANDVALUE
# define sk_OSSL_CMP_ATAV_num sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_num
# define sk_OSSL_CMP_ATAV_value sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_value
# define sk_OSSL_CMP_ATAV_push sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push
# define sk_OSSL_CMP_ATAV_pop_free sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_pop_free
typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT;
typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
@ -299,6 +309,23 @@ int OSSL_CMP_ITAV_get0_crlStatusList(const OSSL_CMP_ITAV *itav,
STACK_OF(OSSL_CMP_CRLSTATUS) **out);
OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crls);
int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *it, STACK_OF(X509_CRL) **out);
OSSL_CMP_ITAV
*OSSL_CMP_ITAV_new0_certReqTemplate(OSSL_CRMF_CERTTEMPLATE *certTemplate,
OSSL_CMP_ATAVS *keySpec);
int OSSL_CMP_ITAV_get1_certReqTemplate(const OSSL_CMP_ITAV *itav,
OSSL_CRMF_CERTTEMPLATE **certTemplate,
OSSL_CMP_ATAVS **keySpec);
OSSL_CMP_ATAV *OSSL_CMP_ATAV_create(ASN1_OBJECT *type, ASN1_TYPE *value);
void OSSL_CMP_ATAV_set0(OSSL_CMP_ATAV *itav, ASN1_OBJECT *type,
ASN1_TYPE *value);
ASN1_OBJECT *OSSL_CMP_ATAV_get0_type(const OSSL_CMP_ATAV *itav);
ASN1_TYPE *OSSL_CMP_ATAV_get0_value(const OSSL_CMP_ATAV *itav);
OSSL_CMP_ATAV *OSSL_CMP_ATAV_new_algId(const X509_ALGOR *alg);
X509_ALGOR *OSSL_CMP_ATAV_get0_algId(const OSSL_CMP_ATAV *atav);
OSSL_CMP_ATAV *OSSL_CMP_ATAV_new_rsaKeyLen(int len);
int OSSL_CMP_ATAV_get_rsaKeyLen(const OSSL_CMP_ATAV *atav);
int OSSL_CMP_ATAV_push1(OSSL_CMP_ATAVS **sk_p, const OSSL_CMP_ATAV *atav);
void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg);
@ -546,6 +573,9 @@ int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx,
int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert,
const X509_CRL *last_crl,
X509_CRL **crl);
int OSSL_CMP_get1_certReqTemplate(OSSL_CMP_CTX *ctx,
OSSL_CRMF_CERTTEMPLATE **certTemplate,
OSSL_CMP_ATAVS **keySpec);
# ifdef __cplusplus
}

View File

@ -60,11 +60,13 @@
# define CMP_R_FAILED_EXTRACTING_PUBKEY 141
# define CMP_R_FAILURE_OBTAINING_RANDOM 110
# define CMP_R_FAIL_INFO_OUT_OF_RANGE 129
# define CMP_R_GENERATE_CERTREQTEMPLATE 197
# define CMP_R_GENERATE_CRLSTATUS 198
# define CMP_R_GETTING_GENP 192
# define CMP_R_GET_ITAV 199
# define CMP_R_INVALID_ARGS 100
# define CMP_R_INVALID_GENP 193
# define CMP_R_INVALID_KEYSPEC 202
# define CMP_R_INVALID_OPTION 174
# define CMP_R_INVALID_ROOTCAKEYUPDATE 195
# define CMP_R_MISSING_CERTID 165

View File

@ -54,6 +54,12 @@ DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_MSG)
generate_stack_macros("OSSL_CRMF_MSG");
-}
typedef struct ossl_crmf_attributetypeandvalue_st OSSL_CRMF_ATTRIBUTETYPEANDVALUE;
void OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(OSSL_CRMF_ATTRIBUTETYPEANDVALUE *v);
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
{-
generate_stack_macros("OSSL_CRMF_ATTRIBUTETYPEANDVALUE");
-}
typedef struct ossl_crmf_pbmparameter_st OSSL_CRMF_PBMPARAMETER;
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER)
typedef struct ossl_crmf_poposigningkey_st OSSL_CRMF_POPOSIGNINGKEY;
@ -71,6 +77,7 @@ typedef struct ossl_crmf_singlepubinfo_st OSSL_CRMF_SINGLEPUBINFO;
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_SINGLEPUBINFO)
typedef struct ossl_crmf_certtemplate_st OSSL_CRMF_CERTTEMPLATE;
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTTEMPLATE)
typedef STACK_OF(OSSL_CRMF_MSG) OSSL_CRMF_MSGS;
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSGS)

View File

@ -96,6 +96,14 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty
0,genm crlStatusList missing -crlcert & -oldcrl, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,,,,,,,, -crlout, _RESULT_DIR/test.crlout.pem
0,genm crlStatusList with wrong cert and correct crl, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, server.crt, -oldcrl, oldcrl.pem,,, -crlout, _RESULT_DIR/test.crlout.pem
,,,,,,,,,,,,,,,,,,,,,,
1,genm certReqTemplate, -section,, -cmd,genm,, -template,_RESULT_DIR/test.template.der, -keyspec,_RESULT_DIR/test.keyspec.der, -infotype,certReqTemplate,,BLANK,,BLANK,,BLANK,,, -expect_sender, """"
0,genm certReqTemplate missing template option, -section,, -cmd,genm,, -template,"""", -keyspec,_RESULT_DIR/test.keyspec.der, -infotype,certReqTemplate,,BLANK,,BLANK,
1,genm certReqTemplate without optional keyspec option, -section,, -cmd,genm,, -template,_RESULT_DIR/test.template.der, -keyspec,"""",, -infotype,certReqTemplate,,BLANK,,BLANK,
0,genm certReqTemplate missing template arg , -section,, -cmd,genm,, -template,BLANK, -keyspec,_RESULT_DIR/test.keyspec.der, -infotype,certReqTemplate,,BLANK,,BLANK,
0,genm certReqTemplate template extra arg , -section,, -cmd,genm,, -template,_RESULT_DIR/test.template.der,_RESULT_DIR/test.template.der, -infotype,certReqTemplate,,BLANK,,BLANK,
0,genm certReqTemplate template arg non-ex dir, -section,, -cmd,genm,, -template,idontexist/idontexist,, -infotype,certReqTemplate,,BLANK,,BLANK,
0,genm certReqTemplate keyspec arg non-ex dir, -section,, -cmd,genm,, -template,_RESULT_DIR/test.template.der, -keyspec,idontexist/idontexist,, -infotype,certReqTemplate,,BLANK,,BLANK,
,,,,,,,,,,,,,,,,,,,,,,
1,profile, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile1,BLANK,,BLANK,
0,profile wrong value, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile2,BLANK,,BLANK,
0,profile missing argument, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,,,,,

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -5559,6 +5559,26 @@ OSSL_CMP_ITAV_get0_crls ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ITAV_new0_crlStatusList ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ITAV_new_crls ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_get1_crlUpdate ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ITAV_new0_certReqTemplate ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ITAV_get1_certReqTemplate ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_create ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_set0 ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_get0_type ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_get0_value ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_new_algId ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_get0_algId ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_new_rsaKeyLen ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_get_rsaKeyLen ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAV_push1 ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_get1_certReqTemplate ? 3_4_0 EXIST::FUNCTION:CMP
d2i_OSSL_CMP_ATAVS ? 3_4_0 EXIST::FUNCTION:CMP
i2d_OSSL_CMP_ATAVS ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAVS_free ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAVS_new ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CMP_ATAVS_it ? 3_4_0 EXIST::FUNCTION:CMP
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free ? 3_4_0 EXIST::FUNCTION:CRMF
OSSL_CRMF_ATTRIBUTETYPEANDVALUE_dup ? 3_4_0 EXIST::FUNCTION:CRMF
OSSL_CRMF_CERTTEMPLATE_dup ? 3_4_0 EXIST::FUNCTION:CRMF
CRYPTO_atomic_store ? 3_4_0 EXIST::FUNCTION:
CRYPTO_aligned_alloc ? 3_4_0 EXIST::FUNCTION:
d2i_X509_ACERT ? 3_4_0 EXIST::FUNCTION:

View File

@ -461,6 +461,9 @@ OSSL_CMP_LOG_WARNING define
OSSL_CMP_MSTR_HELPER define
OSSL_CMP_MSTR define
OSSL_CMP_P10CR define
OSSL_CMP_ATAV define
OSSL_CMP_ATAV_free define
OSSL_CMP_ATAVS define
OSSL_CMP_certConf_cb_t datatype
OSSL_CMP_log_cb_t datatype
OSSL_CMP_severity datatype