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