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