1 /* 2 * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright Nokia 2007-2019 4 * Copyright Siemens AG 2015-2019 5 * 6 * Licensed under the Apache License 2.0 (the "License"). You may not use 7 * this file except in compliance with the License. You can obtain a copy 8 * in the file LICENSE in the source distribution or at 9 * https://www.openssl.org/source/license.html 10 */ 11 12 /* CMP functions for PKIMessage construction */ 13 14 #include "cmp_local.h" 15 16 /* explicit #includes not strictly needed since implied by the above: */ 17 #include <openssl/asn1t.h> 18 #include <openssl/cmp.h> 19 #include <openssl/crmf.h> 20 #include <openssl/err.h> 21 #include <openssl/x509.h> 22 23 OSSL_CMP_MSG *OSSL_CMP_MSG_new(OSSL_LIB_CTX *libctx, const char *propq) 24 { 25 OSSL_CMP_MSG *msg = NULL; 26 27 msg = (OSSL_CMP_MSG *)ASN1_item_new_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), 28 libctx, propq); 29 if (!ossl_cmp_msg_set0_libctx(msg, libctx, propq)) { 30 OSSL_CMP_MSG_free(msg); 31 msg = NULL; 32 } 33 return msg; 34 } 35 36 void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg) 37 { 38 ASN1_item_free((ASN1_VALUE *)msg, ASN1_ITEM_rptr(OSSL_CMP_MSG)); 39 } 40 41 /* 42 * This should only be used if the X509 object was embedded inside another 43 * asn1 object and it needs a libctx to operate. 44 * Use OSSL_CMP_MSG_new() instead if possible. 45 */ 46 int ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG *msg, OSSL_LIB_CTX *libctx, 47 const char *propq) 48 { 49 if (msg != NULL) { 50 msg->libctx = libctx; 51 OPENSSL_free(msg->propq); 52 msg->propq = NULL; 53 if (propq != NULL) { 54 msg->propq = OPENSSL_strdup(propq); 55 if (msg->propq == NULL) 56 return 0; 57 } 58 } 59 return 1; 60 } 61 62 63 OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg) 64 { 65 if (msg == NULL) { 66 ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 67 return NULL; 68 } 69 return msg->header; 70 } 71 72 const char *ossl_cmp_bodytype_to_string(int type) 73 { 74 static const char *type_names[] = { 75 "IR", "IP", "CR", "CP", "P10CR", 76 "POPDECC", "POPDECR", "KUR", "KUP", 77 "KRR", "KRP", "RR", "RP", "CCR", "CCP", 78 "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED", 79 "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP", 80 }; 81 82 if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX) 83 return "illegal body type"; 84 return type_names[type]; 85 } 86 87 int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type) 88 { 89 if (!ossl_assert(msg != NULL && msg->body != NULL)) 90 return 0; 91 92 msg->body->type = type; 93 return 1; 94 } 95 96 int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg) 97 { 98 if (!ossl_assert(msg != NULL && msg->body != NULL)) 99 return -1; 100 101 return msg->body->type; 102 } 103 104 /* Add an extension to the referenced extension stack, which may be NULL */ 105 static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex) 106 { 107 X509_EXTENSION *ext; 108 int res; 109 110 if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */ 111 return 0; 112 113 if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL) 114 return 0; 115 116 res = X509v3_add_ext(pexts, ext, 0) != NULL; 117 X509_EXTENSION_free(ext); 118 return res; 119 } 120 121 /* Add extension list to the referenced extension stack, which may be NULL */ 122 static int add_extensions(STACK_OF(X509_EXTENSION) **target, 123 const STACK_OF(X509_EXTENSION) *exts) 124 { 125 int i; 126 127 if (target == NULL) 128 return 0; 129 130 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 131 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); 132 ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext); 133 int idx = X509v3_get_ext_by_OBJ(*target, obj, -1); 134 135 /* Does extension exist in target? */ 136 if (idx != -1) { 137 /* Delete all extensions of same type */ 138 do { 139 X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target, idx)); 140 idx = X509v3_get_ext_by_OBJ(*target, obj, -1); 141 } while (idx != -1); 142 } 143 if (!X509v3_add_ext(target, ext, -1)) 144 return 0; 145 } 146 return 1; 147 } 148 149 /* Add a CRL revocation reason code to extension stack, which may be NULL */ 150 static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code) 151 { 152 ASN1_ENUMERATED *val = ASN1_ENUMERATED_new(); 153 int res = 0; 154 155 if (val != NULL && ASN1_ENUMERATED_set(val, reason_code)) 156 res = add1_extension(pexts, NID_crl_reason, 0 /* non-critical */, val); 157 ASN1_ENUMERATED_free(val); 158 return res; 159 } 160 161 OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype) 162 { 163 OSSL_CMP_MSG *msg = NULL; 164 165 if (!ossl_assert(ctx != NULL)) 166 return NULL; 167 168 if ((msg = OSSL_CMP_MSG_new(ctx->libctx, ctx->propq)) == NULL) 169 return NULL; 170 if (!ossl_cmp_hdr_init(ctx, msg->header) 171 || !ossl_cmp_msg_set_bodytype(msg, bodytype)) 172 goto err; 173 if (ctx->geninfo_ITAVs != NULL 174 && !ossl_cmp_hdr_generalInfo_push1_items(msg->header, 175 ctx->geninfo_ITAVs)) 176 goto err; 177 178 switch (bodytype) { 179 case OSSL_CMP_PKIBODY_IR: 180 case OSSL_CMP_PKIBODY_CR: 181 case OSSL_CMP_PKIBODY_KUR: 182 if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL) 183 goto err; 184 return msg; 185 186 case OSSL_CMP_PKIBODY_P10CR: 187 if (ctx->p10CSR == NULL) { 188 ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_P10CSR); 189 goto err; 190 } 191 if ((msg->body->value.p10cr = X509_REQ_dup(ctx->p10CSR)) == NULL) 192 goto err; 193 return msg; 194 195 case OSSL_CMP_PKIBODY_IP: 196 case OSSL_CMP_PKIBODY_CP: 197 case OSSL_CMP_PKIBODY_KUP: 198 if ((msg->body->value.ip = OSSL_CMP_CERTREPMESSAGE_new()) == NULL) 199 goto err; 200 return msg; 201 202 case OSSL_CMP_PKIBODY_RR: 203 if ((msg->body->value.rr = sk_OSSL_CMP_REVDETAILS_new_null()) == NULL) 204 goto err; 205 return msg; 206 case OSSL_CMP_PKIBODY_RP: 207 if ((msg->body->value.rp = OSSL_CMP_REVREPCONTENT_new()) == NULL) 208 goto err; 209 return msg; 210 211 case OSSL_CMP_PKIBODY_CERTCONF: 212 if ((msg->body->value.certConf = 213 sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL) 214 goto err; 215 return msg; 216 case OSSL_CMP_PKIBODY_PKICONF: 217 if ((msg->body->value.pkiconf = ASN1_TYPE_new()) == NULL) 218 goto err; 219 ASN1_TYPE_set(msg->body->value.pkiconf, V_ASN1_NULL, NULL); 220 return msg; 221 222 case OSSL_CMP_PKIBODY_POLLREQ: 223 if ((msg->body->value.pollReq = sk_OSSL_CMP_POLLREQ_new_null()) == NULL) 224 goto err; 225 return msg; 226 case OSSL_CMP_PKIBODY_POLLREP: 227 if ((msg->body->value.pollRep = sk_OSSL_CMP_POLLREP_new_null()) == NULL) 228 goto err; 229 return msg; 230 231 case OSSL_CMP_PKIBODY_GENM: 232 case OSSL_CMP_PKIBODY_GENP: 233 if ((msg->body->value.genm = sk_OSSL_CMP_ITAV_new_null()) == NULL) 234 goto err; 235 return msg; 236 237 case OSSL_CMP_PKIBODY_ERROR: 238 if ((msg->body->value.error = OSSL_CMP_ERRORMSGCONTENT_new()) == NULL) 239 goto err; 240 return msg; 241 242 default: 243 ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); 244 goto err; 245 } 246 247 err: 248 OSSL_CMP_MSG_free(msg); 249 return NULL; 250 } 251 252 #define HAS_SAN(ctx) \ 253 (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \ 254 || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) 255 256 static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, int for_KUR, 257 const X509_NAME *ref_subj) 258 { 259 if (ctx->subjectName != NULL) 260 return IS_NULL_DN(ctx->subjectName) ? NULL : ctx->subjectName; 261 if (ctx->p10CSR != NULL) /* first default is from any given CSR */ 262 return X509_REQ_get_subject_name(ctx->p10CSR); 263 if (for_KUR || !HAS_SAN(ctx)) 264 /* 265 * For KUR, copy subject from any reference cert as fallback. 266 * For IR or CR, do the same only if there is no subjectAltName. 267 */ 268 return ref_subj; 269 return NULL; 270 } 271 272 OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) 273 { 274 OSSL_CRMF_MSG *crm = NULL; 275 X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->cert; 276 /* refcert defaults to current client cert */ 277 EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx); 278 STACK_OF(GENERAL_NAME) *default_sans = NULL; 279 const X509_NAME *ref_subj = 280 refcert != NULL ? X509_get_subject_name(refcert) : NULL; 281 const X509_NAME *subject = determine_subj(ctx, for_KUR, ref_subj); 282 const X509_NAME *issuer = ctx->issuer != NULL || refcert == NULL 283 ? (IS_NULL_DN(ctx->issuer) ? NULL : ctx->issuer) 284 : X509_get_issuer_name(refcert); 285 int crit = ctx->setSubjectAltNameCritical || subject == NULL; 286 /* RFC5280: subjectAltName MUST be critical if subject is null */ 287 X509_EXTENSIONS *exts = NULL; 288 289 if (rkey == NULL) { 290 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 291 ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY); 292 return NULL; 293 #endif 294 } 295 if (for_KUR && refcert == NULL && ctx->p10CSR == NULL) { 296 ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT); 297 return NULL; 298 } 299 if ((crm = OSSL_CRMF_MSG_new()) == NULL) 300 return NULL; 301 if (!OSSL_CRMF_MSG_set_certReqId(crm, rid) 302 /* 303 * fill certTemplate, corresponding to CertificationRequestInfo 304 * of PKCS#10. The rkey param cannot be NULL so far - 305 * it could be NULL if centralized key creation was supported 306 */ 307 || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey, 308 subject, issuer, NULL /* serial */)) 309 goto err; 310 if (ctx->days != 0) { 311 time_t now = time(NULL); 312 ASN1_TIME *notBefore = ASN1_TIME_adj(NULL, now, 0, 0); 313 ASN1_TIME *notAfter = ASN1_TIME_adj(NULL, now, ctx->days, 0); 314 315 if (notBefore == NULL 316 || notAfter == NULL 317 || !OSSL_CRMF_MSG_set0_validity(crm, notBefore, notAfter)) { 318 ASN1_TIME_free(notBefore); 319 ASN1_TIME_free(notAfter); 320 goto err; 321 } 322 } 323 324 /* extensions */ 325 if (ctx->p10CSR != NULL 326 && (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL) 327 goto err; 328 if (!ctx->SubjectAltName_nodefault && !HAS_SAN(ctx) && refcert != NULL 329 && (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert), 330 NID_subject_alt_name, NULL, NULL)) 331 != NULL 332 && !add1_extension(&exts, NID_subject_alt_name, crit, default_sans)) 333 goto err; 334 if (ctx->reqExtensions != NULL /* augment/override existing ones */ 335 && !add_extensions(&exts, ctx->reqExtensions)) 336 goto err; 337 if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 338 && !add1_extension(&exts, NID_subject_alt_name, 339 crit, ctx->subjectAltNames)) 340 goto err; 341 if (ctx->policies != NULL 342 && !add1_extension(&exts, NID_certificate_policies, 343 ctx->setPoliciesCritical, ctx->policies)) 344 goto err; 345 if (!OSSL_CRMF_MSG_set0_extensions(crm, exts)) 346 goto err; 347 exts = NULL; 348 /* end fill certTemplate, now set any controls */ 349 350 /* for KUR, set OldCertId according to D.6 */ 351 if (for_KUR && refcert != NULL) { 352 OSSL_CRMF_CERTID *cid = 353 OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert), 354 X509_get0_serialNumber(refcert)); 355 int ret; 356 357 if (cid == NULL) 358 goto err; 359 ret = OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm, cid); 360 OSSL_CRMF_CERTID_free(cid); 361 if (ret == 0) 362 goto err; 363 } 364 365 goto end; 366 367 err: 368 OSSL_CRMF_MSG_free(crm); 369 crm = NULL; 370 371 end: 372 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 373 sk_GENERAL_NAME_pop_free(default_sans, GENERAL_NAME_free); 374 return crm; 375 } 376 377 OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type, 378 const OSSL_CRMF_MSG *crm) 379 { 380 OSSL_CMP_MSG *msg; 381 OSSL_CRMF_MSG *local_crm = NULL; 382 383 if (!ossl_assert(ctx != NULL)) 384 return NULL; 385 386 if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR 387 && type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) { 388 ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); 389 return NULL; 390 } 391 if (type == OSSL_CMP_PKIBODY_P10CR && crm != NULL) { 392 ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); 393 return NULL; 394 } 395 396 if ((msg = ossl_cmp_msg_create(ctx, type)) == NULL) 397 goto err; 398 399 /* header */ 400 if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header)) 401 goto err; 402 403 /* body */ 404 /* For P10CR the content has already been set in OSSL_CMP_MSG_create */ 405 if (type != OSSL_CMP_PKIBODY_P10CR) { 406 EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); 407 408 /* privkey is ctx->newPkey (if private, else NULL) or ctx->pkey */ 409 if (ctx->popoMethod >= OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) { 410 ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO); 411 goto err; 412 } 413 if (crm == NULL) { 414 local_crm = OSSL_CMP_CTX_setup_CRM(ctx, 415 type == OSSL_CMP_PKIBODY_KUR, 416 OSSL_CMP_CERTREQID); 417 if (local_crm == NULL 418 || !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm, 419 privkey, ctx->digest, 420 ctx->libctx, ctx->propq)) 421 goto err; 422 } else { 423 if ((local_crm = OSSL_CRMF_MSG_dup(crm)) == NULL) 424 goto err; 425 } 426 427 /* value.ir is same for cr and kur */ 428 if (!sk_OSSL_CRMF_MSG_push(msg->body->value.ir, local_crm)) 429 goto err; 430 local_crm = NULL; 431 } 432 433 if (!ossl_cmp_msg_protect(ctx, msg)) 434 goto err; 435 436 return msg; 437 438 err: 439 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREQ); 440 OSSL_CRMF_MSG_free(local_crm); 441 OSSL_CMP_MSG_free(msg); 442 return NULL; 443 } 444 445 OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype, 446 int certReqId, const OSSL_CMP_PKISI *si, 447 X509 *cert, const X509 *encryption_recip, 448 STACK_OF(X509) *chain, STACK_OF(X509) *caPubs, 449 int unprotectedErrors) 450 { 451 OSSL_CMP_MSG *msg = NULL; 452 OSSL_CMP_CERTREPMESSAGE *repMsg = NULL; 453 OSSL_CMP_CERTRESPONSE *resp = NULL; 454 int status = OSSL_CMP_PKISTATUS_unspecified; 455 456 if (!ossl_assert(ctx != NULL && si != NULL)) 457 return NULL; 458 459 if ((msg = ossl_cmp_msg_create(ctx, bodytype)) == NULL) 460 goto err; 461 repMsg = msg->body->value.ip; /* value.ip is same for cp and kup */ 462 463 /* header */ 464 if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header)) 465 goto err; 466 467 /* body */ 468 if ((resp = OSSL_CMP_CERTRESPONSE_new()) == NULL) 469 goto err; 470 OSSL_CMP_PKISI_free(resp->status); 471 if ((resp->status = OSSL_CMP_PKISI_dup(si)) == NULL 472 || !ASN1_INTEGER_set(resp->certReqId, certReqId)) 473 goto err; 474 475 status = ossl_cmp_pkisi_get_status(resp->status); 476 if (status != OSSL_CMP_PKISTATUS_rejection 477 && status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) { 478 if (encryption_recip != NULL) { 479 ERR_raise(ERR_LIB_CMP, ERR_R_UNSUPPORTED); 480 goto err; 481 } 482 483 if ((resp->certifiedKeyPair = OSSL_CMP_CERTIFIEDKEYPAIR_new()) 484 == NULL) 485 goto err; 486 resp->certifiedKeyPair->certOrEncCert->type = 487 OSSL_CMP_CERTORENCCERT_CERTIFICATE; 488 if (!X509_up_ref(cert)) 489 goto err; 490 resp->certifiedKeyPair->certOrEncCert->value.certificate = cert; 491 } 492 493 if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg->response, resp)) 494 goto err; 495 resp = NULL; 496 497 if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL 498 && (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL) 499 goto err; 500 if (sk_X509_num(chain) > 0 501 && !ossl_x509_add_certs_new(&msg->extraCerts, chain, 502 X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) 503 goto err; 504 505 if (!unprotectedErrors 506 || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection) 507 if (!ossl_cmp_msg_protect(ctx, msg)) 508 goto err; 509 510 return msg; 511 512 err: 513 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP); 514 OSSL_CMP_CERTRESPONSE_free(resp); 515 OSSL_CMP_MSG_free(msg); 516 return NULL; 517 } 518 519 OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx) 520 { 521 OSSL_CMP_MSG *msg = NULL; 522 OSSL_CMP_REVDETAILS *rd; 523 int ret; 524 525 if (!ossl_assert(ctx != NULL && (ctx->oldCert != NULL 526 || ctx->p10CSR != NULL))) 527 return NULL; 528 529 if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL) 530 goto err; 531 532 /* Fill the template from the contents of the certificate to be revoked */ 533 ret = ctx->oldCert != NULL 534 ? OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, 535 NULL /* pubkey would be redundant */, 536 NULL /* subject would be redundant */, 537 X509_get_issuer_name(ctx->oldCert), 538 X509_get0_serialNumber(ctx->oldCert)) 539 : OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, 540 X509_REQ_get0_pubkey(ctx->p10CSR), 541 X509_REQ_get_subject_name(ctx->p10CSR), 542 NULL, NULL); 543 if (!ret) 544 goto err; 545 546 /* revocation reason code is optional */ 547 if (ctx->revocationReason != CRL_REASON_NONE 548 && !add_crl_reason_extension(&rd->crlEntryDetails, 549 ctx->revocationReason)) 550 goto err; 551 552 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL) 553 goto err; 554 555 if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd)) 556 goto err; 557 rd = NULL; 558 /* Revocation Passphrase according to section 5.3.19.9 could be set here */ 559 560 if (!ossl_cmp_msg_protect(ctx, msg)) 561 goto err; 562 563 return msg; 564 565 err: 566 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR); 567 OSSL_CMP_MSG_free(msg); 568 OSSL_CMP_REVDETAILS_free(rd); 569 return NULL; 570 } 571 572 OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, 573 const OSSL_CRMF_CERTID *cid, int unprotectedErrors) 574 { 575 OSSL_CMP_REVREPCONTENT *rep = NULL; 576 OSSL_CMP_PKISI *si1 = NULL; 577 OSSL_CRMF_CERTID *cid_copy = NULL; 578 OSSL_CMP_MSG *msg = NULL; 579 580 if (!ossl_assert(ctx != NULL && si != NULL)) 581 return NULL; 582 583 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL) 584 goto err; 585 rep = msg->body->value.rp; 586 587 if ((si1 = OSSL_CMP_PKISI_dup(si)) == NULL) 588 goto err; 589 590 if (!sk_OSSL_CMP_PKISI_push(rep->status, si1)) { 591 OSSL_CMP_PKISI_free(si1); 592 goto err; 593 } 594 595 if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL) 596 goto err; 597 if (cid != NULL) { 598 if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL) 599 goto err; 600 if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) { 601 OSSL_CRMF_CERTID_free(cid_copy); 602 goto err; 603 } 604 } 605 606 if (!unprotectedErrors 607 || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection) 608 if (!ossl_cmp_msg_protect(ctx, msg)) 609 goto err; 610 611 return msg; 612 613 err: 614 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RP); 615 OSSL_CMP_MSG_free(msg); 616 return NULL; 617 } 618 619 OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx) 620 { 621 OSSL_CMP_MSG *msg; 622 623 if (!ossl_assert(ctx != NULL)) 624 return NULL; 625 626 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL) 627 goto err; 628 if (ossl_cmp_msg_protect(ctx, msg)) 629 return msg; 630 631 err: 632 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF); 633 OSSL_CMP_MSG_free(msg); 634 return NULL; 635 } 636 637 int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav) 638 { 639 int bodytype; 640 641 if (!ossl_assert(msg != NULL && itav != NULL)) 642 return 0; 643 644 bodytype = OSSL_CMP_MSG_get_bodytype(msg); 645 if (bodytype != OSSL_CMP_PKIBODY_GENM 646 && bodytype != OSSL_CMP_PKIBODY_GENP) { 647 ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); 648 return 0; 649 } 650 651 /* value.genp has the same structure, so this works for genp as well */ 652 return OSSL_CMP_ITAV_push0_stack_item(&msg->body->value.genm, itav); 653 } 654 655 int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg, 656 const STACK_OF(OSSL_CMP_ITAV) *itavs) 657 { 658 int i; 659 OSSL_CMP_ITAV *itav = NULL; 660 661 if (!ossl_assert(msg != NULL)) 662 return 0; 663 664 for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) { 665 itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i)); 666 if (itav == NULL 667 || !ossl_cmp_msg_gen_push0_ITAV(msg, itav)) { 668 OSSL_CMP_ITAV_free(itav); 669 return 0; 670 } 671 } 672 return 1; 673 } 674 675 /* 676 * Creates a new General Message/Response with an empty itav stack 677 * returns a pointer to the PKIMessage on success, NULL on error 678 */ 679 static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, 680 const STACK_OF(OSSL_CMP_ITAV) *itavs, 681 int body_type, int err_code) 682 { 683 OSSL_CMP_MSG *msg = NULL; 684 685 if (!ossl_assert(ctx != NULL)) 686 return NULL; 687 688 if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL) 689 return NULL; 690 691 if (itavs != NULL && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs)) 692 goto err; 693 694 if (!ossl_cmp_msg_protect(ctx, msg)) 695 goto err; 696 697 return msg; 698 699 err: 700 ERR_raise(ERR_LIB_CMP, err_code); 701 OSSL_CMP_MSG_free(msg); 702 return NULL; 703 } 704 705 OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx) 706 { 707 return gen_new(ctx, ctx->genm_ITAVs, 708 OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM); 709 } 710 711 OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx, 712 const STACK_OF(OSSL_CMP_ITAV) *itavs) 713 { 714 return gen_new(ctx, itavs, 715 OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP); 716 } 717 718 OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, 719 int64_t errorCode, const char *details, 720 int unprotected) 721 { 722 OSSL_CMP_MSG *msg = NULL; 723 const char *lib = NULL, *reason = NULL; 724 OSSL_CMP_PKIFREETEXT *ft; 725 726 if (!ossl_assert(ctx != NULL && si != NULL)) 727 return NULL; 728 729 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL) 730 goto err; 731 732 OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo); 733 if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si)) 734 == NULL) 735 goto err; 736 if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL) 737 goto err; 738 if (!ASN1_INTEGER_set_int64(msg->body->value.error->errorCode, errorCode)) 739 goto err; 740 if (errorCode > 0 741 && (uint64_t)errorCode < ((uint64_t)ERR_SYSTEM_FLAG << 1)) { 742 lib = ERR_lib_error_string((unsigned long)errorCode); 743 reason = ERR_reason_error_string((unsigned long)errorCode); 744 } 745 if (lib != NULL || reason != NULL || details != NULL) { 746 if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL) 747 goto err; 748 msg->body->value.error->errorDetails = ft; 749 if (lib != NULL && *lib != '\0' 750 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, -1)) 751 goto err; 752 if (reason != NULL && *reason != '\0' 753 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, -1)) 754 goto err; 755 if (details != NULL 756 && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, -1)) 757 goto err; 758 } 759 760 if (!unprotected && !ossl_cmp_msg_protect(ctx, msg)) 761 goto err; 762 return msg; 763 764 err: 765 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR); 766 OSSL_CMP_MSG_free(msg); 767 return NULL; 768 } 769 770 /* 771 * Set the certHash field of a OSSL_CMP_CERTSTATUS structure. 772 * This is used in the certConf message, for example, 773 * to confirm that the certificate was received successfully. 774 */ 775 int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus, 776 ASN1_OCTET_STRING *hash) 777 { 778 if (!ossl_assert(certStatus != NULL)) 779 return 0; 780 ASN1_OCTET_STRING_free(certStatus->certHash); 781 certStatus->certHash = hash; 782 return 1; 783 } 784 785 OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId, 786 int fail_info, const char *text) 787 { 788 OSSL_CMP_MSG *msg = NULL; 789 OSSL_CMP_CERTSTATUS *certStatus = NULL; 790 ASN1_OCTET_STRING *certHash = NULL; 791 OSSL_CMP_PKISI *sinfo; 792 793 if (!ossl_assert(ctx != NULL && ctx->newCert != NULL 794 && (certReqId == OSSL_CMP_CERTREQID 795 || certReqId == OSSL_CMP_CERTREQID_NONE))) 796 return NULL; 797 798 if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) { 799 ERR_raise(ERR_LIB_CMP, CMP_R_FAIL_INFO_OUT_OF_RANGE); 800 return NULL; 801 } 802 803 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_CERTCONF)) == NULL) 804 goto err; 805 806 if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL) 807 goto err; 808 /* consume certStatus into msg right away so it gets deallocated with msg */ 809 if (sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus) < 1) { 810 OSSL_CMP_CERTSTATUS_free(certStatus); 811 goto err; 812 } 813 814 /* set the ID of the certReq */ 815 if (!ASN1_INTEGER_set(certStatus->certReqId, certReqId)) 816 goto err; 817 /* 818 * The hash of the certificate, using the same hash algorithm 819 * as is used to create and verify the certificate signature. 820 * If not available, a default hash algorithm is used. 821 */ 822 if ((certHash = X509_digest_sig(ctx->newCert, NULL, NULL)) == NULL) 823 goto err; 824 825 if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash)) 826 goto err; 827 certHash = NULL; 828 /* 829 * For any particular CertStatus, omission of the statusInfo field 830 * indicates ACCEPTANCE of the specified certificate. Alternatively, 831 * explicit status details (with respect to acceptance or rejection) MAY 832 * be provided in the statusInfo field, perhaps for auditing purposes at 833 * the CA/RA. 834 */ 835 sinfo = fail_info != 0 ? 836 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) : 837 OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text); 838 if (sinfo == NULL) 839 goto err; 840 certStatus->statusInfo = sinfo; 841 842 if (!ossl_cmp_msg_protect(ctx, msg)) 843 goto err; 844 845 return msg; 846 847 err: 848 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTCONF); 849 OSSL_CMP_MSG_free(msg); 850 ASN1_OCTET_STRING_free(certHash); 851 return NULL; 852 } 853 854 OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid) 855 { 856 OSSL_CMP_MSG *msg = NULL; 857 OSSL_CMP_POLLREQ *preq = NULL; 858 859 if (!ossl_assert(ctx != NULL)) 860 return NULL; 861 862 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL) 863 goto err; 864 865 if ((preq = OSSL_CMP_POLLREQ_new()) == NULL 866 || !ASN1_INTEGER_set(preq->certReqId, crid) 867 || !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq)) 868 goto err; 869 870 preq = NULL; 871 if (!ossl_cmp_msg_protect(ctx, msg)) 872 goto err; 873 874 return msg; 875 876 err: 877 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ); 878 OSSL_CMP_POLLREQ_free(preq); 879 OSSL_CMP_MSG_free(msg); 880 return NULL; 881 } 882 883 OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, 884 int64_t poll_after) 885 { 886 OSSL_CMP_MSG *msg; 887 OSSL_CMP_POLLREP *prep; 888 889 if (!ossl_assert(ctx != NULL)) 890 return NULL; 891 892 if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREP)) == NULL) 893 goto err; 894 if ((prep = OSSL_CMP_POLLREP_new()) == NULL) 895 goto err; 896 if (!sk_OSSL_CMP_POLLREP_push(msg->body->value.pollRep, prep)) 897 goto err; 898 if (!ASN1_INTEGER_set(prep->certReqId, crid)) 899 goto err; 900 if (!ASN1_INTEGER_set_int64(prep->checkAfter, poll_after)) 901 goto err; 902 903 if (!ossl_cmp_msg_protect(ctx, msg)) 904 goto err; 905 return msg; 906 907 err: 908 ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP); 909 OSSL_CMP_MSG_free(msg); 910 return NULL; 911 } 912 913 /*- 914 * returns the status field of the RevRepContent with the given 915 * request/sequence id inside a revocation response. 916 * RevRepContent has the revocation statuses in same order as they were sent in 917 * RevReqContent. 918 * returns NULL on error 919 */ 920 OSSL_CMP_PKISI * 921 ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid) 922 { 923 OSSL_CMP_PKISI *status; 924 925 if (!ossl_assert(rrep != NULL)) 926 return NULL; 927 928 if ((status = sk_OSSL_CMP_PKISI_value(rrep->status, rsid)) != NULL) 929 return status; 930 931 ERR_raise(ERR_LIB_CMP, CMP_R_PKISTATUSINFO_NOT_FOUND); 932 return NULL; 933 } 934 935 /* 936 * returns the CertId field in the revCerts part of the RevRepContent 937 * with the given request/sequence id inside a revocation response. 938 * RevRepContent has the CertIds in same order as they were sent in 939 * RevReqContent. 940 * returns NULL on error 941 */ 942 OSSL_CRMF_CERTID * 943 ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, int rsid) 944 { 945 OSSL_CRMF_CERTID *cid = NULL; 946 947 if (!ossl_assert(rrep != NULL)) 948 return NULL; 949 950 if ((cid = sk_OSSL_CRMF_CERTID_value(rrep->revCerts, rsid)) != NULL) 951 return cid; 952 953 ERR_raise(ERR_LIB_CMP, CMP_R_CERTID_NOT_FOUND); 954 return NULL; 955 } 956 957 static int suitable_rid(const ASN1_INTEGER *certReqId, int rid) 958 { 959 int trid; 960 961 if (rid == OSSL_CMP_CERTREQID_NONE) 962 return 1; 963 964 trid = ossl_cmp_asn1_get_int(certReqId); 965 966 if (trid == OSSL_CMP_CERTREQID_NONE) { 967 ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); 968 return 0; 969 } 970 return rid == trid; 971 } 972 973 /* 974 * returns a pointer to the PollResponse with the given CertReqId 975 * (or the first one in case -1) inside a PollRepContent 976 * returns NULL on error or if no suitable PollResponse available 977 */ 978 OSSL_CMP_POLLREP * 979 ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc, 980 int rid) 981 { 982 OSSL_CMP_POLLREP *pollRep = NULL; 983 int i; 984 985 if (!ossl_assert(prc != NULL)) 986 return NULL; 987 988 for (i = 0; i < sk_OSSL_CMP_POLLREP_num(prc); i++) { 989 pollRep = sk_OSSL_CMP_POLLREP_value(prc, i); 990 if (suitable_rid(pollRep->certReqId, rid)) 991 return pollRep; 992 } 993 994 ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND, 995 "expected certReqId = %d", rid); 996 return NULL; 997 } 998 999 /* 1000 * returns a pointer to the CertResponse with the given CertReqId 1001 * (or the first one in case -1) inside a CertRepMessage 1002 * returns NULL on error or if no suitable CertResponse available 1003 */ 1004 OSSL_CMP_CERTRESPONSE * 1005 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, 1006 int rid) 1007 { 1008 OSSL_CMP_CERTRESPONSE *crep = NULL; 1009 int i; 1010 1011 if (!ossl_assert(crm != NULL && crm->response != NULL)) 1012 return NULL; 1013 1014 for (i = 0; i < sk_OSSL_CMP_CERTRESPONSE_num(crm->response); i++) { 1015 crep = sk_OSSL_CMP_CERTRESPONSE_value(crm->response, i); 1016 if (suitable_rid(crep->certReqId, rid)) 1017 return crep; 1018 } 1019 1020 ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND, 1021 "expected certReqId = %d", rid); 1022 return NULL; 1023 } 1024 1025 /*- 1026 * Retrieve the newly enrolled certificate from the given certResponse crep. 1027 * Uses libctx and propq from ctx, in case of indirect POPO also private key. 1028 * Returns a pointer to a copy of the found certificate, or NULL if not found. 1029 */ 1030 X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx, 1031 const OSSL_CMP_CERTRESPONSE *crep) 1032 { 1033 OSSL_CMP_CERTORENCCERT *coec; 1034 X509 *crt = NULL; 1035 EVP_PKEY *pkey; 1036 1037 if (!ossl_assert(crep != NULL && ctx != NULL)) 1038 return NULL; 1039 1040 if (crep->certifiedKeyPair 1041 && (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) { 1042 switch (coec->type) { 1043 case OSSL_CMP_CERTORENCCERT_CERTIFICATE: 1044 crt = X509_dup(coec->value.certificate); 1045 break; 1046 case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT: 1047 /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */ 1048 pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); 1049 /* pkey is ctx->newPkey (if private, else NULL) or ctx->pkey */ 1050 if (pkey == NULL) { 1051 ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY); 1052 return NULL; 1053 } 1054 crt = 1055 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert, 1056 ctx->libctx, ctx->propq, 1057 pkey); 1058 break; 1059 default: 1060 ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE); 1061 return NULL; 1062 } 1063 } 1064 if (crt == NULL) 1065 ERR_raise(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND); 1066 else 1067 (void)ossl_x509_set0_libctx(crt, ctx->libctx, ctx->propq); 1068 return crt; 1069 } 1070 1071 int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) 1072 { 1073 if (ctx == NULL || msg == NULL) { 1074 ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 1075 return 0; 1076 } 1077 if (!ossl_cmp_hdr_set_transactionID(ctx, msg->header)) 1078 return 0; 1079 return msg->header->protectionAlg == NULL 1080 || ossl_cmp_msg_protect(ctx, msg); 1081 } 1082 1083 int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) 1084 { 1085 if (ctx == NULL || msg == NULL || msg->header == NULL) { 1086 ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 1087 return 0; 1088 } 1089 if (ctx->recipNonce == NULL) /* nothing to do for 1st msg in transaction */ 1090 return 1; 1091 if (!ossl_cmp_asn1_octet_string_set1(&msg->header->recipNonce, 1092 ctx->recipNonce)) 1093 return 0; 1094 return msg->header->protectionAlg == NULL || ossl_cmp_msg_protect(ctx, msg); 1095 } 1096 1097 OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx, 1098 const char *propq) 1099 { 1100 OSSL_CMP_MSG *msg; 1101 BIO *bio = NULL; 1102 1103 if (file == NULL) { 1104 ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 1105 return NULL; 1106 } 1107 1108 msg = OSSL_CMP_MSG_new(libctx, propq); 1109 if (msg == NULL){ 1110 ERR_raise(ERR_LIB_CMP, ERR_R_MALLOC_FAILURE); 1111 return NULL; 1112 } 1113 1114 if ((bio = BIO_new_file(file, "rb")) == NULL 1115 || d2i_OSSL_CMP_MSG_bio(bio, &msg) == NULL) { 1116 OSSL_CMP_MSG_free(msg); 1117 msg = NULL; 1118 } 1119 BIO_free(bio); 1120 return msg; 1121 } 1122 1123 int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg) 1124 { 1125 BIO *bio; 1126 int res; 1127 1128 if (file == NULL || msg == NULL) { 1129 ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); 1130 return -1; 1131 } 1132 1133 bio = BIO_new_file(file, "wb"); 1134 if (bio == NULL) 1135 return -2; 1136 res = i2d_OSSL_CMP_MSG_bio(bio, msg); 1137 BIO_free(bio); 1138 return res; 1139 } 1140 1141 OSSL_CMP_MSG *d2i_OSSL_CMP_MSG(OSSL_CMP_MSG **msg, const unsigned char **in, 1142 long len) 1143 { 1144 OSSL_LIB_CTX *libctx = NULL; 1145 const char *propq = NULL; 1146 1147 if (msg != NULL && *msg != NULL) { 1148 libctx = (*msg)->libctx; 1149 propq = (*msg)->propq; 1150 } 1151 1152 return (OSSL_CMP_MSG *)ASN1_item_d2i_ex((ASN1_VALUE **)msg, in, len, 1153 ASN1_ITEM_rptr(OSSL_CMP_MSG), 1154 libctx, propq); 1155 } 1156 1157 int i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG *msg, unsigned char **out) 1158 { 1159 return ASN1_item_i2d((const ASN1_VALUE *)msg, out, 1160 ASN1_ITEM_rptr(OSSL_CMP_MSG)); 1161 } 1162 1163 OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg) 1164 { 1165 OSSL_LIB_CTX *libctx = NULL; 1166 const char *propq = NULL; 1167 1168 if (msg != NULL && *msg != NULL) { 1169 libctx = (*msg)->libctx; 1170 propq = (*msg)->propq; 1171 } 1172 1173 return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), bio, msg, libctx, 1174 propq); 1175 } 1176 1177 int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg) 1178 { 1179 return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg); 1180 } 1181