1 /*- 2 * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright Nokia 2007-2018 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 * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. 12 */ 13 14 /* 15 * This file contains the functions that handle the individual items inside 16 * the CRMF structures 17 */ 18 19 /* 20 * NAMING 21 * 22 * The 0 functions use the supplied structure pointer directly in the parent and 23 * it will be freed up when the parent is freed. 24 * 25 * The 1 functions use a copy of the supplied structure pointer (or in some 26 * cases increases its link count) in the parent and so both should be freed up. 27 */ 28 29 #include <openssl/asn1t.h> 30 31 #include "crmf_local.h" 32 #include "internal/constant_time.h" 33 #include "internal/sizes.h" 34 35 /* explicit #includes not strictly needed since implied by the above: */ 36 #include <openssl/crmf.h> 37 #include <openssl/err.h> 38 #include <openssl/evp.h> 39 40 /*- 41 * atyp = Attribute Type 42 * valt = Value Type 43 * ctrlinf = "regCtrl" or "regInfo" 44 */ 45 #define IMPLEMENT_CRMF_CTRL_FUNC(atyp, valt, ctrlinf) \ 46 valt *OSSL_CRMF_MSG_get0_##ctrlinf##_##atyp(const OSSL_CRMF_MSG *msg) \ 47 { \ 48 int i; \ 49 STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *controls; \ 50 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *atav = NULL; \ 51 \ 52 if (msg == NULL || msg->certReq == NULL) \ 53 return NULL; \ 54 controls = msg->certReq->controls; \ 55 for (i = 0; i < sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_num(controls); i++) { \ 56 atav = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_value(controls, i); \ 57 if (OBJ_obj2nid(atav->type) == NID_id_##ctrlinf##_##atyp) \ 58 return atav->value.atyp; \ 59 } \ 60 return NULL; \ 61 } \ 62 \ 63 int OSSL_CRMF_MSG_set1_##ctrlinf##_##atyp(OSSL_CRMF_MSG *msg, const valt *in) \ 64 { \ 65 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *atav = NULL; \ 66 \ 67 if (msg == NULL || in == NULL) \ 68 goto err; \ 69 if ((atav = OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new()) == NULL) \ 70 goto err; \ 71 if ((atav->type = OBJ_nid2obj(NID_id_##ctrlinf##_##atyp)) == NULL) \ 72 goto err; \ 73 if ((atav->value.atyp = valt##_dup(in)) == NULL) \ 74 goto err; \ 75 if (!OSSL_CRMF_MSG_push0_##ctrlinf(msg, atav)) \ 76 goto err; \ 77 return 1; \ 78 err: \ 79 OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(atav); \ 80 return 0; \ 81 } 82 83 84 /*- 85 * Pushes the given control attribute into the controls stack of a CertRequest 86 * (section 6) 87 * returns 1 on success, 0 on error 88 */ 89 static int OSSL_CRMF_MSG_push0_regCtrl(OSSL_CRMF_MSG *crm, 90 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *ctrl) 91 { 92 int new = 0; 93 94 if (crm == NULL || crm->certReq == NULL || ctrl == NULL) { 95 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 96 return 0; 97 } 98 99 if (crm->certReq->controls == NULL) { 100 crm->certReq->controls = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null(); 101 if (crm->certReq->controls == NULL) 102 goto err; 103 new = 1; 104 } 105 if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->certReq->controls, ctrl)) 106 goto err; 107 108 return 1; 109 err: 110 if (new != 0) { 111 sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(crm->certReq->controls); 112 crm->certReq->controls = NULL; 113 } 114 return 0; 115 } 116 117 /* id-regCtrl-regToken Control (section 6.1) */ 118 IMPLEMENT_CRMF_CTRL_FUNC(regToken, ASN1_STRING, regCtrl) 119 120 /* id-regCtrl-authenticator Control (section 6.2) */ 121 #define ASN1_UTF8STRING_dup ASN1_STRING_dup 122 IMPLEMENT_CRMF_CTRL_FUNC(authenticator, ASN1_UTF8STRING, regCtrl) 123 124 int OSSL_CRMF_MSG_set0_SinglePubInfo(OSSL_CRMF_SINGLEPUBINFO *spi, 125 int method, GENERAL_NAME *nm) 126 { 127 if (spi == NULL 128 || method < OSSL_CRMF_PUB_METHOD_DONTCARE 129 || method > OSSL_CRMF_PUB_METHOD_LDAP) { 130 ERR_raise(ERR_LIB_CRMF, ERR_R_PASSED_INVALID_ARGUMENT); 131 return 0; 132 } 133 134 if (!ASN1_INTEGER_set(spi->pubMethod, method)) 135 return 0; 136 GENERAL_NAME_free(spi->pubLocation); 137 spi->pubLocation = nm; 138 return 1; 139 } 140 141 int 142 OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(OSSL_CRMF_PKIPUBLICATIONINFO *pi, 143 OSSL_CRMF_SINGLEPUBINFO *spi) 144 { 145 if (pi == NULL || spi == NULL) { 146 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 147 return 0; 148 } 149 if (pi->pubInfos == NULL) 150 pi->pubInfos = sk_OSSL_CRMF_SINGLEPUBINFO_new_null(); 151 if (pi->pubInfos == NULL) 152 return 0; 153 154 return sk_OSSL_CRMF_SINGLEPUBINFO_push(pi->pubInfos, spi); 155 } 156 157 int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(OSSL_CRMF_PKIPUBLICATIONINFO *pi, 158 int action) 159 { 160 if (pi == NULL 161 || action < OSSL_CRMF_PUB_ACTION_DONTPUBLISH 162 || action > OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH) { 163 ERR_raise(ERR_LIB_CRMF, ERR_R_PASSED_INVALID_ARGUMENT); 164 return 0; 165 } 166 167 return ASN1_INTEGER_set(pi->action, action); 168 } 169 170 /* id-regCtrl-pkiPublicationInfo Control (section 6.3) */ 171 IMPLEMENT_CRMF_CTRL_FUNC(pkiPublicationInfo, OSSL_CRMF_PKIPUBLICATIONINFO, 172 regCtrl) 173 174 /* id-regCtrl-oldCertID Control (section 6.5) from the given */ 175 IMPLEMENT_CRMF_CTRL_FUNC(oldCertID, OSSL_CRMF_CERTID, regCtrl) 176 177 OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer, 178 const ASN1_INTEGER *serial) 179 { 180 OSSL_CRMF_CERTID *cid = NULL; 181 182 if (issuer == NULL || serial == NULL) { 183 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 184 return NULL; 185 } 186 187 if ((cid = OSSL_CRMF_CERTID_new()) == NULL) 188 goto err; 189 190 if (!X509_NAME_set(&cid->issuer->d.directoryName, issuer)) 191 goto err; 192 cid->issuer->type = GEN_DIRNAME; 193 194 ASN1_INTEGER_free(cid->serialNumber); 195 if ((cid->serialNumber = ASN1_INTEGER_dup(serial)) == NULL) 196 goto err; 197 198 return cid; 199 200 err: 201 OSSL_CRMF_CERTID_free(cid); 202 return NULL; 203 } 204 205 /* 206 * id-regCtrl-protocolEncrKey Control (section 6.6) 207 */ 208 IMPLEMENT_CRMF_CTRL_FUNC(protocolEncrKey, X509_PUBKEY, regCtrl) 209 210 /*- 211 * Pushes the attribute given in regInfo in to the CertReqMsg->regInfo stack. 212 * (section 7) 213 * returns 1 on success, 0 on error 214 */ 215 static int OSSL_CRMF_MSG_push0_regInfo(OSSL_CRMF_MSG *crm, 216 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *ri) 217 { 218 STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *info = NULL; 219 220 if (crm == NULL || ri == NULL) { 221 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 222 return 0; 223 } 224 225 if (crm->regInfo == NULL) 226 crm->regInfo = info = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null(); 227 if (crm->regInfo == NULL) 228 goto err; 229 if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->regInfo, ri)) 230 goto err; 231 return 1; 232 233 err: 234 if (info != NULL) 235 crm->regInfo = NULL; 236 sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(info); 237 return 0; 238 } 239 240 /* id-regInfo-utf8Pairs to regInfo (section 7.1) */ 241 IMPLEMENT_CRMF_CTRL_FUNC(utf8Pairs, ASN1_UTF8STRING, regInfo) 242 243 /* id-regInfo-certReq to regInfo (section 7.2) */ 244 IMPLEMENT_CRMF_CTRL_FUNC(certReq, OSSL_CRMF_CERTREQUEST, regInfo) 245 246 247 /* retrieves the certificate template of crm */ 248 OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm) 249 { 250 if (crm == NULL || crm->certReq == NULL) { 251 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 252 return NULL; 253 } 254 return crm->certReq->certTemplate; 255 } 256 257 258 int OSSL_CRMF_MSG_set0_validity(OSSL_CRMF_MSG *crm, 259 ASN1_TIME *notBefore, ASN1_TIME *notAfter) 260 { 261 OSSL_CRMF_OPTIONALVALIDITY *vld; 262 OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm); 263 264 if (tmpl == NULL) { /* also crm == NULL implies this */ 265 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 266 return 0; 267 } 268 269 if ((vld = OSSL_CRMF_OPTIONALVALIDITY_new()) == NULL) 270 return 0; 271 vld->notBefore = notBefore; 272 vld->notAfter = notAfter; 273 tmpl->validity = vld; 274 return 1; 275 } 276 277 278 int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid) 279 { 280 if (crm == NULL || crm->certReq == NULL || crm->certReq->certReqId == NULL) { 281 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 282 return 0; 283 } 284 285 return ASN1_INTEGER_set(crm->certReq->certReqId, rid); 286 } 287 288 /* get ASN.1 encoded integer, return -1 on error */ 289 static int crmf_asn1_get_int(const ASN1_INTEGER *a) 290 { 291 int64_t res; 292 293 if (!ASN1_INTEGER_get_int64(&res, a)) { 294 ERR_raise(ERR_LIB_CRMF, ASN1_R_INVALID_NUMBER); 295 return -1; 296 } 297 if (res < INT_MIN) { 298 ERR_raise(ERR_LIB_CRMF, ASN1_R_TOO_SMALL); 299 return -1; 300 } 301 if (res > INT_MAX) { 302 ERR_raise(ERR_LIB_CRMF, ASN1_R_TOO_LARGE); 303 return -1; 304 } 305 return (int)res; 306 } 307 308 int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm) 309 { 310 if (crm == NULL || /* not really needed: */ crm->certReq == NULL) { 311 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 312 return -1; 313 } 314 return crmf_asn1_get_int(crm->certReq->certReqId); 315 } 316 317 318 int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, 319 X509_EXTENSIONS *exts) 320 { 321 OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm); 322 323 if (tmpl == NULL) { /* also crm == NULL implies this */ 324 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 325 return 0; 326 } 327 328 if (sk_X509_EXTENSION_num(exts) == 0) { 329 sk_X509_EXTENSION_free(exts); 330 exts = NULL; /* do not include empty extensions list */ 331 } 332 333 sk_X509_EXTENSION_pop_free(tmpl->extensions, X509_EXTENSION_free); 334 tmpl->extensions = exts; 335 return 1; 336 } 337 338 339 int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, 340 X509_EXTENSION *ext) 341 { 342 int new = 0; 343 OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm); 344 345 if (tmpl == NULL || ext == NULL) { /* also crm == NULL implies this */ 346 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 347 return 0; 348 } 349 350 if (tmpl->extensions == NULL) { 351 if ((tmpl->extensions = sk_X509_EXTENSION_new_null()) == NULL) 352 goto err; 353 new = 1; 354 } 355 356 if (!sk_X509_EXTENSION_push(tmpl->extensions, ext)) 357 goto err; 358 return 1; 359 err: 360 if (new != 0) { 361 sk_X509_EXTENSION_free(tmpl->extensions); 362 tmpl->extensions = NULL; 363 } 364 return 0; 365 } 366 367 static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps, 368 const OSSL_CRMF_CERTREQUEST *cr, 369 EVP_PKEY *pkey, const EVP_MD *digest, 370 OSSL_LIB_CTX *libctx, const char *propq) 371 { 372 char name[80] = ""; 373 374 if (ps == NULL || cr == NULL || pkey == NULL) { 375 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 376 return 0; 377 } 378 if (ps->poposkInput != NULL) { 379 /* We do not support cases 1+2 defined in RFC 4211, section 4.1 */ 380 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPOSKINPUT_NOT_SUPPORTED); 381 return 0; 382 } 383 384 if (EVP_PKEY_get_default_digest_name(pkey, name, sizeof(name)) > 0 385 && strcmp(name, "UNDEF") == 0) /* at least for Ed25519, Ed448 */ 386 digest = NULL; 387 388 return ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST), 389 ps->algorithmIdentifier, NULL, ps->signature, cr, 390 NULL, pkey, digest, libctx, propq); 391 } 392 393 394 int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm, 395 EVP_PKEY *pkey, const EVP_MD *digest, 396 OSSL_LIB_CTX *libctx, const char *propq) 397 { 398 OSSL_CRMF_POPO *pp = NULL; 399 ASN1_INTEGER *tag = NULL; 400 401 if (crm == NULL || (meth == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) { 402 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 403 return 0; 404 } 405 406 if (meth == OSSL_CRMF_POPO_NONE) 407 goto end; 408 if ((pp = OSSL_CRMF_POPO_new()) == NULL) 409 goto err; 410 pp->type = meth; 411 412 switch (meth) { 413 case OSSL_CRMF_POPO_RAVERIFIED: 414 if ((pp->value.raVerified = ASN1_NULL_new()) == NULL) 415 goto err; 416 break; 417 418 case OSSL_CRMF_POPO_SIGNATURE: 419 { 420 OSSL_CRMF_POPOSIGNINGKEY *ps = OSSL_CRMF_POPOSIGNINGKEY_new(); 421 422 if (ps == NULL) 423 goto err; 424 if (!create_popo_signature(ps, crm->certReq, pkey, digest, 425 libctx, propq)) { 426 OSSL_CRMF_POPOSIGNINGKEY_free(ps); 427 goto err; 428 } 429 pp->value.signature = ps; 430 } 431 break; 432 433 case OSSL_CRMF_POPO_KEYENC: 434 if ((pp->value.keyEncipherment = OSSL_CRMF_POPOPRIVKEY_new()) == NULL) 435 goto err; 436 tag = ASN1_INTEGER_new(); 437 pp->value.keyEncipherment->type = 438 OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE; 439 pp->value.keyEncipherment->value.subsequentMessage = tag; 440 if (tag == NULL 441 || !ASN1_INTEGER_set(tag, OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT)) 442 goto err; 443 break; 444 445 default: 446 ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO); 447 goto err; 448 } 449 450 end: 451 OSSL_CRMF_POPO_free(crm->popo); 452 crm->popo = pp; 453 454 return 1; 455 err: 456 OSSL_CRMF_POPO_free(pp); 457 return 0; 458 } 459 460 /* verifies the Proof-of-Possession of the request with the given rid in reqs */ 461 int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, 462 int rid, int acceptRAVerified, 463 OSSL_LIB_CTX *libctx, const char *propq) 464 { 465 OSSL_CRMF_MSG *req = NULL; 466 X509_PUBKEY *pubkey = NULL; 467 OSSL_CRMF_POPOSIGNINGKEY *sig = NULL; 468 const ASN1_ITEM *it; 469 void *asn; 470 471 if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) { 472 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 473 return 0; 474 } 475 476 if (req->popo == NULL) { 477 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING); 478 return 0; 479 } 480 481 switch (req->popo->type) { 482 case OSSL_CRMF_POPO_RAVERIFIED: 483 if (!acceptRAVerified) { 484 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED); 485 return 0; 486 } 487 break; 488 case OSSL_CRMF_POPO_SIGNATURE: 489 pubkey = req->certReq->certTemplate->publicKey; 490 if (pubkey == NULL) { 491 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING_PUBLIC_KEY); 492 return 0; 493 } 494 sig = req->popo->value.signature; 495 if (sig->poposkInput != NULL) { 496 /* 497 * According to RFC 4211: publicKey contains a copy of 498 * the public key from the certificate template. This MUST be 499 * exactly the same value as contained in the certificate template. 500 */ 501 if (sig->poposkInput->publicKey == NULL) { 502 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING_PUBLIC_KEY); 503 return 0; 504 } 505 if (X509_PUBKEY_eq(pubkey, sig->poposkInput->publicKey) != 1) { 506 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY); 507 return 0; 508 } 509 it = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT); 510 asn = sig->poposkInput; 511 } else { 512 if (req->certReq->certTemplate->subject == NULL) { 513 ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING_SUBJECT); 514 return 0; 515 } 516 it = ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST); 517 asn = req->certReq; 518 } 519 if (ASN1_item_verify_ex(it, sig->algorithmIdentifier, sig->signature, 520 asn, NULL, X509_PUBKEY_get0(pubkey), libctx, 521 propq) < 1) 522 return 0; 523 break; 524 case OSSL_CRMF_POPO_KEYENC: 525 case OSSL_CRMF_POPO_KEYAGREE: 526 default: 527 ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_POPO_METHOD); 528 return 0; 529 } 530 return 1; 531 } 532 533 /* retrieves the serialNumber of the given cert template or NULL on error */ 534 const ASN1_INTEGER 535 *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl) 536 { 537 return tmpl != NULL ? tmpl->serialNumber : NULL; 538 } 539 540 const X509_NAME 541 *OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl) 542 { 543 return tmpl != NULL ? tmpl->subject : NULL; 544 } 545 546 /* retrieves the issuer name of the given cert template or NULL on error */ 547 const X509_NAME 548 *OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl) 549 { 550 return tmpl != NULL ? tmpl->issuer : NULL; 551 } 552 553 X509_EXTENSIONS 554 *OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl) 555 { 556 return tmpl != NULL ? tmpl->extensions : NULL; 557 } 558 559 /* retrieves the issuer name of the given CertId or NULL on error */ 560 const X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid) 561 { 562 return cid != NULL && cid->issuer->type == GEN_DIRNAME ? 563 cid->issuer->d.directoryName : NULL; 564 } 565 566 /* retrieves the serialNumber of the given CertId or NULL on error */ 567 const ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid) 568 { 569 return cid != NULL ? cid->serialNumber : NULL; 570 } 571 572 /*- 573 * fill in certificate template. 574 * Any value argument that is NULL will leave the respective field unchanged. 575 */ 576 int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, 577 EVP_PKEY *pubkey, 578 const X509_NAME *subject, 579 const X509_NAME *issuer, 580 const ASN1_INTEGER *serial) 581 { 582 if (tmpl == NULL) { 583 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 584 return 0; 585 } 586 if (subject != NULL && !X509_NAME_set((X509_NAME **)&tmpl->subject, subject)) 587 return 0; 588 if (issuer != NULL && !X509_NAME_set((X509_NAME **)&tmpl->issuer, issuer)) 589 return 0; 590 if (serial != NULL) { 591 ASN1_INTEGER_free(tmpl->serialNumber); 592 if ((tmpl->serialNumber = ASN1_INTEGER_dup(serial)) == NULL) 593 return 0; 594 } 595 if (pubkey != NULL && !X509_PUBKEY_set(&tmpl->publicKey, pubkey)) 596 return 0; 597 return 1; 598 } 599 600 601 /*- 602 * Decrypts the certificate in the given encryptedValue using private key pkey. 603 * This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2. 604 * 605 * returns a pointer to the decrypted certificate 606 * returns NULL on error or if no certificate available 607 */ 608 X509 609 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert, 610 OSSL_LIB_CTX *libctx, const char *propq, 611 EVP_PKEY *pkey) 612 { 613 X509 *cert = NULL; /* decrypted certificate */ 614 EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */ 615 unsigned char *ek = NULL; /* decrypted symmetric encryption key */ 616 size_t eksize = 0; /* size of decrypted symmetric encryption key */ 617 EVP_CIPHER *cipher = NULL; /* used cipher */ 618 int cikeysize = 0; /* key size from cipher */ 619 unsigned char *iv = NULL; /* initial vector for symmetric encryption */ 620 unsigned char *outbuf = NULL; /* decryption output buffer */ 621 const unsigned char *p = NULL; /* needed for decoding ASN1 */ 622 int n, outlen = 0; 623 EVP_PKEY_CTX *pkctx = NULL; /* private key context */ 624 char name[OSSL_MAX_NAME_SIZE]; 625 626 if (ecert == NULL || ecert->symmAlg == NULL || ecert->encSymmKey == NULL 627 || ecert->encValue == NULL || pkey == NULL) { 628 ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); 629 return NULL; 630 } 631 632 /* select symmetric cipher based on algorithm given in message */ 633 OBJ_obj2txt(name, sizeof(name), ecert->symmAlg->algorithm, 0); 634 635 (void)ERR_set_mark(); 636 cipher = EVP_CIPHER_fetch(NULL, name, NULL); 637 638 if (cipher == NULL) 639 cipher = (EVP_CIPHER *)EVP_get_cipherbyname(name); 640 641 if (cipher == NULL) { 642 (void)ERR_clear_last_mark(); 643 ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_CIPHER); 644 goto end; 645 } 646 (void)ERR_pop_to_mark(); 647 648 cikeysize = EVP_CIPHER_get_key_length(cipher); 649 /* first the symmetric key needs to be decrypted */ 650 pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); 651 if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx) > 0) { 652 ASN1_BIT_STRING *encKey = ecert->encSymmKey; 653 size_t failure; 654 int retval; 655 656 if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, 657 encKey->data, encKey->length) <= 0 658 || (ek = OPENSSL_malloc(eksize)) == NULL) 659 goto end; 660 retval = EVP_PKEY_decrypt(pkctx, ek, &eksize, 661 encKey->data, encKey->length); 662 ERR_clear_error(); /* error state may have sensitive information */ 663 failure = ~constant_time_is_zero_s(constant_time_msb(retval) 664 | constant_time_is_zero(retval)); 665 failure |= ~constant_time_eq_s(eksize, (size_t)cikeysize); 666 if (failure) { 667 ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY); 668 goto end; 669 } 670 } else { 671 goto end; 672 } 673 if ((iv = OPENSSL_malloc(EVP_CIPHER_get_iv_length(cipher))) == NULL) 674 goto end; 675 if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, 676 EVP_CIPHER_get_iv_length(cipher)) 677 != EVP_CIPHER_get_iv_length(cipher)) { 678 ERR_raise(ERR_LIB_CRMF, CRMF_R_MALFORMED_IV); 679 goto end; 680 } 681 682 /* 683 * d2i_X509 changes the given pointer, so use p for decoding the message and 684 * keep the original pointer in outbuf so the memory can be freed later 685 */ 686 if ((p = outbuf = OPENSSL_malloc(ecert->encValue->length + 687 EVP_CIPHER_get_block_size(cipher))) == NULL 688 || (evp_ctx = EVP_CIPHER_CTX_new()) == NULL) 689 goto end; 690 EVP_CIPHER_CTX_set_padding(evp_ctx, 0); 691 692 if (!EVP_DecryptInit(evp_ctx, cipher, ek, iv) 693 || !EVP_DecryptUpdate(evp_ctx, outbuf, &outlen, 694 ecert->encValue->data, 695 ecert->encValue->length) 696 || !EVP_DecryptFinal(evp_ctx, outbuf + outlen, &n)) { 697 ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_CERTIFICATE); 698 goto end; 699 } 700 outlen += n; 701 702 /* convert decrypted certificate from DER to internal ASN.1 structure */ 703 if ((cert = X509_new_ex(libctx, propq)) == NULL) 704 goto end; 705 if (d2i_X509(&cert, &p, outlen) == NULL) 706 ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE); 707 end: 708 EVP_PKEY_CTX_free(pkctx); 709 OPENSSL_free(outbuf); 710 EVP_CIPHER_CTX_free(evp_ctx); 711 EVP_CIPHER_free(cipher); 712 OPENSSL_clear_free(ek, eksize); 713 OPENSSL_free(iv); 714 return cert; 715 } 716