Coverage Report

Created: 2025-12-31 06:58

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