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