xref: /openssl/crypto/cmp/cmp_ctx.c (revision b6461792)
1 /*
2  * Copyright 2007-2024 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 #include <openssl/trace.h>
13 #include <openssl/bio.h>
14 #include <openssl/ocsp.h> /* for OCSP_REVOKED_STATUS_* */
15 
16 #include "cmp_local.h"
17 
18 /* explicit #includes not strictly needed since implied by the above: */
19 #include <openssl/cmp.h>
20 #include <openssl/crmf.h>
21 #include <openssl/err.h>
22 
23 #define DEFINE_OSSL_CMP_CTX_get0(FIELD, TYPE) \
24     DEFINE_OSSL_CMP_CTX_get0_NAME(FIELD, FIELD, TYPE)
25 #define DEFINE_OSSL_CMP_CTX_get0_NAME(NAME, FIELD, TYPE) \
26 TYPE *OSSL_CMP_CTX_get0_##NAME(const OSSL_CMP_CTX *ctx) \
27 { \
28     if (ctx == NULL) { \
29         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
30         return NULL; \
31     } \
32     return ctx->FIELD; \
33 }
34 
35 /*
36  * Get current certificate store containing trusted root CA certs
37  */
DEFINE_OSSL_CMP_CTX_get0_NAME(trusted,trusted,X509_STORE)38 DEFINE_OSSL_CMP_CTX_get0_NAME(trusted, trusted, X509_STORE)
39 
40 #define DEFINE_OSSL_set0(PREFIX, FIELD, TYPE) \
41     DEFINE_OSSL_set0_NAME(PREFIX, FIELD, FIELD, TYPE)
42 #define DEFINE_OSSL_set0_NAME(PREFIX, NAME, FIELD, TYPE) \
43 int PREFIX##_set0##_##NAME(OSSL_CMP_CTX *ctx, TYPE *val) \
44 { \
45     if (ctx == NULL) { \
46         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
47         return 0; \
48     } \
49     TYPE##_free(ctx->FIELD); \
50     ctx->FIELD = val; \
51     return 1; \
52 }
53 
54 /*
55  * Set certificate store containing trusted (root) CA certs and possibly CRLs
56  * and a cert verification callback function used for CMP server authentication.
57  * Any already existing store entry is freed. Given NULL, the entry is reset.
58  */
59 DEFINE_OSSL_set0_NAME(OSSL_CMP_CTX, trusted, trusted, X509_STORE)
60 
61 DEFINE_OSSL_CMP_CTX_get0(libctx, OSSL_LIB_CTX)
62 DEFINE_OSSL_CMP_CTX_get0(propq, const char)
63 
64 /* Get current list of non-trusted intermediate certs */
65 DEFINE_OSSL_CMP_CTX_get0(untrusted, STACK_OF(X509))
66 
67 /*
68  * Set untrusted certificates for path construction in authentication of
69  * the CMP server and potentially others (TLS server, newly enrolled cert).
70  */
71 int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
72 {
73     STACK_OF(X509) *untrusted = NULL;
74 
75     if (ctx == NULL) {
76         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
77         return 0;
78     }
79     if (!ossl_x509_add_certs_new(&untrusted, certs,
80                                  X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
81         goto err;
82     OSSL_STACK_OF_X509_free(ctx->untrusted);
83     ctx->untrusted = untrusted;
84     return 1;
85  err:
86     OSSL_STACK_OF_X509_free(untrusted);
87     return 0;
88 }
89 
cmp_ctx_set_md(OSSL_CMP_CTX * ctx,EVP_MD ** pmd,int nid)90 static int cmp_ctx_set_md(OSSL_CMP_CTX *ctx, EVP_MD **pmd, int nid)
91 {
92     EVP_MD *md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propq);
93     /* fetching in advance to be able to throw error early if unsupported */
94 
95     if (md == NULL) {
96         ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_ALGORITHM);
97         return 0;
98     }
99     EVP_MD_free(*pmd);
100     *pmd = md;
101     return 1;
102 }
103 
104 /*
105  * Allocates and initializes OSSL_CMP_CTX context structure with default values.
106  * Returns new context on success, NULL on error
107  */
OSSL_CMP_CTX_new(OSSL_LIB_CTX * libctx,const char * propq)108 OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq)
109 {
110     OSSL_CMP_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
111 
112     if (ctx == NULL)
113         goto err;
114 
115     ctx->libctx = libctx;
116     if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)
117         goto err;
118 
119     ctx->log_verbosity = OSSL_CMP_LOG_INFO;
120 
121     ctx->status = OSSL_CMP_PKISTATUS_unspecified;
122     ctx->failInfoCode = -1;
123 
124     ctx->keep_alive = 1;
125     ctx->msg_timeout = -1;
126     ctx->tls_used = -1; /* default for backward compatibility */
127 
128     if ((ctx->untrusted = sk_X509_new_null()) == NULL) {
129         ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB);
130         goto err;
131     }
132 
133     ctx->pbm_slen = 16;
134     if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256))
135         goto err;
136     ctx->pbm_itercnt = 500;
137     ctx->pbm_mac = NID_hmac_sha1;
138 
139     if (!cmp_ctx_set_md(ctx, &ctx->digest, NID_sha256))
140         goto err;
141     ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE;
142     ctx->revocationReason = CRL_REASON_NONE;
143 
144     /* all other elements are initialized to 0 or NULL, respectively */
145     return ctx;
146 
147  err:
148     OSSL_CMP_CTX_free(ctx);
149     return NULL;
150 }
151 
152 #define OSSL_CMP_ITAVs_free(itavs) \
153     sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
154 #define X509_EXTENSIONS_free(exts) \
155     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free)
156 #define OSSL_CMP_PKIFREETEXT_free(text) \
157     sk_ASN1_UTF8STRING_pop_free(text, ASN1_UTF8STRING_free)
158 
159 /* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
OSSL_CMP_CTX_reinit(OSSL_CMP_CTX * ctx)160 int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
161 {
162     if (ctx == NULL) {
163         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
164         return 0;
165     }
166 
167 #ifndef OPENSSL_NO_HTTP
168     if (ctx->http_ctx != NULL) {
169         (void)OSSL_HTTP_close(ctx->http_ctx, 1);
170         ossl_cmp_debug(ctx, "disconnected from CMP server");
171         ctx->http_ctx = NULL;
172     }
173 #endif
174     ctx->status = OSSL_CMP_PKISTATUS_unspecified;
175     ctx->failInfoCode = -1;
176 
177     OSSL_CMP_ITAVs_free(ctx->genm_ITAVs);
178     ctx->genm_ITAVs = NULL;
179 
180     return ossl_cmp_ctx_set0_statusString(ctx, NULL)
181         && ossl_cmp_ctx_set0_newCert(ctx, NULL)
182         && ossl_cmp_ctx_set1_newChain(ctx, NULL)
183         && ossl_cmp_ctx_set1_caPubs(ctx, NULL)
184         && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL)
185         && ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL)
186         && ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL)
187         && OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
188         && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)
189         && ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
190 }
191 
192 /* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */
OSSL_CMP_CTX_free(OSSL_CMP_CTX * ctx)193 void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
194 {
195     if (ctx == NULL)
196         return;
197 
198 #ifndef OPENSSL_NO_HTTP
199     if (ctx->http_ctx != NULL) {
200         (void)OSSL_HTTP_close(ctx->http_ctx, 1);
201         ossl_cmp_debug(ctx, "disconnected from CMP server");
202     }
203 #endif
204     OPENSSL_free(ctx->propq);
205     OPENSSL_free(ctx->serverPath);
206     OPENSSL_free(ctx->server);
207     OPENSSL_free(ctx->proxy);
208     OPENSSL_free(ctx->no_proxy);
209 
210     X509_free(ctx->srvCert);
211     X509_free(ctx->validatedSrvCert);
212     X509_NAME_free(ctx->expected_sender);
213     X509_STORE_free(ctx->trusted);
214     OSSL_STACK_OF_X509_free(ctx->untrusted);
215 
216     X509_free(ctx->cert);
217     OSSL_STACK_OF_X509_free(ctx->chain);
218     EVP_PKEY_free(ctx->pkey);
219     ASN1_OCTET_STRING_free(ctx->referenceValue);
220     if (ctx->secretValue != NULL)
221         OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
222     ASN1_OCTET_STRING_free(ctx->secretValue);
223     EVP_MD_free(ctx->pbm_owf);
224 
225     X509_NAME_free(ctx->recipient);
226     EVP_MD_free(ctx->digest);
227     ASN1_OCTET_STRING_free(ctx->transactionID);
228     ASN1_OCTET_STRING_free(ctx->senderNonce);
229     ASN1_OCTET_STRING_free(ctx->recipNonce);
230     ASN1_OCTET_STRING_free(ctx->first_senderNonce);
231     OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs);
232     OSSL_STACK_OF_X509_free(ctx->extraCertsOut);
233 
234     EVP_PKEY_free(ctx->newPkey);
235     X509_NAME_free(ctx->issuer);
236     ASN1_INTEGER_free(ctx->serialNumber);
237     X509_NAME_free(ctx->subjectName);
238     sk_GENERAL_NAME_pop_free(ctx->subjectAltNames, GENERAL_NAME_free);
239     X509_EXTENSIONS_free(ctx->reqExtensions);
240     sk_POLICYINFO_pop_free(ctx->policies, POLICYINFO_free);
241     X509_free(ctx->oldCert);
242     X509_REQ_free(ctx->p10CSR);
243 
244     OSSL_CMP_ITAVs_free(ctx->genm_ITAVs);
245 
246     OSSL_CMP_PKIFREETEXT_free(ctx->statusString);
247     X509_free(ctx->newCert);
248     OSSL_STACK_OF_X509_free(ctx->newChain);
249     OSSL_STACK_OF_X509_free(ctx->caPubs);
250     OSSL_STACK_OF_X509_free(ctx->extraCertsIn);
251 
252     OPENSSL_free(ctx);
253 }
254 
255 #define DEFINE_OSSL_set(PREFIX, FIELD, TYPE) \
256 int PREFIX##_set_##FIELD(OSSL_CMP_CTX *ctx, TYPE val) \
257 { \
258     if (ctx == NULL) { \
259         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
260         return 0; \
261     } \
262     ctx->FIELD = val; \
263     return 1; \
264 }
265 
DEFINE_OSSL_set(ossl_cmp_ctx,status,int)266 DEFINE_OSSL_set(ossl_cmp_ctx, status, int)
267 
268 #define DEFINE_OSSL_get(PREFIX, FIELD, TYPE, ERR_RET) \
269 TYPE PREFIX##_get_##FIELD(const OSSL_CMP_CTX *ctx) \
270 { \
271     if (ctx == NULL) { \
272         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
273         return ERR_RET; \
274     } \
275     return ctx->FIELD; \
276 }
277 
278 /*
279  * Returns the PKIStatus from the last CertRepMessage
280  * or Revocation Response or error message, -1 on error
281  */
282 DEFINE_OSSL_get(OSSL_CMP_CTX, status, int, -1)
283 
284 /*
285  * Returns the statusString from the last CertRepMessage
286  * or Revocation Response or error message, NULL on error
287  */
288 DEFINE_OSSL_CMP_CTX_get0(statusString, OSSL_CMP_PKIFREETEXT)
289 
290 DEFINE_OSSL_set0(ossl_cmp_ctx, statusString, OSSL_CMP_PKIFREETEXT)
291 
292 /* Set callback function for checking if the cert is ok or should be rejected */
293 DEFINE_OSSL_set(OSSL_CMP_CTX, certConf_cb, OSSL_CMP_certConf_cb_t)
294 
295 /*
296  * Set argument, respectively a pointer to a structure containing arguments,
297  * optionally to be used by the certConf callback.
298  */
299 DEFINE_OSSL_set(OSSL_CMP_CTX, certConf_cb_arg, void *)
300 
301 /*
302  * Get argument, respectively the pointer to a structure containing arguments,
303  * optionally to be used by certConf callback.
304  * Returns callback argument set previously (NULL if not set or on error)
305  */
306 DEFINE_OSSL_get(OSSL_CMP_CTX, certConf_cb_arg, void *, NULL)
307 
308 #ifndef OPENSSL_NO_TRACE
309 static size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt,
310                                     int category, int cmd, void *vdata)
311 {
312     OSSL_CMP_CTX *ctx = vdata;
313     const char *msg;
314     OSSL_CMP_severity level = -1;
315     char *func = NULL;
316     char *file = NULL;
317     int line = 0;
318 
319     if (buf == NULL || cnt == 0 || cmd != OSSL_TRACE_CTRL_WRITE || ctx == NULL)
320         return 0;
321     if (ctx->log_cb == NULL)
322         return 1; /* silently drop message */
323 
324     msg = ossl_cmp_log_parse_metadata(buf, &level, &func, &file, &line);
325 
326     if (level > ctx->log_verbosity) /* excludes the case level is unknown */
327         goto end; /* suppress output since severity is not sufficient */
328 
329     if (!ctx->log_cb(func != NULL ? func : "(no func)",
330                      file != NULL ? file : "(no file)",
331                      line, level, msg))
332         cnt = 0;
333 
334  end:
335     OPENSSL_free(func);
336     OPENSSL_free(file);
337     return cnt;
338 }
339 #endif
340 
341 /* Print CMP log messages (i.e., diagnostic info) via the log cb of the ctx */
ossl_cmp_print_log(OSSL_CMP_severity level,const OSSL_CMP_CTX * ctx,const char * func,const char * file,int line,const char * level_str,const char * format,...)342 int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
343                        const char *func, const char *file, int line,
344                        const char *level_str, const char *format, ...)
345 {
346     va_list args;
347     char hugebuf[1024 * 2];
348     int res = 0;
349 
350     if (ctx == NULL || ctx->log_cb == NULL)
351         return 1; /* silently drop message */
352 
353     if (level > ctx->log_verbosity) /* excludes the case level is unknown */
354         return 1; /* suppress output since severity is not sufficient */
355 
356     if (format == NULL)
357         return 0;
358 
359     va_start(args, format);
360 
361     if (func == NULL)
362         func = "(unset function name)";
363     if (file == NULL)
364         file = "(unset file name)";
365     if (level_str == NULL)
366         level_str = "(unset level string)";
367 
368 #ifndef OPENSSL_NO_TRACE
369     if (OSSL_TRACE_ENABLED(CMP)) {
370         OSSL_TRACE_BEGIN(CMP) {
371             int printed =
372                 BIO_snprintf(hugebuf, sizeof(hugebuf),
373                              "%s:%s:%d:" OSSL_CMP_LOG_PREFIX "%s: ",
374                              func, file, line, level_str);
375             if (printed > 0 && (size_t)printed < sizeof(hugebuf)) {
376                 if (BIO_vsnprintf(hugebuf + printed,
377                                   sizeof(hugebuf) - printed, format, args) > 0)
378                     res = BIO_puts(trc_out, hugebuf) > 0;
379             }
380         } OSSL_TRACE_END(CMP);
381     }
382 #else /* compensate for disabled trace API */
383     {
384         if (BIO_vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0)
385             res = ctx->log_cb(func, file, line, level, hugebuf);
386     }
387 #endif
388     va_end(args);
389     return res;
390 }
391 
392 /* Set a callback function for error reporting and logging messages */
OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX * ctx,OSSL_CMP_log_cb_t cb)393 int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
394 {
395     if (ctx == NULL) {
396         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
397         return 0;
398     }
399     ctx->log_cb = cb;
400 
401 #ifndef OPENSSL_NO_TRACE
402     /* do also in case cb == NULL, to switch off logging output: */
403     if (!OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_CMP,
404                                  ossl_cmp_log_trace_cb, ctx))
405         return 0;
406 #endif
407 
408     return 1;
409 }
410 
411 /* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */
OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX * ctx)412 void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx)
413 {
414     if (ctx != NULL && OSSL_CMP_LOG_ERR > ctx->log_verbosity)
415         return; /* suppress output since severity is not sufficient */
416     OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb);
417 }
418 
419 /*
420  * Set or clear the reference value to be used for identification
421  * (i.e., the user name) when using PBMAC.
422  */
OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX * ctx,const unsigned char * ref,int len)423 int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
424                                      const unsigned char *ref, int len)
425 {
426     if (ctx == NULL) {
427         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
428         return 0;
429     }
430     return
431         ossl_cmp_asn1_octet_string_set1_bytes(&ctx->referenceValue, ref, len);
432 }
433 
434 /* Set or clear the password to be used for protecting messages with PBMAC */
OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX * ctx,const unsigned char * sec,int len)435 int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx,
436                                   const unsigned char *sec, int len)
437 {
438     ASN1_OCTET_STRING *secretValue = NULL;
439 
440     if (ctx == NULL) {
441         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
442         return 0;
443     }
444     if (ossl_cmp_asn1_octet_string_set1_bytes(&secretValue, sec, len) != 1)
445         return 0;
446     if (ctx->secretValue != NULL) {
447         OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
448         ASN1_OCTET_STRING_free(ctx->secretValue);
449     }
450     ctx->secretValue = secretValue;
451     return 1;
452 }
453 
454 #define DEFINE_OSSL_CMP_CTX_get1_certs(FIELD) \
455 STACK_OF(X509) *OSSL_CMP_CTX_get1_##FIELD(const OSSL_CMP_CTX *ctx) \
456 { \
457     if (ctx == NULL) { \
458         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
459         return NULL; \
460     } \
461     return X509_chain_up_ref(ctx->FIELD); \
462 }
463 
464 /* Returns the cert chain computed by OSSL_CMP_certConf_cb(), NULL on error */
465 DEFINE_OSSL_CMP_CTX_get1_certs(newChain)
466 
467 #define DEFINE_OSSL_set1_certs(PREFIX, FIELD) \
468 int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) \
469 { \
470     if (ctx == NULL) { \
471         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
472         return 0; \
473     } \
474     OSSL_STACK_OF_X509_free(ctx->FIELD); \
475     ctx->FIELD = NULL; \
476     return certs == NULL || (ctx->FIELD = X509_chain_up_ref(certs)) != NULL; \
477 }
478 
479 /*
480  * Copies any given stack of inbound X509 certificates to newChain
481  * of the OSSL_CMP_CTX structure so that they may be retrieved later.
482  */
DEFINE_OSSL_set1_certs(ossl_cmp_ctx,newChain)483 DEFINE_OSSL_set1_certs(ossl_cmp_ctx, newChain)
484 
485 /* Returns the stack of extraCerts received in CertRepMessage, NULL on error */
486 DEFINE_OSSL_CMP_CTX_get1_certs(extraCertsIn)
487 
488 /*
489  * Copies any given stack of inbound X509 certificates to extraCertsIn
490  * of the OSSL_CMP_CTX structure so that they may be retrieved later.
491  */
492 DEFINE_OSSL_set1_certs(ossl_cmp_ctx, extraCertsIn)
493 
494 /*
495  * Copies any given stack as the new stack of X509
496  * certificates to send out in the extraCerts field.
497  */
498 DEFINE_OSSL_set1_certs(OSSL_CMP_CTX, extraCertsOut)
499 
500 /*
501  * Add the given policy info object
502  * to the X509_EXTENSIONS of the requested certificate template.
503  */
504 int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
505 {
506     if (ctx == NULL || pinfo == NULL) {
507         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
508         return 0;
509     }
510 
511     if (ctx->policies == NULL
512             && (ctx->policies = CERTIFICATEPOLICIES_new()) == NULL)
513         return 0;
514 
515     return sk_POLICYINFO_push(ctx->policies, pinfo);
516 }
517 
518 /* Add an ITAV for geninfo of the PKI message header */
OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX * ctx,OSSL_CMP_ITAV * itav)519 int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
520 {
521     if (ctx == NULL) {
522         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
523         return 0;
524     }
525     return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
526 }
527 
OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX * ctx)528 int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx)
529 {
530     if (ctx == NULL) {
531         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
532         return 0;
533     }
534     OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs);
535     ctx->geninfo_ITAVs = NULL;
536     return 1;
537 }
538 
DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs,STACK_OF (OSSL_CMP_ITAV))539 DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs, STACK_OF(OSSL_CMP_ITAV))
540 
541 /* Add an itav for the body of outgoing general messages */
542 int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
543 {
544     if (ctx == NULL) {
545         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
546         return 0;
547     }
548     return OSSL_CMP_ITAV_push0_stack_item(&ctx->genm_ITAVs, itav);
549 }
550 
551 /*
552  * Returns a duplicate of the stack of X509 certificates that
553  * were received in the caPubs field of the last CertRepMessage.
554  * Returns NULL on error
555  */
556 DEFINE_OSSL_CMP_CTX_get1_certs(caPubs)
557 
558 /*
559  * Copies any given stack of certificates to the given
560  * OSSL_CMP_CTX structure so that they may be retrieved later.
561  */
DEFINE_OSSL_set1_certs(ossl_cmp_ctx,caPubs)562 DEFINE_OSSL_set1_certs(ossl_cmp_ctx, caPubs)
563 
564 #define char_dup OPENSSL_strdup
565 #define char_free OPENSSL_free
566 #define DEFINE_OSSL_CMP_CTX_set1(FIELD, TYPE) /* this uses _dup */ \
567 int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \
568 { \
569     TYPE *val_dup = NULL; \
570     \
571     if (ctx == NULL) { \
572         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
573         return 0; \
574     } \
575     \
576     if (val != NULL && (val_dup = TYPE##_dup(val)) == NULL) \
577         return 0; \
578     TYPE##_free(ctx->FIELD); \
579     ctx->FIELD = val_dup; \
580     return 1; \
581 }
582 
583 #define X509_invalid(cert) (!ossl_x509v3_cache_extensions(cert))
584 #define EVP_PKEY_invalid(key) 0
585 
586 #define DEFINE_OSSL_set1_up_ref(PREFIX, FIELD, TYPE) \
587 int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
588 { \
589     if (ctx == NULL) { \
590         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
591         return 0; \
592     } \
593     \
594     /* prevent misleading error later on malformed cert or provider issue */ \
595     if (val != NULL && TYPE##_invalid(val)) { \
596         ERR_raise(ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE); \
597         return 0; \
598     } \
599     if (val != NULL && !TYPE##_up_ref(val)) \
600         return 0; \
601     TYPE##_free(ctx->FIELD); \
602     ctx->FIELD = val; \
603     return 1; \
604 }
605 
606 DEFINE_OSSL_set1_up_ref(ossl_cmp_ctx, validatedSrvCert, X509)
607 
608 /*
609  * Pins the server certificate to be directly trusted (even if it is expired)
610  * for verifying response messages.
611  * Cert pointer is not consumed. It may be NULL to clear the entry.
612  */
613 DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, srvCert, X509)
614 
615 /* Set the X509 name of the recipient to be placed in the PKIHeader */
616 DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
617 
618 /* Store the X509 name of the expected sender in the PKIHeader of responses */
619 DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
620 
621 /* Set the X509 name of the issuer to be placed in the certTemplate */
622 DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
623 
624 /* Set the ASN1_INTEGER serial to be placed in the certTemplate for rr */
625 DEFINE_OSSL_CMP_CTX_set1(serialNumber, ASN1_INTEGER)
626 /*
627  * Set the subject name that will be placed in the certificate
628  * request. This will be the subject name on the received certificate.
629  */
630 DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
631 
632 /* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
633 int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
634 {
635     if (ctx == NULL) {
636         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
637         return 0;
638     }
639 
640     if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 && exts != NULL
641             && X509v3_get_ext_by_NID(exts, NID_subject_alt_name, -1) >= 0) {
642         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES);
643         return 0;
644     }
645     X509_EXTENSIONS_free(ctx->reqExtensions);
646     ctx->reqExtensions = exts;
647     return 1;
648 }
649 
650 /* returns 1 if ctx contains a Subject Alternative Name extension, else 0 */
OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX * ctx)651 int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
652 {
653     if (ctx == NULL) {
654         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
655         return -1;
656     }
657     /* if one of the following conditions 'fail' this is not an error */
658     return ctx->reqExtensions != NULL
659         && X509v3_get_ext_by_NID(ctx->reqExtensions,
660                                  NID_subject_alt_name, -1) >= 0;
661 }
662 
663 /*
664  * Add a GENERAL_NAME structure that will be added to the CRMF
665  * request's extensions field to request subject alternative names.
666  */
OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX * ctx,const GENERAL_NAME * name)667 int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
668                                       const GENERAL_NAME *name)
669 {
670     GENERAL_NAME *name_dup;
671 
672     if (ctx == NULL || name == NULL) {
673         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
674         return 0;
675     }
676 
677     if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) {
678         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES);
679         return 0;
680     }
681 
682     if (ctx->subjectAltNames == NULL
683             && (ctx->subjectAltNames = sk_GENERAL_NAME_new_null()) == NULL)
684         return 0;
685     if ((name_dup = GENERAL_NAME_dup(name)) == NULL)
686         return 0;
687     if (!sk_GENERAL_NAME_push(ctx->subjectAltNames, name_dup)) {
688         GENERAL_NAME_free(name_dup);
689         return 0;
690     }
691     return 1;
692 }
693 
694 /*
695  * Set our own client certificate, used for example in KUR and when
696  * doing the IR with existing certificate.
697  */
DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX,cert,X509)698 DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, cert, X509)
699 
700 int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted,
701                                   STACK_OF(X509) *candidates)
702 {
703     STACK_OF(X509) *chain;
704 
705     if (ctx == NULL) {
706         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
707         return 0;
708     }
709 
710     if (!ossl_x509_add_certs_new(&ctx->untrusted, candidates,
711                                  X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
712         return 0;
713 
714     ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert");
715     chain = X509_build_chain(ctx->cert, ctx->untrusted, own_trusted, 0,
716                              ctx->libctx, ctx->propq);
717     if (chain == NULL) {
718         ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN);
719         return 0;
720     }
721     ossl_cmp_debug(ctx, "success building chain for own CMP signer cert");
722     ctx->chain = chain;
723     return 1;
724 }
725 
726 /*
727  * Set the old certificate that we are updating in KUR
728  * or the certificate to be revoked in RR, respectively.
729  * Also used as reference cert (defaulting to cert) for deriving subject DN
730  * and SANs. Its issuer is used as default recipient in the CMP message header.
731  */
DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX,oldCert,X509)732 DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, oldCert, X509)
733 
734 /* Set the PKCS#10 CSR to be sent in P10CR */
735 DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
736 
737 /*
738  * Set the (newly received in IP/KUP/CP) certificate in the context.
739  * This only permits for one cert to be enrolled at a time.
740  */
741 DEFINE_OSSL_set0(ossl_cmp_ctx, newCert, X509)
742 
743 /* Get successfully validated server cert, if any, of current transaction */
744 DEFINE_OSSL_CMP_CTX_get0(validatedSrvCert, X509)
745 
746 /*
747  * Get the (newly received in IP/KUP/CP) client certificate from the context
748  * This only permits for one client cert to be received...
749  */
750 DEFINE_OSSL_CMP_CTX_get0(newCert, X509)
751 
752 /* Set the client's current private key */
753 DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, pkey, EVP_PKEY)
754 
755 /* Set new key pair. Used e.g. when doing Key Update */
756 int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
757 {
758     if (ctx == NULL) {
759         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
760         return 0;
761     }
762 
763     EVP_PKEY_free(ctx->newPkey);
764     ctx->newPkey = pkey;
765     ctx->newPkey_priv = priv;
766     return 1;
767 }
768 
769 /* Get the private/public key to use for cert enrollment, or NULL on error */
770 /* In case |priv| == 0, better use ossl_cmp_ctx_get0_newPubkey() below */
OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX * ctx,int priv)771 EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
772 {
773     if (ctx == NULL) {
774         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
775         return NULL;
776     }
777 
778     if (ctx->newPkey != NULL)
779         return priv && !ctx->newPkey_priv ? NULL : ctx->newPkey;
780     if (ctx->p10CSR != NULL)
781         return priv ? NULL : X509_REQ_get0_pubkey(ctx->p10CSR);
782     return ctx->pkey; /* may be NULL */
783 }
784 
ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX * ctx)785 EVP_PKEY *ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX *ctx)
786 {
787     if (!ossl_assert(ctx != NULL))
788         return NULL;
789     if (ctx->newPkey != NULL)
790         return ctx->newPkey;
791     if (ctx->p10CSR != NULL)
792         return X509_REQ_get0_pubkey(ctx->p10CSR);
793     if (ctx->oldCert != NULL)
794         return X509_get0_pubkey(ctx->oldCert);
795     if (ctx->cert != NULL)
796         return X509_get0_pubkey(ctx->cert);
797     return ctx->pkey;
798 }
799 
800 #define DEFINE_set1_ASN1_OCTET_STRING(PREFIX, FIELD) \
801 int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *id) \
802 { \
803     if (ctx == NULL) { \
804         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
805         return 0; \
806     } \
807     return ossl_cmp_asn1_octet_string_set1(&ctx->FIELD, id); \
808 }
809 
810 /* Set the given transactionID to the context */
DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX,transactionID)811 DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, transactionID)
812 
813 /* Set the nonce to be used for the recipNonce in the message created next */
814 DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, recipNonce)
815 
816 /* Stores the given nonce as the last senderNonce sent out */
817 DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, senderNonce)
818 
819 /* store the first req sender nonce for verifying delayed delivery */
820 DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, first_senderNonce)
821 
822 /* Set the proxy server to use for HTTP(S) connections */
823 DEFINE_OSSL_CMP_CTX_set1(proxy, char)
824 
825 /* Set the (HTTP) hostname of the CMP server */
826 DEFINE_OSSL_CMP_CTX_set1(server, char)
827 
828 /* Set the server exclusion list of the HTTP proxy server */
829 DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
830 
831 #ifndef OPENSSL_NO_HTTP
832 /* Set the http connect/disconnect callback function to be used for HTTP(S) */
833 DEFINE_OSSL_set(OSSL_CMP_CTX, http_cb, OSSL_HTTP_bio_cb_t)
834 
835 /* Set argument optionally to be used by the http connect/disconnect callback */
836 DEFINE_OSSL_set(OSSL_CMP_CTX, http_cb_arg, void *)
837 
838 /*
839  * Get argument optionally to be used by the http connect/disconnect callback
840  * Returns callback argument set previously (NULL if not set or on error)
841  */
842 DEFINE_OSSL_get(OSSL_CMP_CTX, http_cb_arg, void *, NULL)
843 #endif
844 
845 /* Set callback function for sending CMP request and receiving response */
846 DEFINE_OSSL_set(OSSL_CMP_CTX, transfer_cb, OSSL_CMP_transfer_cb_t)
847 
848 /* Set argument optionally to be used by the transfer callback */
849 DEFINE_OSSL_set(OSSL_CMP_CTX, transfer_cb_arg, void *)
850 
851 /*
852  * Get argument optionally to be used by the transfer callback.
853  * Returns callback argument set previously (NULL if not set or on error)
854  */
855 DEFINE_OSSL_get(OSSL_CMP_CTX, transfer_cb_arg, void *, NULL)
856 
857 /** Set the HTTP server port to be used */
858 DEFINE_OSSL_set(OSSL_CMP_CTX, serverPort, int)
859 
860 /* Set the HTTP path to be used on the server (e.g "pkix/") */
861 DEFINE_OSSL_CMP_CTX_set1(serverPath, char)
862 
863 /* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
864 DEFINE_OSSL_set(ossl_cmp_ctx, failInfoCode, int)
865 
866 /*
867  * Get the failInfo error code in OSSL_CMP_CTX as bit encoding.
868  * Returns bit string as integer on success, -1 on error
869  */
870 DEFINE_OSSL_get(OSSL_CMP_CTX, failInfoCode, int, -1)
871 
872 /* Set a Boolean or integer option of the context to the "val" arg */
873 int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
874 {
875     int min_val;
876 
877     if (ctx == NULL) {
878         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
879         return 0;
880     }
881 
882     switch (opt) {
883     case OSSL_CMP_OPT_REVOCATION_REASON:
884         min_val = OCSP_REVOKED_STATUS_NOSTATUS;
885         break;
886     case OSSL_CMP_OPT_POPO_METHOD:
887         min_val = OSSL_CRMF_POPO_NONE;
888         break;
889     default:
890         min_val = 0;
891         break;
892     }
893     if (val < min_val) {
894         ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_SMALL);
895         return 0;
896     }
897 
898     switch (opt) {
899     case OSSL_CMP_OPT_LOG_VERBOSITY:
900         if (val > OSSL_CMP_LOG_MAX) {
901             ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
902             return 0;
903         }
904         ctx->log_verbosity = val;
905         break;
906     case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
907         ctx->implicitConfirm = val;
908         break;
909     case OSSL_CMP_OPT_DISABLE_CONFIRM:
910         ctx->disableConfirm = val;
911         break;
912     case OSSL_CMP_OPT_UNPROTECTED_SEND:
913         ctx->unprotectedSend = val;
914         break;
915     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
916         ctx->unprotectedErrors = val;
917         break;
918     case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS:
919         ctx->noCacheExtraCerts = val;
920         break;
921     case OSSL_CMP_OPT_VALIDITY_DAYS:
922         ctx->days = val;
923         break;
924     case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
925         ctx->SubjectAltName_nodefault = val;
926         break;
927     case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL:
928         ctx->setSubjectAltNameCritical = val;
929         break;
930     case OSSL_CMP_OPT_POLICIES_CRITICAL:
931         ctx->setPoliciesCritical = val;
932         break;
933     case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
934         ctx->ignore_keyusage = val;
935         break;
936     case OSSL_CMP_OPT_POPO_METHOD:
937         if (val > OSSL_CRMF_POPO_KEYAGREE) {
938             ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
939             return 0;
940         }
941         ctx->popoMethod = val;
942         break;
943     case OSSL_CMP_OPT_DIGEST_ALGNID:
944         if (!cmp_ctx_set_md(ctx, &ctx->digest, val))
945             return 0;
946         break;
947     case OSSL_CMP_OPT_OWF_ALGNID:
948         if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val))
949             return 0;
950         break;
951     case OSSL_CMP_OPT_MAC_ALGNID:
952         ctx->pbm_mac = val;
953         break;
954     case OSSL_CMP_OPT_KEEP_ALIVE:
955         ctx->keep_alive = val;
956         break;
957     case OSSL_CMP_OPT_MSG_TIMEOUT:
958         ctx->msg_timeout = val;
959         break;
960     case OSSL_CMP_OPT_TOTAL_TIMEOUT:
961         ctx->total_timeout = val;
962         break;
963     case OSSL_CMP_OPT_USE_TLS:
964         ctx->tls_used = val;
965         break;
966     case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
967         ctx->permitTAInExtraCertsForIR = val;
968         break;
969     case OSSL_CMP_OPT_REVOCATION_REASON:
970         if (val > OCSP_REVOKED_STATUS_AACOMPROMISE) {
971             ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
972             return 0;
973         }
974         ctx->revocationReason = val;
975         break;
976     default:
977         ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION);
978         return 0;
979     }
980 
981     return 1;
982 }
983 
984 /*
985  * Reads a Boolean or integer option value from the context.
986  * Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON)
987  */
OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX * ctx,int opt)988 int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
989 {
990     if (ctx == NULL) {
991         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
992         return -1;
993     }
994 
995     switch (opt) {
996     case OSSL_CMP_OPT_LOG_VERBOSITY:
997         return ctx->log_verbosity;
998     case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
999         return ctx->implicitConfirm;
1000     case OSSL_CMP_OPT_DISABLE_CONFIRM:
1001         return ctx->disableConfirm;
1002     case OSSL_CMP_OPT_UNPROTECTED_SEND:
1003         return ctx->unprotectedSend;
1004     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
1005         return ctx->unprotectedErrors;
1006     case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS:
1007         return ctx->noCacheExtraCerts;
1008     case OSSL_CMP_OPT_VALIDITY_DAYS:
1009         return ctx->days;
1010     case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
1011         return ctx->SubjectAltName_nodefault;
1012     case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL:
1013         return ctx->setSubjectAltNameCritical;
1014     case OSSL_CMP_OPT_POLICIES_CRITICAL:
1015         return ctx->setPoliciesCritical;
1016     case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
1017         return ctx->ignore_keyusage;
1018     case OSSL_CMP_OPT_POPO_METHOD:
1019         return ctx->popoMethod;
1020     case OSSL_CMP_OPT_DIGEST_ALGNID:
1021         return EVP_MD_get_type(ctx->digest);
1022     case OSSL_CMP_OPT_OWF_ALGNID:
1023         return EVP_MD_get_type(ctx->pbm_owf);
1024     case OSSL_CMP_OPT_MAC_ALGNID:
1025         return ctx->pbm_mac;
1026     case OSSL_CMP_OPT_KEEP_ALIVE:
1027         return ctx->keep_alive;
1028     case OSSL_CMP_OPT_MSG_TIMEOUT:
1029         return ctx->msg_timeout;
1030     case OSSL_CMP_OPT_TOTAL_TIMEOUT:
1031         return ctx->total_timeout;
1032     case OSSL_CMP_OPT_USE_TLS:
1033         return ctx->tls_used;
1034     case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
1035         return ctx->permitTAInExtraCertsForIR;
1036     case OSSL_CMP_OPT_REVOCATION_REASON:
1037         return ctx->revocationReason;
1038     default:
1039         ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION);
1040         return -1;
1041     }
1042 }
1043