]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/crmf/crmf_lib.c
6a259f96a816dcee7acf7f6c787829f18bca3497
[thirdparty/openssl.git] / crypto / crmf / crmf_lib.c
1 /*-
2 * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright Nokia 2007-2018
4 * Copyright Siemens AG 2015-2018
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_int.h"
32
33 /* explicit #includes not strictly needed since implied by the above: */
34 #include <openssl/crmf.h>
35 #include <openssl/err.h>
36 #include <openssl/evp.h>
37
38 /*-
39 * atyp = Attribute Type
40 * valt = Value Type
41 * ctrlinf = "regCtrl" or "regInfo"
42 */
43 #define IMPLEMENT_CRMF_CTRL_FUNC(atyp, valt, ctrlinf) \
44 int OSSL_CRMF_MSG_set1_##ctrlinf##_##atyp(OSSL_CRMF_MSG *msg, \
45 const valt *in) \
46 { \
47 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *atav = NULL; \
48 \
49 if (msg == NULL || in == NULL) \
50 goto err; \
51 if ((atav = OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new()) == NULL) \
52 goto err; \
53 if ((atav->type = OBJ_nid2obj(NID_id_##ctrlinf##_##atyp)) == NULL) \
54 goto err; \
55 if ((atav->value.atyp = valt##_dup(in)) == NULL) \
56 goto err; \
57 if (!OSSL_CRMF_MSG_push0_##ctrlinf(msg, atav)) \
58 goto err; \
59 return 1; \
60 err: \
61 OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(atav); \
62 return 0; \
63 }
64
65
66 /*-
67 * Pushes the given control attribute into the controls stack of a CertRequest
68 * (section 6)
69 * returns 1 on success, 0 on error
70 */
71 static int OSSL_CRMF_MSG_push0_regCtrl(OSSL_CRMF_MSG *crm,
72 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *ctrl)
73 {
74 int new = 0;
75
76 if (crm == NULL || crm->certReq == NULL || ctrl == NULL) {
77 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_REGCTRL, CRMF_R_NULL_ARGUMENT);
78 return 0;
79 }
80
81 if (crm->certReq->controls == NULL) {
82 crm->certReq->controls = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null();
83 if (crm->certReq->controls == NULL)
84 goto oom;
85 new = 1;
86 }
87 if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->certReq->controls, ctrl))
88 goto oom;
89
90 return 1;
91 oom:
92 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_REGCTRL, ERR_R_MALLOC_FAILURE);
93
94 if (new != 0) {
95 sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(crm->certReq->controls);
96 crm->certReq->controls = NULL;
97 }
98 return 0;
99 }
100
101 /* id-regCtrl-regToken Control (section 6.1) */
102 IMPLEMENT_CRMF_CTRL_FUNC(regToken, ASN1_STRING, regCtrl)
103
104 /* id-regCtrl-authenticator Control (section 6.2) */
105 #define ASN1_UTF8STRING_dup ASN1_STRING_dup
106 IMPLEMENT_CRMF_CTRL_FUNC(authenticator, ASN1_UTF8STRING, regCtrl)
107
108 int OSSL_CRMF_MSG_set0_SinglePubInfo(OSSL_CRMF_SINGLEPUBINFO *spi,
109 int method, GENERAL_NAME *nm)
110 {
111 if (spi == NULL
112 || method < OSSL_CRMF_PUB_METHOD_DONTCARE
113 || method > OSSL_CRMF_PUB_METHOD_LDAP) {
114 CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET0_SINGLEPUBINFO,
115 ERR_R_PASSED_INVALID_ARGUMENT);
116 return 0;
117 }
118
119 if (!ASN1_INTEGER_set(spi->pubMethod, method))
120 return 0;
121 GENERAL_NAME_free(spi->pubLocation);
122 spi->pubLocation = nm;
123 return 1;
124 }
125
126 int OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(
127 OSSL_CRMF_PKIPUBLICATIONINFO *pi,
128 OSSL_CRMF_SINGLEPUBINFO *spi)
129 {
130 if (pi == NULL || spi == NULL) {
131 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PKIPUBLICATIONINFO_PUSH0_SINGLEPUBINFO,
132 CRMF_R_NULL_ARGUMENT);
133 return 0;
134 }
135 if (pi->pubInfos == NULL)
136 pi->pubInfos = sk_OSSL_CRMF_SINGLEPUBINFO_new_null();
137 if (pi->pubInfos == NULL)
138 goto oom;
139
140 if (!sk_OSSL_CRMF_SINGLEPUBINFO_push(pi->pubInfos, spi))
141 goto oom;
142 return 1;
143
144 oom:
145 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PKIPUBLICATIONINFO_PUSH0_SINGLEPUBINFO,
146 ERR_R_MALLOC_FAILURE);
147 return 0;
148 }
149
150 int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(
151 OSSL_CRMF_PKIPUBLICATIONINFO *pi, int action)
152 {
153 if (pi == NULL
154 || action < OSSL_CRMF_PUB_ACTION_DONTPUBLISH
155 || action > OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH) {
156 CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET_PKIPUBLICATIONINFO_ACTION,
157 ERR_R_PASSED_INVALID_ARGUMENT);
158 return 0;
159 }
160
161 return ASN1_INTEGER_set(pi->action, action);
162 }
163
164 /* id-regCtrl-pkiPublicationInfo Control (section 6.3) */
165 IMPLEMENT_CRMF_CTRL_FUNC(pkiPublicationInfo, OSSL_CRMF_PKIPUBLICATIONINFO,
166 regCtrl)
167
168 /* id-regCtrl-oldCertID Control (section 6.5) from the given */
169 IMPLEMENT_CRMF_CTRL_FUNC(oldCertID, OSSL_CRMF_CERTID, regCtrl)
170
171 OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer,
172 const ASN1_INTEGER *serial)
173 {
174 OSSL_CRMF_CERTID *cid = NULL;
175
176 if (issuer == NULL || serial == NULL) {
177 CRMFerr(CRMF_F_OSSL_CRMF_CERTID_GEN, CRMF_R_NULL_ARGUMENT);
178 return NULL;
179 }
180
181 if ((cid = OSSL_CRMF_CERTID_new()) == NULL)
182 goto oom;
183
184 if (!X509_NAME_set(&cid->issuer->d.directoryName, issuer))
185 goto oom;
186 cid->issuer->type = GEN_DIRNAME;
187
188 ASN1_INTEGER_free(cid->serialNumber);
189 if ((cid->serialNumber = ASN1_INTEGER_dup(serial)) == NULL)
190 goto oom;
191
192 return cid;
193
194 oom:
195 CRMFerr(CRMF_F_OSSL_CRMF_CERTID_GEN, ERR_R_MALLOC_FAILURE);
196 OSSL_CRMF_CERTID_free(cid);
197 return NULL;
198 }
199
200 /*
201 * id-regCtrl-protocolEncrKey Control (section 6.6)
202 *
203 * For some reason X509_PUBKEY_dup() is not implemented in OpenSSL X509
204 * TODO: check whether that should go elsewhere
205 */
206 static IMPLEMENT_ASN1_DUP_FUNCTION(X509_PUBKEY)
207 IMPLEMENT_CRMF_CTRL_FUNC(protocolEncrKey, X509_PUBKEY, regCtrl)
208
209 /*-
210 * Pushes the attribute given in regInfo in to the CertReqMsg->regInfo stack.
211 * (section 7)
212 * returns 1 on success, 0 on error
213 */
214 static int OSSL_CRMF_MSG_push0_regInfo(OSSL_CRMF_MSG *crm,
215 OSSL_CRMF_ATTRIBUTETYPEANDVALUE *ri)
216 {
217 STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *info = NULL;
218
219 if (crm == NULL || ri == NULL) {
220 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_REGINFO, CRMF_R_NULL_ARGUMENT);
221 return 0;
222 }
223
224 if (crm->regInfo == NULL)
225 crm->regInfo = info = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null();
226 if (crm->regInfo == NULL)
227 goto oom;
228 if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->regInfo, ri))
229 goto oom;
230 return 1;
231
232 oom:
233 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_REGINFO, ERR_R_MALLOC_FAILURE);
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 CRMFerr(CRMF_F_OSSL_CRMF_MSG_GET0_TMPL, CRMF_R_NULL_ARGUMENT);
252 return NULL;
253 }
254 return crm->certReq->certTemplate;
255 }
256
257
258 int OSSL_CRMF_MSG_set_validity(OSSL_CRMF_MSG *crm, time_t from, time_t to)
259 {
260 OSSL_CRMF_OPTIONALVALIDITY *vld = NULL;
261 ASN1_TIME *from_asn = NULL;
262 ASN1_TIME *to_asn = NULL;
263 OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm);
264
265 if (tmpl == NULL) { /* also crm == NULL implies this */
266 CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET_VALIDITY, CRMF_R_NULL_ARGUMENT);
267 return 0;
268 }
269
270 if (from != 0 && ((from_asn = ASN1_TIME_set(NULL, from)) == NULL))
271 goto oom;
272 if (to != 0 && ((to_asn = ASN1_TIME_set(NULL, to)) == NULL))
273 goto oom;
274 if ((vld = OSSL_CRMF_OPTIONALVALIDITY_new()) == NULL)
275 goto oom;
276
277 vld->notBefore = from_asn;
278 vld->notAfter = to_asn;
279
280 tmpl->validity = vld;
281
282 return 1;
283 oom:
284 CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET_VALIDITY, ERR_R_MALLOC_FAILURE);
285 ASN1_TIME_free(from_asn);
286 ASN1_TIME_free(to_asn);
287 return 0;
288 }
289
290
291 int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid)
292 {
293 if (crm == NULL || crm->certReq == NULL || crm->certReq->certReqId == NULL) {
294 CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET_CERTREQID, CRMF_R_NULL_ARGUMENT);
295 return 0;
296 }
297
298 return ASN1_INTEGER_set(crm->certReq->certReqId, rid);
299 }
300
301 /* get ASN.1 encoded integer, return -1 on error */
302 static int crmf_asn1_get_int(int func, const ASN1_INTEGER *a)
303 {
304 int64_t res;
305
306 if (!ASN1_INTEGER_get_int64(&res, a)) {
307 CRMFerr(func, ASN1_R_INVALID_NUMBER);
308 return -1;
309 }
310 if (res < INT_MIN) {
311 CRMFerr(func, ASN1_R_TOO_SMALL);
312 return -1;
313 }
314 if (res > INT_MAX) {
315 CRMFerr(func, ASN1_R_TOO_LARGE);
316 return -1;
317 }
318 return (int)res;
319 }
320
321 int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm)
322 {
323 if (crm == NULL || /* not really needed: */ crm->certReq == NULL) {
324 CRMFerr(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, CRMF_R_NULL_ARGUMENT);
325 return -1;
326 }
327 return crmf_asn1_get_int(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID,
328 crm->certReq->certReqId);
329 }
330
331
332 int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm,
333 X509_EXTENSIONS *exts)
334 {
335 OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm);
336
337 if (tmpl == NULL) { /* also crm == NULL implies this */
338 CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET0_EXTENSIONS, CRMF_R_NULL_ARGUMENT);
339 return 0;
340 }
341
342 if (sk_X509_EXTENSION_num(exts) == 0) {
343 sk_X509_EXTENSION_free(exts);
344 exts = NULL; /* do not include empty extensions list */
345 }
346
347 sk_X509_EXTENSION_pop_free(tmpl->extensions, X509_EXTENSION_free);
348 tmpl->extensions = exts;
349 return 1;
350 }
351
352
353 int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm,
354 const X509_EXTENSION *ext)
355 {
356 int new = 0;
357 OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm);
358
359 if (tmpl == NULL || ext == NULL) { /* also crm == NULL implies this */
360 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_EXTENSION, CRMF_R_NULL_ARGUMENT);
361 return 0;
362 }
363
364 if (tmpl->extensions == NULL) {
365 if ((tmpl->extensions = sk_X509_EXTENSION_new_null()) == NULL)
366 goto oom;
367 new = 1;
368 }
369
370 if (!sk_X509_EXTENSION_push(tmpl->extensions, (X509_EXTENSION *)ext))
371 goto oom;
372 return 1;
373 oom:
374 CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_EXTENSION, ERR_R_MALLOC_FAILURE);
375
376 if (new != 0) {
377 sk_X509_EXTENSION_free(tmpl->extensions);
378 tmpl->extensions = NULL;
379 }
380 return 0;
381 }
382
383 /* TODO: support cases 1+2 (besides case 3) defined in RFC 4211, section 4.1. */
384 static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps,
385 OSSL_CRMF_CERTREQUEST *cr,
386 EVP_PKEY *pkey, int dgst)
387 {
388 int len;
389 size_t crlen;
390 size_t siglen;
391 unsigned char *crder = NULL, *sig = NULL;
392 int alg_nid = 0;
393 int md_nid = 0;
394 const EVP_MD *alg = NULL;
395 EVP_MD_CTX *ctx = NULL;
396 int ret = 0;
397
398 if (ps == NULL || cr == NULL || pkey == NULL) {
399 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_NULL_ARGUMENT);
400 return 0;
401 }
402
403 /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
404 ps->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
405 ps->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
406
407 len = i2d_OSSL_CRMF_CERTREQUEST(cr, &crder);
408 if (len < 0 || crder == NULL) {
409 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
410 goto err;
411 }
412 crlen = (size_t)len;
413
414 if (!OBJ_find_sigid_by_algs(&alg_nid, dgst, EVP_PKEY_id(pkey))) {
415 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
416 CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
417 goto err;
418 }
419 if (!OBJ_find_sigid_algs(alg_nid, &md_nid, NULL)
420 || (alg = EVP_get_digestbynid(md_nid)) == NULL) {
421 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
422 CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
423 goto err;
424 }
425 if (!X509_ALGOR_set0(ps->algorithmIdentifier, OBJ_nid2obj(alg_nid),
426 V_ASN1_NULL, NULL)
427 || (ctx = EVP_MD_CTX_new()) == NULL
428 || EVP_DigestSignInit(ctx, NULL, alg, NULL, pkey) <= 0
429 || EVP_DigestSignUpdate(ctx, crder, crlen) <= 0
430 || EVP_DigestSignFinal(ctx, NULL, &siglen) <= 0) {
431 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
432 goto err;
433 }
434 if ((sig = OPENSSL_malloc(siglen)) == NULL) {
435 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, ERR_R_MALLOC_FAILURE);
436 goto err;
437 }
438 if (EVP_DigestSignFinal(ctx, sig, &siglen) <= 0
439 || !ASN1_BIT_STRING_set(ps->signature, sig, siglen)) {
440 CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
441 goto err;
442 }
443 ret = 1;
444
445 err:
446 OPENSSL_free(crder);
447 EVP_MD_CTX_free(ctx);
448 OPENSSL_free(sig);
449 return ret;
450 }
451
452
453 int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
454 int dgst, int ppmtd)
455 {
456 OSSL_CRMF_POPO *pp = NULL;
457 ASN1_INTEGER *tag = NULL;
458
459 if (crm == NULL || (ppmtd == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) {
460 CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, CRMF_R_NULL_ARGUMENT);
461 return 0;
462 }
463
464 if (ppmtd == OSSL_CRMF_POPO_NONE)
465 goto end;
466 if ((pp = OSSL_CRMF_POPO_new()) == NULL)
467 goto oom;
468 pp->type = ppmtd;
469
470 switch (ppmtd) {
471 case OSSL_CRMF_POPO_RAVERIFIED:
472 if ((pp->value.raVerified = ASN1_NULL_new()) == NULL)
473 goto oom;
474 break;
475
476 case OSSL_CRMF_POPO_SIGNATURE:
477 {
478 OSSL_CRMF_POPOSIGNINGKEY *ps = OSSL_CRMF_POPOSIGNINGKEY_new();
479 if (ps == NULL
480 || !CRMF_poposigningkey_init(ps, crm->certReq, pkey, dgst)){
481 OSSL_CRMF_POPOSIGNINGKEY_free(ps);
482 goto err;
483 }
484 pp->value.signature = ps;
485 }
486 break;
487
488 case OSSL_CRMF_POPO_KEYENC:
489 if ((pp->value.keyEncipherment = OSSL_CRMF_POPOPRIVKEY_new()) == NULL)
490 goto oom;
491 tag = ASN1_INTEGER_new();
492 pp->value.keyEncipherment->type =
493 OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE;
494 pp->value.keyEncipherment->value.subsequentMessage = tag;
495 if (tag == NULL
496 || !ASN1_INTEGER_set(tag, OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT))
497 goto oom;
498 break;
499
500 default:
501 CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO,
502 CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO);
503 goto err;
504 }
505
506 end:
507 OSSL_CRMF_POPO_free(crm->popo);
508 crm->popo = pp;
509
510 return 1;
511 oom:
512 CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, ERR_R_MALLOC_FAILURE);
513 err:
514 OSSL_CRMF_POPO_free(pp);
515 return 0;
516 }
517
518 /* returns 0 for equal, -1 for a < b or error on a, 1 for a > b or error on b */
519 static int X509_PUBKEY_cmp(X509_PUBKEY *a, X509_PUBKEY *b)
520 {
521 X509_ALGOR *algA = NULL, *algB = NULL;
522 int res = 0;
523
524 if (a == b)
525 return 0;
526 if (a == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a)
527 || algA == NULL)
528 return -1;
529 if (b == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b)
530 || algB == NULL)
531 return 1;
532 if ((res = X509_ALGOR_cmp(algA, algB)) != 0)
533 return res;
534 return EVP_PKEY_cmp(X509_PUBKEY_get0(a), X509_PUBKEY_get0(b));
535 }
536
537 /* verifies the Proof-of-Possession of the request with the given rid in reqs */
538 int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
539 int rid, int acceptRAVerified)
540 {
541 OSSL_CRMF_MSG *req = NULL;
542 X509_PUBKEY *pubkey = NULL;
543 OSSL_CRMF_POPOSIGNINGKEY *sig = NULL;
544
545 if (reqs == NULL
546 || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL
547 || req->popo == NULL) {
548 CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
549 CRMF_R_NULL_ARGUMENT);
550 return 0;
551 }
552
553 switch (req->popo->type) {
554 case OSSL_CRMF_POPO_RAVERIFIED:
555 if (acceptRAVerified)
556 return 1;
557 break;
558 case OSSL_CRMF_POPO_SIGNATURE:
559 pubkey = req->certReq->certTemplate->publicKey;
560 sig = req->popo->value.signature;
561 if (sig->poposkInput != NULL) {
562 /*
563 * According to RFC 4211: publicKey contains a copy of
564 * the public key from the certificate template. This MUST be
565 * exactly the same value as contained in the certificate template.
566 */
567 if (pubkey == NULL
568 || sig->poposkInput->publicKey == NULL
569 || X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey)
570 || ASN1_item_verify(
571 ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT),
572 sig->algorithmIdentifier, sig->signature,
573 sig->poposkInput, X509_PUBKEY_get0(pubkey)) < 1)
574 break;
575 } else {
576 if (pubkey == NULL
577 || req->certReq->certTemplate->subject == NULL
578 || ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
579 sig->algorithmIdentifier, sig->signature,
580 req->certReq,
581 X509_PUBKEY_get0(pubkey)) < 1)
582 break;
583 }
584 return 1;
585 case OSSL_CRMF_POPO_KEYENC:
586 /*
587 * TODO: when OSSL_CMP_certrep_new() supports encrypted certs,
588 * return 1 if the type of req->popo->value.keyEncipherment
589 * is OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE and
590 * its value.subsequentMessage == OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT
591 */
592 case OSSL_CRMF_POPO_KEYAGREE:
593 default:
594 CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
595 CRMF_R_UNSUPPORTED_POPO_METHOD);
596 return 0;
597 }
598 CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
599 CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED);
600 return 0;
601 }
602
603 /* retrieves the serialNumber of the given cert template or NULL on error */
604 ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(OSSL_CRMF_CERTTEMPLATE *tmpl)
605 {
606 return tmpl != NULL ? tmpl->serialNumber : NULL;
607 }
608
609 /* retrieves the issuer name of the given cert template or NULL on error */
610 X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl)
611 {
612 return tmpl != NULL ? tmpl->issuer : NULL;
613 }
614
615 /*
616 * fill in certificate template.
617 * Any value argument that is NULL will leave the respective field unchanged.
618 */
619 int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
620 EVP_PKEY *pubkey,
621 const X509_NAME *subject,
622 const X509_NAME *issuer,
623 const ASN1_INTEGER *serial)
624 {
625 if (tmpl == NULL) {
626 CRMFerr(CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, CRMF_R_NULL_ARGUMENT);
627 return 0;
628 }
629 if (subject != NULL && !X509_NAME_set(&tmpl->subject, subject))
630 goto oom;
631 if (issuer != NULL && !X509_NAME_set(&tmpl->issuer, issuer))
632 goto oom;
633 if (serial != NULL) {
634 ASN1_INTEGER_free(tmpl->serialNumber);
635 if ((tmpl->serialNumber = ASN1_INTEGER_dup(serial)) == NULL)
636 goto oom;
637 }
638 if (pubkey != NULL && !X509_PUBKEY_set(&tmpl->publicKey, pubkey))
639 goto oom;
640 return 1;
641
642 oom:
643 CRMFerr(CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, ERR_R_MALLOC_FAILURE);
644 return 0;
645 }
646
647
648 /*-
649 * Decrypts the certificate in the given encryptedValue
650 * this is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2
651 *
652 * returns a pointer to the decrypted certificate
653 * returns NULL on error or if no certificate available
654 */
655 X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
656 EVP_PKEY *pkey)
657 {
658 X509 *cert = NULL; /* decrypted certificate */
659 EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */
660 unsigned char *ek = NULL; /* decrypted symmetric encryption key */
661 const EVP_CIPHER *cipher = NULL; /* used cipher */
662 unsigned char *iv = NULL; /* initial vector for symmetric encryption */
663 unsigned char *outbuf = NULL; /* decryption output buffer */
664 const unsigned char *p = NULL; /* needed for decoding ASN1 */
665 int symmAlg = 0; /* NIDs for symmetric algorithm */
666 int n, outlen = 0;
667 EVP_PKEY_CTX *pkctx = NULL; /* private key context */
668
669 if (ecert == NULL || ecert->symmAlg == NULL || ecert->encSymmKey == NULL
670 || ecert->encValue == NULL || pkey == NULL) {
671 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
672 CRMF_R_NULL_ARGUMENT);
673 return NULL;
674 }
675 if ((symmAlg = OBJ_obj2nid(ecert->symmAlg->algorithm)) == 0) {
676 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
677 CRMF_R_UNSUPPORTED_CIPHER);
678 return NULL;
679 }
680
681 /* first the symmetric key needs to be decrypted */
682 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
683 if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx)) {
684 ASN1_BIT_STRING *encKey = ecert->encSymmKey;
685 size_t eksize = 0;
686
687 if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, encKey->data, encKey->length)
688 <= 0
689 || (ek = OPENSSL_malloc(eksize)) == NULL
690 || EVP_PKEY_decrypt(pkctx, ek, &eksize, encKey->data,
691 encKey->length) <= 0) {
692 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
693 CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY);
694 goto end;
695 }
696 } else {
697 goto oom;
698 }
699
700 /* select symmetric cipher based on algorithm given in message */
701 if ((cipher = EVP_get_cipherbynid(symmAlg)) == NULL) {
702 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
703 CRMF_R_UNSUPPORTED_CIPHER);
704 goto end;
705 }
706 if ((iv = OPENSSL_malloc(EVP_CIPHER_iv_length(cipher))) == NULL)
707 goto oom;
708 if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv,
709 EVP_CIPHER_iv_length(cipher))
710 != EVP_CIPHER_iv_length(cipher)) {
711 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
712 CRMF_R_MALFORMED_IV);
713 goto end;
714 }
715
716 /*
717 * d2i_X509 changes the given pointer, so use p for decoding the message and
718 * keep the original pointer in outbuf so the memory can be freed later
719 */
720 if ((p = outbuf = OPENSSL_malloc(ecert->encValue->length +
721 EVP_CIPHER_block_size(cipher))) == NULL
722 || (evp_ctx = EVP_CIPHER_CTX_new()) == NULL)
723 goto oom;
724 EVP_CIPHER_CTX_set_padding(evp_ctx, 0);
725
726 if (!EVP_DecryptInit(evp_ctx, cipher, ek, iv)
727 || !EVP_DecryptUpdate(evp_ctx, outbuf, &outlen,
728 ecert->encValue->data,
729 ecert->encValue->length)
730 || !EVP_DecryptFinal(evp_ctx, outbuf + outlen, &n)) {
731 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
732 CRMF_R_ERROR_DECRYPTING_CERTIFICATE);
733 goto end;
734 }
735 outlen += n;
736
737 /* convert decrypted certificate from DER to internal ASN.1 structure */
738 if ((cert = d2i_X509(NULL, &p, outlen)) == NULL) {
739 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
740 CRMF_R_ERROR_DECODING_CERTIFICATE);
741 }
742 goto end;
743
744 oom:
745 CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, ERR_R_MALLOC_FAILURE);
746 end:
747 EVP_PKEY_CTX_free(pkctx);
748 OPENSSL_free(outbuf);
749 EVP_CIPHER_CTX_free(evp_ctx);
750 OPENSSL_free(ek);
751 OPENSSL_free(iv);
752 return cert;
753 }