xref: /freebsd/crypto/openssl/crypto/cmp/cmp_ctx.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
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         {
372             int printed = 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)
378                     > 0)
379                     res = BIO_puts(trc_out, hugebuf) > 0;
380             }
381         }
382         OSSL_TRACE_END(CMP);
383     }
384 #else /* compensate for disabled trace API */
385     {
386         if (BIO_vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0)
387             res = ctx->log_cb(func, file, line, level, hugebuf);
388     }
389 #endif
390     va_end(args);
391     return res;
392 }
393 
394 /* 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)395 int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
396 {
397     if (ctx == NULL) {
398         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
399         return 0;
400     }
401     ctx->log_cb = cb;
402 
403 #ifndef OPENSSL_NO_TRACE
404     /* do also in case cb == NULL, to switch off logging output: */
405     if (!OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_CMP,
406             ossl_cmp_log_trace_cb, ctx))
407         return 0;
408 #endif
409 
410     return 1;
411 }
412 
413 /* 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)414 void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx)
415 {
416     if (ctx != NULL && OSSL_CMP_LOG_ERR > ctx->log_verbosity)
417         return; /* suppress output since severity is not sufficient */
418     OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb);
419 }
420 
421 /*
422  * Set or clear the reference value to be used for identification
423  * (i.e., the user name) when using PBMAC.
424  */
OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX * ctx,const unsigned char * ref,int len)425 int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
426     const unsigned char *ref, int len)
427 {
428     if (ctx == NULL) {
429         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
430         return 0;
431     }
432     return ossl_cmp_asn1_octet_string_set1_bytes(&ctx->referenceValue, ref, len);
433 }
434 
435 /* 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)436 int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx,
437     const unsigned char *sec, int len)
438 {
439     ASN1_OCTET_STRING *secretValue = NULL;
440 
441     if (ctx == NULL) {
442         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
443         return 0;
444     }
445     if (ossl_cmp_asn1_octet_string_set1_bytes(&secretValue, sec, len) != 1)
446         return 0;
447     if (ctx->secretValue != NULL) {
448         OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
449         ASN1_OCTET_STRING_free(ctx->secretValue);
450     }
451     ctx->secretValue = secretValue;
452     return 1;
453 }
454 
455 #define DEFINE_OSSL_CMP_CTX_get1_certs(FIELD)                          \
456     STACK_OF(X509) *OSSL_CMP_CTX_get1_##FIELD(const OSSL_CMP_CTX *ctx) \
457     {                                                                  \
458         if (ctx == NULL) {                                             \
459             ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);               \
460             return NULL;                                               \
461         }                                                              \
462         return X509_chain_up_ref(ctx->FIELD);                          \
463     }
464 
465 /* Returns the cert chain computed by OSSL_CMP_certConf_cb(), NULL on error */
466 DEFINE_OSSL_CMP_CTX_get1_certs(newChain)
467 
468 #define DEFINE_OSSL_set1_certs(PREFIX, FIELD)                                    \
469     int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)          \
470     {                                                                            \
471         if (ctx == NULL) {                                                       \
472             ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);                         \
473             return 0;                                                            \
474         }                                                                        \
475         OSSL_STACK_OF_X509_free(ctx->FIELD);                                     \
476         ctx->FIELD = NULL;                                                       \
477         return certs == NULL || (ctx->FIELD = X509_chain_up_ref(certs)) != NULL; \
478     }
479 
480     /*
481      * Copies any given stack of inbound X509 certificates to newChain
482      * of the OSSL_CMP_CTX structure so that they may be retrieved later.
483      */
DEFINE_OSSL_set1_certs(ossl_cmp_ctx,newChain)484     DEFINE_OSSL_set1_certs(ossl_cmp_ctx, newChain)
485 
486     /* Returns the stack of extraCerts received in CertRepMessage, NULL on error */
487     DEFINE_OSSL_CMP_CTX_get1_certs(extraCertsIn)
488 
489     /*
490      * Copies any given stack of inbound X509 certificates to extraCertsIn
491      * of the OSSL_CMP_CTX structure so that they may be retrieved later.
492      */
493     DEFINE_OSSL_set1_certs(ossl_cmp_ctx, extraCertsIn)
494 
495     /*
496      * Copies any given stack as the new stack of X509
497      * certificates to send out in the extraCerts field.
498      */
499     DEFINE_OSSL_set1_certs(OSSL_CMP_CTX, extraCertsOut)
500 
501     /*
502      * Add the given policy info object
503      * to the X509_EXTENSIONS of the requested certificate template.
504      */
505     int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
506 {
507     if (ctx == NULL || pinfo == NULL) {
508         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
509         return 0;
510     }
511 
512     if (ctx->policies == NULL
513         && (ctx->policies = CERTIFICATEPOLICIES_new()) == NULL)
514         return 0;
515 
516     return sk_POLICYINFO_push(ctx->policies, pinfo);
517 }
518 
519 /* Add an ITAV for geninfo of the PKI message header */
OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX * ctx,OSSL_CMP_ITAV * itav)520 int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
521 {
522     if (ctx == NULL) {
523         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
524         return 0;
525     }
526     return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
527 }
528 
OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX * ctx)529 int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx)
530 {
531     if (ctx == NULL) {
532         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
533         return 0;
534     }
535     OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs);
536     ctx->geninfo_ITAVs = NULL;
537     return 1;
538 }
539 
DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs,STACK_OF (OSSL_CMP_ITAV))540 DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs, STACK_OF(OSSL_CMP_ITAV))
541 
542     /* Add an itav for the body of outgoing general messages */
543     int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
544 {
545     if (ctx == NULL) {
546         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
547         return 0;
548     }
549     return OSSL_CMP_ITAV_push0_stack_item(&ctx->genm_ITAVs, itav);
550 }
551 
552 /*
553  * Returns a duplicate of the stack of X509 certificates that
554  * were received in the caPubs field of the last CertRepMessage.
555  * Returns NULL on error
556  */
557 DEFINE_OSSL_CMP_CTX_get1_certs(caPubs)
558 
559     /*
560      * Copies any given stack of certificates to the given
561      * OSSL_CMP_CTX structure so that they may be retrieved later.
562      */
DEFINE_OSSL_set1_certs(ossl_cmp_ctx,caPubs)563     DEFINE_OSSL_set1_certs(ossl_cmp_ctx, caPubs)
564 
565 #define char_dup OPENSSL_strdup
566 #define char_free OPENSSL_free
567 #define DEFINE_OSSL_CMP_CTX_set1(FIELD, TYPE) /* this uses _dup */    \
568     int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \
569     {                                                                 \
570         TYPE *val_dup = NULL;                                         \
571                                                                       \
572         if (ctx == NULL) {                                            \
573             ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);              \
574             return 0;                                                 \
575         }                                                             \
576                                                                       \
577         if (val != NULL && (val_dup = TYPE##_dup(val)) == NULL)       \
578             return 0;                                                 \
579         TYPE##_free(ctx->FIELD);                                      \
580         ctx->FIELD = val_dup;                                         \
581         return 1;                                                     \
582     }
583 
584 #define X509_invalid(cert) (!ossl_x509v3_cache_extensions(cert))
585 #define EVP_PKEY_invalid(key) 0
586 
587 #define DEFINE_OSSL_set1_up_ref(PREFIX, FIELD, TYPE)                             \
588     int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val)                      \
589     {                                                                            \
590         if (ctx == NULL) {                                                       \
591             ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);                         \
592             return 0;                                                            \
593         }                                                                        \
594                                                                                  \
595         /* prevent misleading error later on malformed cert or provider issue */ \
596         if (val != NULL && TYPE##_invalid(val)) {                                \
597             ERR_raise(ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE);       \
598             return 0;                                                            \
599         }                                                                        \
600         if (val != NULL && !TYPE##_up_ref(val))                                  \
601             return 0;                                                            \
602         TYPE##_free(ctx->FIELD);                                                 \
603         ctx->FIELD = val;                                                        \
604         return 1;                                                                \
605     }
606 
607         DEFINE_OSSL_set1_up_ref(ossl_cmp_ctx, validatedSrvCert, X509)
608 
609     /*
610      * Pins the server certificate to be directly trusted (even if it is expired)
611      * for verifying response messages.
612      * Cert pointer is not consumed. It may be NULL to clear the entry.
613      */
614     DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, srvCert, X509)
615 
616     /* Set the X509 name of the recipient to be placed in the PKIHeader */
617     DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
618 
619     /* Store the X509 name of the expected sender in the PKIHeader of responses */
620     DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
621 
622     /* Set the X509 name of the issuer to be placed in the certTemplate */
623     DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
624 
625     /* Set the ASN1_INTEGER serial to be placed in the certTemplate for rr */
626     DEFINE_OSSL_CMP_CTX_set1(serialNumber, ASN1_INTEGER)
627     /*
628      * Set the subject name that will be placed in the certificate
629      * request. This will be the subject name on the received certificate.
630      */
631     DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
632 
633     /* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
634     int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
635 {
636     if (ctx == NULL) {
637         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
638         return 0;
639     }
640 
641     if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 && exts != NULL
642         && X509v3_get_ext_by_NID(exts, NID_subject_alt_name, -1) >= 0) {
643         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES);
644         return 0;
645     }
646     X509_EXTENSIONS_free(ctx->reqExtensions);
647     ctx->reqExtensions = exts;
648     return 1;
649 }
650 
651 /* returns 1 if ctx contains a Subject Alternative Name extension, else 0 */
OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX * ctx)652 int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
653 {
654     if (ctx == NULL) {
655         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
656         return -1;
657     }
658     /* if one of the following conditions 'fail' this is not an error */
659     return ctx->reqExtensions != NULL
660         && X509v3_get_ext_by_NID(ctx->reqExtensions,
661                NID_subject_alt_name, -1)
662         >= 0;
663 }
664 
665 /*
666  * Add a GENERAL_NAME structure that will be added to the CRMF
667  * request's extensions field to request subject alternative names.
668  */
OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX * ctx,const GENERAL_NAME * name)669 int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
670     const GENERAL_NAME *name)
671 {
672     GENERAL_NAME *name_dup;
673 
674     if (ctx == NULL || name == NULL) {
675         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
676         return 0;
677     }
678 
679     if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) {
680         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES);
681         return 0;
682     }
683 
684     if (ctx->subjectAltNames == NULL
685         && (ctx->subjectAltNames = sk_GENERAL_NAME_new_null()) == NULL)
686         return 0;
687     if ((name_dup = GENERAL_NAME_dup(name)) == NULL)
688         return 0;
689     if (!sk_GENERAL_NAME_push(ctx->subjectAltNames, name_dup)) {
690         GENERAL_NAME_free(name_dup);
691         return 0;
692     }
693     return 1;
694 }
695 
696 /*
697  * Set our own client certificate, used for example in KUR and when
698  * doing the IR with existing certificate.
699  */
DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX,cert,X509)700 DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, cert, X509)
701 
702     int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted,
703         STACK_OF(X509) *candidates)
704 {
705     STACK_OF(X509) *chain;
706 
707     if (ctx == NULL) {
708         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
709         return 0;
710     }
711 
712     if (!ossl_x509_add_certs_new(&ctx->untrusted, candidates,
713             X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
714         return 0;
715 
716     ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert");
717     chain = X509_build_chain(ctx->cert, ctx->untrusted, own_trusted, 0,
718         ctx->libctx, ctx->propq);
719     if (chain == NULL) {
720         ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN);
721         return 0;
722     }
723     ossl_cmp_debug(ctx, "success building chain for own CMP signer cert");
724     ctx->chain = chain;
725     return 1;
726 }
727 
728 /*
729  * Set the old certificate that we are updating in KUR
730  * or the certificate to be revoked in RR, respectively.
731  * Also used as reference cert (defaulting to cert) for deriving subject DN
732  * and SANs. Its issuer is used as default recipient in the CMP message header.
733  */
DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX,oldCert,X509)734 DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, oldCert, X509)
735 
736     /* Set the PKCS#10 CSR to be sent in P10CR */
737     DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
738 
739     /*
740      * Set the (newly received in IP/KUP/CP) certificate in the context.
741      * This only permits for one cert to be enrolled at a time.
742      */
743     DEFINE_OSSL_set0(ossl_cmp_ctx, newCert, X509)
744 
745     /* Get successfully validated server cert, if any, of current transaction */
746     DEFINE_OSSL_CMP_CTX_get0(validatedSrvCert, X509)
747 
748     /*
749      * Get the (newly received in IP/KUP/CP) client certificate from the context
750      * This only permits for one client cert to be received...
751      */
752     DEFINE_OSSL_CMP_CTX_get0(newCert, X509)
753 
754     /* Set the client's current private key */
755     DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, pkey, EVP_PKEY)
756 
757     /* Set new key pair. Used e.g. when doing Key Update */
758     int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
759 {
760     if (ctx == NULL) {
761         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
762         return 0;
763     }
764 
765     EVP_PKEY_free(ctx->newPkey);
766     ctx->newPkey = pkey;
767     ctx->newPkey_priv = priv;
768     return 1;
769 }
770 
771 /* Get the private/public key to use for cert enrollment, or NULL on error */
772 /* In case |priv| == 0, better use ossl_cmp_ctx_get0_newPubkey() below */
OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX * ctx,int priv)773 EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
774 {
775     if (ctx == NULL) {
776         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
777         return NULL;
778     }
779 
780     if (ctx->newPkey != NULL)
781         return priv && !ctx->newPkey_priv ? NULL : ctx->newPkey;
782     if (ctx->p10CSR != NULL)
783         return priv ? NULL : X509_REQ_get0_pubkey(ctx->p10CSR);
784     return ctx->pkey; /* may be NULL */
785 }
786 
ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX * ctx)787 EVP_PKEY *ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX *ctx)
788 {
789     if (!ossl_assert(ctx != NULL))
790         return NULL;
791     if (ctx->newPkey != NULL)
792         return ctx->newPkey;
793     if (ctx->p10CSR != NULL)
794         return X509_REQ_get0_pubkey(ctx->p10CSR);
795     if (ctx->oldCert != NULL)
796         return X509_get0_pubkey(ctx->oldCert);
797     if (ctx->cert != NULL)
798         return X509_get0_pubkey(ctx->cert);
799     return ctx->pkey;
800 }
801 
802 #define DEFINE_set1_ASN1_OCTET_STRING(PREFIX, FIELD)                          \
803     int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *id) \
804     {                                                                         \
805         if (ctx == NULL) {                                                    \
806             ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);                      \
807             return 0;                                                         \
808         }                                                                     \
809         return ossl_cmp_asn1_octet_string_set1(&ctx->FIELD, id);              \
810     }
811 
812 /* Set the given transactionID to the context */
DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX,transactionID)813 DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, transactionID)
814 
815     /* Set the nonce to be used for the recipNonce in the message created next */
816     DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, recipNonce)
817 
818     /* Stores the given nonce as the last senderNonce sent out */
819     DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, senderNonce)
820 
821     /* store the first req sender nonce for verifying delayed delivery */
822     DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, first_senderNonce)
823 
824     /* Set the proxy server to use for HTTP(S) connections */
825     DEFINE_OSSL_CMP_CTX_set1(proxy, char)
826 
827     /* Set the (HTTP) hostname of the CMP server */
828     DEFINE_OSSL_CMP_CTX_set1(server, char)
829 
830     /* Set the server exclusion list of the HTTP proxy server */
831     DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
832 
833 #ifndef OPENSSL_NO_HTTP
834     /* Set the http connect/disconnect callback function to be used for HTTP(S) */
835     DEFINE_OSSL_set(OSSL_CMP_CTX, http_cb, OSSL_HTTP_bio_cb_t)
836 
837     /* Set argument optionally to be used by the http connect/disconnect callback */
838     DEFINE_OSSL_set(OSSL_CMP_CTX, http_cb_arg, void *)
839 
840     /*
841      * Get argument optionally to be used by the http connect/disconnect callback
842      * Returns callback argument set previously (NULL if not set or on error)
843      */
844     DEFINE_OSSL_get(OSSL_CMP_CTX, http_cb_arg, void *, NULL)
845 #endif
846 
847     /* Set callback function for sending CMP request and receiving response */
848     DEFINE_OSSL_set(OSSL_CMP_CTX, transfer_cb, OSSL_CMP_transfer_cb_t)
849 
850     /* Set argument optionally to be used by the transfer callback */
851     DEFINE_OSSL_set(OSSL_CMP_CTX, transfer_cb_arg, void *)
852 
853     /*
854      * Get argument optionally to be used by the transfer callback.
855      * Returns callback argument set previously (NULL if not set or on error)
856      */
857     DEFINE_OSSL_get(OSSL_CMP_CTX, transfer_cb_arg, void *, NULL)
858 
859     /** Set the HTTP server port to be used */
860     DEFINE_OSSL_set(OSSL_CMP_CTX, serverPort, int)
861 
862     /* Set the HTTP path to be used on the server (e.g "pkix/") */
863     DEFINE_OSSL_CMP_CTX_set1(serverPath, char)
864 
865     /* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
866     DEFINE_OSSL_set(ossl_cmp_ctx, failInfoCode, int)
867 
868     /*
869      * Get the failInfo error code in OSSL_CMP_CTX as bit encoding.
870      * Returns bit string as integer on success, -1 on error
871      */
872     DEFINE_OSSL_get(OSSL_CMP_CTX, failInfoCode, int, -1)
873 
874     /* Set a Boolean or integer option of the context to the "val" arg */
875     int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
876 {
877     int min_val;
878 
879     if (ctx == NULL) {
880         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
881         return 0;
882     }
883 
884     switch (opt) {
885     case OSSL_CMP_OPT_REVOCATION_REASON:
886         min_val = OCSP_REVOKED_STATUS_NOSTATUS;
887         break;
888     case OSSL_CMP_OPT_POPO_METHOD:
889         min_val = OSSL_CRMF_POPO_NONE;
890         break;
891     default:
892         min_val = 0;
893         break;
894     }
895     if (val < min_val) {
896         ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_SMALL);
897         return 0;
898     }
899 
900     switch (opt) {
901     case OSSL_CMP_OPT_LOG_VERBOSITY:
902         if (val > OSSL_CMP_LOG_MAX) {
903             ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
904             return 0;
905         }
906         ctx->log_verbosity = val;
907         break;
908     case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
909         ctx->implicitConfirm = val;
910         break;
911     case OSSL_CMP_OPT_DISABLE_CONFIRM:
912         ctx->disableConfirm = val;
913         break;
914     case OSSL_CMP_OPT_UNPROTECTED_SEND:
915         ctx->unprotectedSend = val;
916         break;
917     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
918         ctx->unprotectedErrors = val;
919         break;
920     case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS:
921         ctx->noCacheExtraCerts = val;
922         break;
923     case OSSL_CMP_OPT_VALIDITY_DAYS:
924         ctx->days = val;
925         break;
926     case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
927         ctx->SubjectAltName_nodefault = val;
928         break;
929     case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL:
930         ctx->setSubjectAltNameCritical = val;
931         break;
932     case OSSL_CMP_OPT_POLICIES_CRITICAL:
933         ctx->setPoliciesCritical = val;
934         break;
935     case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
936         ctx->ignore_keyusage = val;
937         break;
938     case OSSL_CMP_OPT_POPO_METHOD:
939         if (val > OSSL_CRMF_POPO_KEYAGREE) {
940             ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
941             return 0;
942         }
943         ctx->popoMethod = val;
944         break;
945     case OSSL_CMP_OPT_DIGEST_ALGNID:
946         if (!cmp_ctx_set_md(ctx, &ctx->digest, val))
947             return 0;
948         break;
949     case OSSL_CMP_OPT_OWF_ALGNID:
950         if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val))
951             return 0;
952         break;
953     case OSSL_CMP_OPT_MAC_ALGNID:
954         ctx->pbm_mac = val;
955         break;
956     case OSSL_CMP_OPT_KEEP_ALIVE:
957         ctx->keep_alive = val;
958         break;
959     case OSSL_CMP_OPT_MSG_TIMEOUT:
960         ctx->msg_timeout = val;
961         break;
962     case OSSL_CMP_OPT_TOTAL_TIMEOUT:
963         ctx->total_timeout = val;
964         break;
965     case OSSL_CMP_OPT_USE_TLS:
966         ctx->tls_used = val;
967         break;
968     case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
969         ctx->permitTAInExtraCertsForIR = val;
970         break;
971     case OSSL_CMP_OPT_REVOCATION_REASON:
972         if (val > OCSP_REVOKED_STATUS_AACOMPROMISE) {
973             ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE);
974             return 0;
975         }
976         ctx->revocationReason = val;
977         break;
978     default:
979         ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION);
980         return 0;
981     }
982 
983     return 1;
984 }
985 
986 /*
987  * Reads a Boolean or integer option value from the context.
988  * Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON)
989  */
OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX * ctx,int opt)990 int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
991 {
992     if (ctx == NULL) {
993         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
994         return -1;
995     }
996 
997     switch (opt) {
998     case OSSL_CMP_OPT_LOG_VERBOSITY:
999         return ctx->log_verbosity;
1000     case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
1001         return ctx->implicitConfirm;
1002     case OSSL_CMP_OPT_DISABLE_CONFIRM:
1003         return ctx->disableConfirm;
1004     case OSSL_CMP_OPT_UNPROTECTED_SEND:
1005         return ctx->unprotectedSend;
1006     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
1007         return ctx->unprotectedErrors;
1008     case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS:
1009         return ctx->noCacheExtraCerts;
1010     case OSSL_CMP_OPT_VALIDITY_DAYS:
1011         return ctx->days;
1012     case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
1013         return ctx->SubjectAltName_nodefault;
1014     case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL:
1015         return ctx->setSubjectAltNameCritical;
1016     case OSSL_CMP_OPT_POLICIES_CRITICAL:
1017         return ctx->setPoliciesCritical;
1018     case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
1019         return ctx->ignore_keyusage;
1020     case OSSL_CMP_OPT_POPO_METHOD:
1021         return ctx->popoMethod;
1022     case OSSL_CMP_OPT_DIGEST_ALGNID:
1023         return EVP_MD_get_type(ctx->digest);
1024     case OSSL_CMP_OPT_OWF_ALGNID:
1025         return EVP_MD_get_type(ctx->pbm_owf);
1026     case OSSL_CMP_OPT_MAC_ALGNID:
1027         return ctx->pbm_mac;
1028     case OSSL_CMP_OPT_KEEP_ALIVE:
1029         return ctx->keep_alive;
1030     case OSSL_CMP_OPT_MSG_TIMEOUT:
1031         return ctx->msg_timeout;
1032     case OSSL_CMP_OPT_TOTAL_TIMEOUT:
1033         return ctx->total_timeout;
1034     case OSSL_CMP_OPT_USE_TLS:
1035         return ctx->tls_used;
1036     case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
1037         return ctx->permitTAInExtraCertsForIR;
1038     case OSSL_CMP_OPT_REVOCATION_REASON:
1039         return ctx->revocationReason;
1040     default:
1041         ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION);
1042         return -1;
1043     }
1044 }
1045