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