Branch data Line data Source code
1 : : /* crypto/ts/ts_conf.c */
2 : : /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 : : * project 2002.
4 : : */
5 : : /* ====================================================================
6 : : * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : *
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer.
14 : : *
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in
17 : : * the documentation and/or other materials provided with the
18 : : * distribution.
19 : : *
20 : : * 3. All advertising materials mentioning features or use of this
21 : : * software must display the following acknowledgment:
22 : : * "This product includes software developed by the OpenSSL Project
23 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 : : *
25 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 : : * endorse or promote products derived from this software without
27 : : * prior written permission. For written permission, please contact
28 : : * licensing@OpenSSL.org.
29 : : *
30 : : * 5. Products derived from this software may not be called "OpenSSL"
31 : : * nor may "OpenSSL" appear in their names without prior written
32 : : * permission of the OpenSSL Project.
33 : : *
34 : : * 6. Redistributions of any form whatsoever must retain the following
35 : : * acknowledgment:
36 : : * "This product includes software developed by the OpenSSL Project
37 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 : : *
39 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
51 : : * ====================================================================
52 : : *
53 : : * This product includes cryptographic software written by Eric Young
54 : : * (eay@cryptsoft.com). This product includes software written by Tim
55 : : * Hudson (tjh@cryptsoft.com).
56 : : *
57 : : */
58 : :
59 : : #include <string.h>
60 : :
61 : : #include <openssl/crypto.h>
62 : : #include "cryptlib.h"
63 : : #include <openssl/pem.h>
64 : : #ifndef OPENSSL_NO_ENGINE
65 : : #include <openssl/engine.h>
66 : : #endif
67 : : #include <openssl/ts.h>
68 : :
69 : : /* Macro definitions for the configuration file. */
70 : :
71 : : #define BASE_SECTION "tsa"
72 : : #define ENV_DEFAULT_TSA "default_tsa"
73 : : #define ENV_SERIAL "serial"
74 : : #define ENV_CRYPTO_DEVICE "crypto_device"
75 : : #define ENV_SIGNER_CERT "signer_cert"
76 : : #define ENV_CERTS "certs"
77 : : #define ENV_SIGNER_KEY "signer_key"
78 : : #define ENV_DEFAULT_POLICY "default_policy"
79 : : #define ENV_OTHER_POLICIES "other_policies"
80 : : #define ENV_DIGESTS "digests"
81 : : #define ENV_ACCURACY "accuracy"
82 : : #define ENV_ORDERING "ordering"
83 : : #define ENV_TSA_NAME "tsa_name"
84 : : #define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain"
85 : : #define ENV_VALUE_SECS "secs"
86 : : #define ENV_VALUE_MILLISECS "millisecs"
87 : : #define ENV_VALUE_MICROSECS "microsecs"
88 : : #define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits"
89 : : #define ENV_VALUE_YES "yes"
90 : : #define ENV_VALUE_NO "no"
91 : :
92 : : /* Function definitions for certificate and key loading. */
93 : :
94 : 3 : X509 *TS_CONF_load_cert(const char *file)
95 : : {
96 : 3 : BIO *cert = NULL;
97 : 3 : X509 *x = NULL;
98 : :
99 [ + - ]: 3 : if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
100 : 3 : x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
101 : : end:
102 [ - + ]: 3 : if (x == NULL)
103 : 0 : fprintf(stderr, "unable to load certificate: %s\n", file);
104 : 3 : BIO_free(cert);
105 : 3 : return x;
106 : : }
107 : :
108 : 12 : STACK_OF(X509) *TS_CONF_load_certs(const char *file)
109 : : {
110 : 12 : BIO *certs = NULL;
111 : 12 : STACK_OF(X509) *othercerts = NULL;
112 : 12 : STACK_OF(X509_INFO) *allcerts = NULL;
113 : : int i;
114 : :
115 [ + - ]: 12 : if (!(certs = BIO_new_file(file, "r"))) goto end;
116 : :
117 [ + - ]: 12 : if (!(othercerts = sk_X509_new_null())) goto end;
118 : 12 : allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
119 [ + + ]: 24 : for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
120 : : {
121 : 12 : X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
122 [ + - ]: 12 : if (xi->x509)
123 : : {
124 : 12 : sk_X509_push(othercerts, xi->x509);
125 : 12 : xi->x509 = NULL;
126 : : }
127 : : }
128 : : end:
129 [ - + ]: 12 : if (othercerts == NULL)
130 : 0 : fprintf(stderr, "unable to load certificates: %s\n", file);
131 : 12 : sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
132 : 12 : BIO_free(certs);
133 : 12 : return othercerts;
134 : : }
135 : :
136 : 3 : EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
137 : : {
138 : 3 : BIO *key = NULL;
139 : 3 : EVP_PKEY *pkey = NULL;
140 : :
141 [ + - ]: 3 : if (!(key = BIO_new_file(file, "r"))) goto end;
142 : 3 : pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass);
143 : : end:
144 [ - + ]: 3 : if (pkey == NULL)
145 : 0 : fprintf(stderr, "unable to load private key: %s\n", file);
146 : 3 : BIO_free(key);
147 : 3 : return pkey;
148 : : }
149 : :
150 : : /* Function definitions for handling configuration options. */
151 : :
152 : 0 : static void TS_CONF_lookup_fail(const char *name, const char *tag)
153 : : {
154 : 0 : fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag);
155 : 0 : }
156 : :
157 : 0 : static void TS_CONF_invalid(const char *name, const char *tag)
158 : : {
159 : 0 : fprintf(stderr, "invalid variable value for %s::%s\n", name, tag);
160 : 0 : }
161 : :
162 : 3 : const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
163 : : {
164 [ + + ]: 3 : if (!section)
165 : : {
166 : 1 : section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
167 [ - + ]: 1 : if (!section)
168 : 0 : TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
169 : : }
170 : 3 : return section;
171 : : }
172 : :
173 : 3 : int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
174 : : TS_RESP_CTX *ctx)
175 : : {
176 : 3 : int ret = 0;
177 : 3 : char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
178 [ - + ]: 3 : if (!serial)
179 : : {
180 : 0 : TS_CONF_lookup_fail(section, ENV_SERIAL);
181 : 0 : goto err;
182 : : }
183 : 3 : TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
184 : :
185 : 3 : ret = 1;
186 : : err:
187 : 3 : return ret;
188 : : }
189 : :
190 : : #ifndef OPENSSL_NO_ENGINE
191 : :
192 : 3 : int TS_CONF_set_crypto_device(CONF *conf, const char *section,
193 : : const char *device)
194 : : {
195 : 3 : int ret = 0;
196 : :
197 [ + - ]: 3 : if (!device)
198 : 3 : device = NCONF_get_string(conf, section,
199 : : ENV_CRYPTO_DEVICE);
200 : :
201 [ - + ][ # # ]: 3 : if (device && !TS_CONF_set_default_engine(device))
202 : : {
203 : 0 : TS_CONF_invalid(section, ENV_CRYPTO_DEVICE);
204 : 0 : goto err;
205 : : }
206 : : ret = 1;
207 : : err:
208 : 3 : return ret;
209 : : }
210 : :
211 : 0 : int TS_CONF_set_default_engine(const char *name)
212 : : {
213 : 0 : ENGINE *e = NULL;
214 : 0 : int ret = 0;
215 : :
216 : : /* Leave the default if builtin specified. */
217 [ # # ]: 0 : if (strcmp(name, "builtin") == 0) return 1;
218 : :
219 [ # # ]: 0 : if (!(e = ENGINE_by_id(name))) goto err;
220 : : /* Enable the use of the NCipher HSM for forked children. */
221 [ # # ]: 0 : if (strcmp(name, "chil") == 0)
222 : 0 : ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
223 : : /* All the operations are going to be carried out by the engine. */
224 [ # # ]: 0 : if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err;
225 : 0 : ret = 1;
226 : : err:
227 [ # # ]: 0 : if (!ret)
228 : : {
229 : 0 : TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE,
230 : : TS_R_COULD_NOT_SET_ENGINE);
231 : 0 : ERR_add_error_data(2, "engine:", name);
232 : : }
233 [ # # ]: 0 : if (e) ENGINE_free(e);
234 : 0 : return ret;
235 : : }
236 : :
237 : : #endif
238 : :
239 : 3 : int TS_CONF_set_signer_cert(CONF *conf, const char *section,
240 : : const char *cert, TS_RESP_CTX *ctx)
241 : : {
242 : 3 : int ret = 0;
243 : 3 : X509 *cert_obj = NULL;
244 [ + - ]: 3 : if (!cert)
245 : 3 : cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
246 [ - + ]: 3 : if (!cert)
247 : : {
248 : 0 : TS_CONF_lookup_fail(section, ENV_SIGNER_CERT);
249 : 0 : goto err;
250 : : }
251 [ + - ]: 3 : if (!(cert_obj = TS_CONF_load_cert(cert)))
252 : : goto err;
253 [ + - ]: 3 : if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
254 : : goto err;
255 : :
256 : 3 : ret = 1;
257 : : err:
258 : 3 : X509_free(cert_obj);
259 : 3 : return ret;
260 : : }
261 : :
262 : 3 : int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
263 : : TS_RESP_CTX *ctx)
264 : : {
265 : 3 : int ret = 0;
266 : 3 : STACK_OF(X509) *certs_obj = NULL;
267 [ + - ]: 3 : if (!certs)
268 : 3 : certs = NCONF_get_string(conf, section, ENV_CERTS);
269 : : /* Certificate chain is optional. */
270 [ + - ]: 3 : if (!certs) goto end;
271 [ + - ]: 3 : if (!(certs_obj = TS_CONF_load_certs(certs))) goto err;
272 [ + - ]: 3 : if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err;
273 : : end:
274 : : ret = 1;
275 : : err:
276 : 3 : sk_X509_pop_free(certs_obj, X509_free);
277 : 3 : return ret;
278 : : }
279 : :
280 : 3 : int TS_CONF_set_signer_key(CONF *conf, const char *section,
281 : : const char *key, const char *pass,
282 : : TS_RESP_CTX *ctx)
283 : : {
284 : 3 : int ret = 0;
285 : 3 : EVP_PKEY *key_obj = NULL;
286 [ + - ]: 3 : if (!key)
287 : 3 : key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
288 [ - + ]: 3 : if (!key)
289 : : {
290 : 0 : TS_CONF_lookup_fail(section, ENV_SIGNER_KEY);
291 : 0 : goto err;
292 : : }
293 [ + - ]: 3 : if (!(key_obj = TS_CONF_load_key(key, pass))) goto err;
294 [ + - ]: 3 : if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err;
295 : :
296 : 3 : ret = 1;
297 : : err:
298 : 3 : EVP_PKEY_free(key_obj);
299 : 3 : return ret;
300 : : }
301 : :
302 : 3 : int TS_CONF_set_def_policy(CONF *conf, const char *section,
303 : : const char *policy, TS_RESP_CTX *ctx)
304 : : {
305 : 3 : int ret = 0;
306 : 3 : ASN1_OBJECT *policy_obj = NULL;
307 [ + - ]: 3 : if (!policy)
308 : 3 : policy = NCONF_get_string(conf, section,
309 : : ENV_DEFAULT_POLICY);
310 [ - + ]: 3 : if (!policy)
311 : : {
312 : 0 : TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
313 : 0 : goto err;
314 : : }
315 [ - + ]: 3 : if (!(policy_obj = OBJ_txt2obj(policy, 0)))
316 : : {
317 : 0 : TS_CONF_invalid(section, ENV_DEFAULT_POLICY);
318 : 0 : goto err;
319 : : }
320 [ + - ]: 3 : if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
321 : : goto err;
322 : :
323 : 3 : ret = 1;
324 : : err:
325 : 3 : ASN1_OBJECT_free(policy_obj);
326 : 3 : return ret;
327 : : }
328 : :
329 : 3 : int TS_CONF_set_policies(CONF *conf, const char *section,
330 : : TS_RESP_CTX *ctx)
331 : : {
332 : 3 : int ret = 0;
333 : : int i;
334 : 3 : STACK_OF(CONF_VALUE) *list = NULL;
335 : 3 : char *policies = NCONF_get_string(conf, section,
336 : : ENV_OTHER_POLICIES);
337 : : /* If no other policy is specified, that's fine. */
338 [ + - ][ - + ]: 3 : if (policies && !(list = X509V3_parse_list(policies)))
339 : : {
340 : 0 : TS_CONF_invalid(section, ENV_OTHER_POLICIES);
341 : 0 : goto err;
342 : : }
343 [ + + ]: 9 : for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
344 : : {
345 : 6 : CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
346 [ + - ]: 6 : const char *extval = val->value ? val->value : val->name;
347 : : ASN1_OBJECT *objtmp;
348 [ - + ]: 6 : if (!(objtmp = OBJ_txt2obj(extval, 0)))
349 : : {
350 : 0 : TS_CONF_invalid(section, ENV_OTHER_POLICIES);
351 : 0 : goto err;
352 : : }
353 [ + - ]: 6 : if (!TS_RESP_CTX_add_policy(ctx, objtmp))
354 : : goto err;
355 : 6 : ASN1_OBJECT_free(objtmp);
356 : : }
357 : :
358 : : ret = 1;
359 : : err:
360 : 3 : sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
361 : 3 : return ret;
362 : : }
363 : :
364 : 3 : int TS_CONF_set_digests(CONF *conf, const char *section,
365 : : TS_RESP_CTX *ctx)
366 : : {
367 : 3 : int ret = 0;
368 : : int i;
369 : 3 : STACK_OF(CONF_VALUE) *list = NULL;
370 : 3 : char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
371 [ - + ]: 3 : if (!digests)
372 : : {
373 : 0 : TS_CONF_lookup_fail(section, ENV_DIGESTS);
374 : 0 : goto err;
375 : : }
376 [ - + ]: 3 : if (!(list = X509V3_parse_list(digests)))
377 : : {
378 : 0 : TS_CONF_invalid(section, ENV_DIGESTS);
379 : 0 : goto err;
380 : : }
381 [ + - ]: 3 : if (sk_CONF_VALUE_num(list) == 0)
382 : : {
383 : 0 : TS_CONF_invalid(section, ENV_DIGESTS);
384 : 0 : goto err;
385 : : }
386 [ + + ]: 9 : for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
387 : : {
388 : 6 : CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
389 [ + - ]: 6 : const char *extval = val->value ? val->value : val->name;
390 : : const EVP_MD *md;
391 [ - + ]: 6 : if (!(md = EVP_get_digestbyname(extval)))
392 : : {
393 : 0 : TS_CONF_invalid(section, ENV_DIGESTS);
394 : 0 : goto err;
395 : : }
396 [ + - ]: 6 : if (!TS_RESP_CTX_add_md(ctx, md))
397 : : goto err;
398 : : }
399 : :
400 : : ret = 1;
401 : : err:
402 : 3 : sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
403 : 3 : return ret;
404 : : }
405 : :
406 : 3 : int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
407 : : {
408 : 3 : int ret = 0;
409 : : int i;
410 : 3 : int secs = 0, millis = 0, micros = 0;
411 : 3 : STACK_OF(CONF_VALUE) *list = NULL;
412 : 3 : char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
413 : :
414 [ + - ][ - + ]: 3 : if (accuracy && !(list = X509V3_parse_list(accuracy)))
415 : : {
416 : 0 : TS_CONF_invalid(section, ENV_ACCURACY);
417 : 0 : goto err;
418 : : }
419 [ + + ]: 12 : for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
420 : : {
421 : 9 : CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
422 [ + + ]: 9 : if (strcmp(val->name, ENV_VALUE_SECS) == 0)
423 : : {
424 [ + - ]: 3 : if (val->value) secs = atoi(val->value);
425 : : }
426 [ + + ]: 6 : else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0)
427 : : {
428 [ + - ]: 3 : if (val->value) millis = atoi(val->value);
429 : : }
430 [ + - ]: 3 : else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0)
431 : : {
432 [ + - ]: 3 : if (val->value) micros = atoi(val->value);
433 : : }
434 : : else
435 : : {
436 : 0 : TS_CONF_invalid(section, ENV_ACCURACY);
437 : 0 : goto err;
438 : : }
439 : : }
440 [ + - ]: 3 : if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
441 : : goto err;
442 : :
443 : 3 : ret = 1;
444 : : err:
445 : 3 : sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
446 : 3 : return ret;
447 : : }
448 : :
449 : 3 : int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
450 : : TS_RESP_CTX *ctx)
451 : : {
452 : 3 : int ret = 0;
453 : 3 : long digits = 0;
454 : :
455 : : /* If not specified, set the default value to 0, i.e. sec precision */
456 [ + - ]: 3 : if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
457 : : &digits))
458 : 3 : digits = 0;
459 [ - + ]: 3 : if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS)
460 : : {
461 : 0 : TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
462 : 0 : goto err;
463 : : }
464 : :
465 [ - + ]: 3 : if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
466 : : goto err;
467 : :
468 : : return 1;
469 : : err:
470 : : return ret;
471 : : }
472 : :
473 : 9 : static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field,
474 : : int flag, TS_RESP_CTX *ctx)
475 : : {
476 : : /* Default is false. */
477 : 9 : const char *value = NCONF_get_string(conf, section, field);
478 [ + - ]: 9 : if (value)
479 : : {
480 [ + - ]: 9 : if (strcmp(value, ENV_VALUE_YES) == 0)
481 : 9 : TS_RESP_CTX_add_flags(ctx, flag);
482 [ # # ]: 0 : else if (strcmp(value, ENV_VALUE_NO) != 0)
483 : : {
484 : 0 : TS_CONF_invalid(section, field);
485 : 0 : return 0;
486 : : }
487 : : }
488 : :
489 : : return 1;
490 : : }
491 : :
492 : 3 : int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
493 : : {
494 : 3 : return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
495 : : }
496 : :
497 : 3 : int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
498 : : {
499 : 3 : return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
500 : : }
501 : :
502 : 3 : int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
503 : : TS_RESP_CTX *ctx)
504 : : {
505 : 3 : return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
506 : : TS_ESS_CERT_ID_CHAIN, ctx);
507 : : }
|