Line data Source code
1 : /*
2 : * Copyright (C) 2002-2016 Free Software Foundation, Inc.
3 : * Copyright (C) 2016-2017 Red Hat, Inc.
4 : *
5 : * Author: Nikos Mavrogiannopoulos
6 : *
7 : * This file is part of GnuTLS.
8 : *
9 : * The GnuTLS is free software; you can redistribute it and/or
10 : * modify it under the terms of the GNU Lesser General Public License
11 : * as published by the Free Software Foundation; either version 2.1 of
12 : * the License, or (at your option) any later version.
13 : *
14 : * This library is distributed in the hope that it will be useful, but
15 : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : * Lesser General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>
21 : *
22 : */
23 :
24 : #include "gnutls_int.h"
25 : #include "auth.h"
26 : #include "errors.h"
27 : #include <auth/cert.h>
28 : #include "dh.h"
29 : #include "num.h"
30 : #include "datum.h"
31 : #include <pk.h>
32 : #include <algorithms.h>
33 : #include <global.h>
34 : #include <record.h>
35 : #include <tls-sig.h>
36 : #include <state.h>
37 : #include <pk.h>
38 : #include "str.h"
39 : #include <debug.h>
40 : #include <x509_b64.h>
41 : #include <x509.h>
42 : #include "x509/common.h"
43 : #include "x509/x509_int.h"
44 : #include <str_array.h>
45 : #include <gnutls/x509.h>
46 : #include "read-file.h"
47 : #include "system-keys.h"
48 : #include "urls.h"
49 : #include "cert-cred.h"
50 : #ifdef _WIN32
51 : #include <wincrypt.h>
52 : #endif
53 :
54 : /*
55 : * This file includes functions related to adding certificates and other
56 : * related objects in a certificate credentials structure.
57 : */
58 :
59 :
60 : /* Returns the name of the certificate of a null name
61 : */
62 11274 : int _gnutls_get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
63 : {
64 11274 : size_t max_size;
65 11274 : int i, ret = 0, ret2;
66 11274 : char name[MAX_CN];
67 11274 : unsigned have_dns_name = 0;
68 :
69 31821 : for (i = 0; !(ret < 0); i++) {
70 20547 : max_size = sizeof(name);
71 :
72 20547 : ret =
73 20547 : gnutls_x509_crt_get_subject_alt_name(crt, i, name,
74 : &max_size, NULL);
75 20547 : if (ret == GNUTLS_SAN_DNSNAME) {
76 8975 : have_dns_name = 1;
77 :
78 8975 : ret2 =
79 8975 : _gnutls_str_array_append_idna(names, name,
80 : max_size);
81 8975 : if (ret2 < 0) {
82 0 : _gnutls_str_array_clear(names);
83 0 : return gnutls_assert_val(ret2);
84 : }
85 : }
86 : }
87 :
88 11274 : if (have_dns_name == 0) {
89 2622 : max_size = sizeof(name);
90 2622 : ret =
91 2622 : gnutls_x509_crt_get_dn_by_oid(crt, OID_X520_COMMON_NAME, 0, 0,
92 : name, &max_size);
93 2622 : if (ret >= 0) {
94 2582 : ret = _gnutls_str_array_append_idna(names, name, max_size);
95 2582 : if (ret < 0) {
96 0 : _gnutls_str_array_clear(names);
97 0 : return gnutls_assert_val(ret);
98 : }
99 : }
100 : }
101 :
102 : return 0;
103 : }
104 :
105 : /* Reads a DER encoded certificate list from memory and stores it to a
106 : * gnutls_cert structure. Returns the number of certificates parsed.
107 : */
108 : static int
109 8835 : parse_der_cert_mem(gnutls_certificate_credentials_t res,
110 : gnutls_privkey_t key,
111 : const void *input_cert, int input_cert_size)
112 : {
113 8835 : gnutls_datum_t tmp;
114 8835 : gnutls_x509_crt_t crt;
115 8835 : gnutls_pcert_st *ccert;
116 8835 : int ret;
117 8835 : gnutls_str_array_t names;
118 :
119 8835 : _gnutls_str_array_init(&names);
120 :
121 8835 : ccert = gnutls_malloc(sizeof(*ccert));
122 8835 : if (ccert == NULL) {
123 0 : gnutls_assert();
124 0 : return GNUTLS_E_MEMORY_ERROR;
125 : }
126 :
127 8835 : ret = gnutls_x509_crt_init(&crt);
128 8835 : if (ret < 0) {
129 0 : gnutls_assert();
130 0 : goto cleanup;
131 : }
132 :
133 8835 : tmp.data = (uint8_t *) input_cert;
134 8835 : tmp.size = input_cert_size;
135 :
136 8835 : ret = gnutls_x509_crt_import(crt, &tmp, GNUTLS_X509_FMT_DER);
137 8835 : if (ret < 0) {
138 0 : gnutls_assert();
139 0 : gnutls_x509_crt_deinit(crt);
140 0 : goto cleanup;
141 : }
142 :
143 8835 : ret = _gnutls_get_x509_name(crt, &names);
144 8835 : if (ret < 0) {
145 0 : gnutls_assert();
146 0 : gnutls_x509_crt_deinit(crt);
147 0 : goto cleanup;
148 : }
149 :
150 8835 : ret = gnutls_pcert_import_x509(ccert, crt, 0);
151 8835 : gnutls_x509_crt_deinit(crt);
152 :
153 8835 : if (ret < 0) {
154 0 : gnutls_assert();
155 0 : goto cleanup;
156 : }
157 :
158 8835 : ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, 1);
159 8835 : if (ret < 0) {
160 0 : gnutls_assert();
161 0 : goto cleanup;
162 : }
163 :
164 : return ret;
165 :
166 0 : cleanup:
167 0 : _gnutls_str_array_clear(&names);
168 0 : gnutls_free(ccert);
169 0 : return ret;
170 : }
171 :
172 : /* Reads a base64 encoded certificate list from memory and stores it to
173 : * a gnutls_cert structure. Returns the number of certificate parsed.
174 : */
175 : static int
176 2357 : parse_pem_cert_mem(gnutls_certificate_credentials_t res,
177 : gnutls_privkey_t key,
178 : const char *input_cert, int input_cert_size)
179 : {
180 2357 : int size;
181 2357 : const char *ptr;
182 2357 : gnutls_datum_t tmp;
183 2357 : int ret, count, i;
184 2357 : unsigned ncerts = 0;
185 2357 : gnutls_pcert_st *pcerts = NULL;
186 2357 : gnutls_str_array_t names;
187 2357 : gnutls_x509_crt_t unsorted[DEFAULT_MAX_VERIFY_DEPTH];
188 :
189 2357 : _gnutls_str_array_init(&names);
190 :
191 : /* move to the certificate
192 : */
193 2357 : ptr = memmem(input_cert, input_cert_size,
194 : PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
195 2357 : if (ptr == NULL)
196 0 : ptr = memmem(input_cert, input_cert_size,
197 : PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);
198 :
199 2357 : if (ptr == NULL) {
200 0 : gnutls_assert();
201 0 : return GNUTLS_E_BASE64_DECODING_ERROR;
202 : }
203 2357 : size = input_cert_size - (ptr - input_cert);
204 :
205 2357 : count = 0;
206 :
207 3431 : do {
208 3431 : tmp.data = (void *) ptr;
209 3431 : tmp.size = size;
210 :
211 3431 : ret = gnutls_x509_crt_init(&unsorted[count]);
212 3431 : if (ret < 0) {
213 0 : gnutls_assert();
214 0 : goto cleanup;
215 : }
216 :
217 3431 : ret = gnutls_x509_crt_import(unsorted[count], &tmp, GNUTLS_X509_FMT_PEM);
218 3431 : if (ret < 0) {
219 0 : gnutls_assert();
220 0 : goto cleanup;
221 : }
222 3431 : count++;
223 :
224 : /* now we move ptr after the pem header
225 : */
226 3431 : ptr++;
227 3431 : size--;
228 :
229 : /* find the next certificate (if any)
230 : */
231 :
232 3431 : if (size > 0) {
233 3431 : char *ptr3;
234 :
235 3431 : ptr3 =
236 3431 : memmem(ptr, size, PEM_CERT_SEP,
237 : sizeof(PEM_CERT_SEP) - 1);
238 3431 : if (ptr3 == NULL)
239 2357 : ptr3 = memmem(ptr, size, PEM_CERT_SEP2,
240 : sizeof(PEM_CERT_SEP2) - 1);
241 :
242 3431 : ptr = ptr3;
243 3431 : size = input_cert_size - (ptr - input_cert);
244 : } else
245 : ptr = NULL;
246 :
247 : }
248 3431 : while (ptr != NULL && count < DEFAULT_MAX_VERIFY_DEPTH);
249 :
250 2357 : ret =
251 2357 : _gnutls_get_x509_name(unsorted[0], &names);
252 2357 : if (ret < 0) {
253 0 : gnutls_assert();
254 0 : goto cleanup;
255 : }
256 :
257 2357 : pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * count);
258 2357 : if (pcerts == NULL) {
259 0 : gnutls_assert();
260 0 : return GNUTLS_E_MEMORY_ERROR;
261 : }
262 :
263 2357 : ncerts = count;
264 2357 : ret =
265 2357 : gnutls_pcert_import_x509_list(pcerts, unsorted, &ncerts, GNUTLS_X509_CRT_LIST_SORT);
266 2357 : if (ret < 0) {
267 0 : gnutls_free(pcerts);
268 0 : gnutls_assert();
269 0 : goto cleanup;
270 : }
271 :
272 2357 : ret =
273 2357 : _gnutls_certificate_credential_append_keypair(res, key, names, pcerts, ncerts);
274 2357 : if (ret < 0) {
275 0 : gnutls_assert();
276 0 : goto cleanup;
277 : }
278 :
279 5788 : for (i = 0; i < count; i++)
280 3431 : gnutls_x509_crt_deinit(unsorted[i]);
281 :
282 2357 : return ncerts;
283 :
284 0 : cleanup:
285 0 : _gnutls_str_array_clear(&names);
286 0 : for (i = 0; i < count; i++)
287 0 : gnutls_x509_crt_deinit(unsorted[i]);
288 0 : if (pcerts) {
289 0 : for (i = 0; i < count; i++)
290 0 : gnutls_pcert_deinit(&pcerts[i]);
291 0 : gnutls_free(pcerts);
292 : }
293 : return ret;
294 : }
295 :
296 :
297 :
298 : /* Reads a DER or PEM certificate from memory
299 : */
300 : static int
301 11192 : read_cert_mem(gnutls_certificate_credentials_t res,
302 : gnutls_privkey_t key,
303 : const void *cert,
304 : int cert_size, gnutls_x509_crt_fmt_t type)
305 : {
306 11192 : int ret;
307 :
308 11192 : if (type == GNUTLS_X509_FMT_DER)
309 8835 : ret = parse_der_cert_mem(res, key, cert, cert_size);
310 : else
311 2357 : ret = parse_pem_cert_mem(res, key, cert, cert_size);
312 :
313 11192 : if (ret < 0) {
314 0 : gnutls_assert();
315 0 : return ret;
316 : }
317 :
318 : return ret;
319 : }
320 :
321 1 : static int tmp_pin_cb(void *userdata, int attempt, const char *token_url,
322 : const char *token_label, unsigned int flags,
323 : char *pin, size_t pin_max)
324 : {
325 1 : const char *tmp_pin = userdata;
326 :
327 1 : if (attempt == 0) {
328 1 : snprintf(pin, pin_max, "%s", tmp_pin);
329 1 : return 0;
330 : }
331 :
332 : return -1;
333 : }
334 :
335 : /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
336 : * indicates the certificate format.
337 : *
338 : * It returns the private key read in @rkey.
339 : */
340 : int
341 11247 : _gnutls_read_key_mem(gnutls_certificate_credentials_t res,
342 : const void *key, int key_size, gnutls_x509_crt_fmt_t type,
343 : const char *pass, unsigned int flags,
344 : gnutls_privkey_t *rkey)
345 : {
346 11247 : int ret;
347 11247 : gnutls_datum_t tmp;
348 11247 : gnutls_privkey_t privkey;
349 :
350 11247 : if (key) {
351 11247 : tmp.data = (uint8_t *) key;
352 11247 : tmp.size = key_size;
353 :
354 11247 : ret = gnutls_privkey_init(&privkey);
355 11247 : if (ret < 0) {
356 0 : gnutls_assert();
357 0 : return ret;
358 : }
359 :
360 11247 : if (res->pin.cb) {
361 0 : gnutls_privkey_set_pin_function(privkey,
362 : res->pin.cb,
363 : res->pin.data);
364 11247 : } else if (pass != NULL) {
365 0 : snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s",
366 : pass);
367 0 : gnutls_privkey_set_pin_function(privkey,
368 : tmp_pin_cb,
369 : res->pin_tmp);
370 : }
371 :
372 11247 : ret =
373 11247 : gnutls_privkey_import_x509_raw(privkey, &tmp, type,
374 : pass, flags);
375 11247 : if (ret < 0) {
376 0 : gnutls_assert();
377 0 : gnutls_privkey_deinit(privkey);
378 0 : return ret;
379 : }
380 :
381 11247 : *rkey = privkey;
382 : } else {
383 0 : gnutls_assert();
384 0 : return GNUTLS_E_INVALID_REQUEST;
385 : }
386 :
387 11247 : return 0;
388 : }
389 :
390 :
391 : /* Reads a private key from a token.
392 : */
393 : static int
394 4 : read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey)
395 : {
396 4 : int ret;
397 4 : gnutls_privkey_t pkey = NULL;
398 :
399 : /* allocate space for the pkey list
400 : */
401 4 : ret = gnutls_privkey_init(&pkey);
402 4 : if (ret < 0) {
403 0 : gnutls_assert();
404 0 : goto cleanup;
405 : }
406 :
407 4 : if (res->pin.cb)
408 1 : gnutls_privkey_set_pin_function(pkey, res->pin.cb,
409 : res->pin.data);
410 :
411 4 : ret = gnutls_privkey_import_url(pkey, url, 0);
412 4 : if (ret < 0) {
413 0 : gnutls_assert();
414 0 : goto cleanup;
415 : }
416 :
417 4 : *rkey = pkey;
418 :
419 4 : return 0;
420 :
421 0 : cleanup:
422 0 : if (pkey)
423 0 : gnutls_privkey_deinit(pkey);
424 :
425 : return ret;
426 : }
427 :
428 :
429 : #define MAX_PKCS11_CERT_CHAIN 8
430 : /* Reads a certificate key from a token.
431 : */
432 : static int
433 4 : read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const char *url)
434 : {
435 4 : int ret;
436 4 : gnutls_x509_crt_t crt = NULL;
437 4 : gnutls_pcert_st *ccert = NULL;
438 4 : gnutls_str_array_t names;
439 4 : gnutls_datum_t t = {NULL, 0};
440 4 : unsigned i, count = 0;
441 :
442 4 : _gnutls_str_array_init(&names);
443 :
444 4 : ccert = gnutls_malloc(sizeof(*ccert)*MAX_PKCS11_CERT_CHAIN);
445 4 : if (ccert == NULL) {
446 0 : gnutls_assert();
447 0 : ret = GNUTLS_E_MEMORY_ERROR;
448 0 : goto cleanup;
449 : }
450 :
451 4 : ret = gnutls_x509_crt_init(&crt);
452 4 : if (ret < 0) {
453 0 : gnutls_assert();
454 0 : goto cleanup;
455 : }
456 :
457 4 : if (res->pin.cb)
458 1 : gnutls_x509_crt_set_pin_function(crt, res->pin.cb,
459 : res->pin.data);
460 :
461 4 : ret = gnutls_x509_crt_import_url(crt, url, 0);
462 4 : if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
463 0 : ret =
464 0 : gnutls_x509_crt_import_url(crt, url,
465 : GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
466 4 : if (ret < 0) {
467 0 : gnutls_assert();
468 0 : goto cleanup;
469 : }
470 :
471 4 : ret = _gnutls_get_x509_name(crt, &names);
472 4 : if (ret < 0) {
473 0 : gnutls_assert();
474 0 : goto cleanup;
475 : }
476 :
477 : /* Try to load the whole certificate chain from the PKCS #11 token */
478 6 : for (i=0;i<MAX_PKCS11_CERT_CHAIN;i++) {
479 6 : ret = gnutls_x509_crt_check_issuer(crt, crt);
480 6 : if (i > 0 && ret != 0) {
481 : /* self signed */
482 : break;
483 : }
484 :
485 4 : ret = gnutls_pcert_import_x509(&ccert[i], crt, 0);
486 4 : if (ret < 0) {
487 0 : gnutls_assert();
488 0 : goto cleanup;
489 : }
490 4 : count++;
491 :
492 4 : ret = _gnutls_get_raw_issuer(url, crt, &t, 0);
493 4 : if (ret < 0)
494 : break;
495 :
496 2 : gnutls_x509_crt_deinit(crt);
497 2 : crt = NULL;
498 2 : ret = gnutls_x509_crt_init(&crt);
499 2 : if (ret < 0) {
500 0 : gnutls_assert();
501 0 : goto cleanup;
502 : }
503 :
504 2 : ret = gnutls_x509_crt_import(crt, &t, GNUTLS_X509_FMT_DER);
505 2 : if (ret < 0) {
506 0 : gnutls_assert();
507 0 : goto cleanup;
508 : }
509 2 : gnutls_free(t.data);
510 : }
511 :
512 4 : ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, count);
513 4 : if (ret < 0) {
514 0 : gnutls_assert();
515 0 : goto cleanup;
516 : }
517 :
518 4 : if (crt != NULL)
519 4 : gnutls_x509_crt_deinit(crt);
520 :
521 : return 0;
522 0 : cleanup:
523 0 : if (crt != NULL)
524 0 : gnutls_x509_crt_deinit(crt);
525 0 : gnutls_free(t.data);
526 0 : _gnutls_str_array_clear(&names);
527 0 : gnutls_free(ccert);
528 0 : return ret;
529 : }
530 :
531 : /* Reads a certificate file
532 : */
533 : static int
534 368 : read_cert_file(gnutls_certificate_credentials_t res,
535 : gnutls_privkey_t key,
536 : const char *certfile, gnutls_x509_crt_fmt_t type)
537 : {
538 368 : int ret;
539 368 : size_t size;
540 368 : char *data;
541 :
542 368 : if (gnutls_url_is_supported(certfile)) {
543 4 : return read_cert_url(res, key, certfile);
544 : }
545 :
546 364 : data = read_file(certfile, RF_BINARY, &size);
547 :
548 364 : if (data == NULL) {
549 2 : gnutls_assert();
550 2 : return GNUTLS_E_FILE_ERROR;
551 : }
552 :
553 362 : ret = read_cert_mem(res, key, data, size, type);
554 362 : free(data);
555 :
556 362 : return ret;
557 :
558 : }
559 :
560 :
561 :
562 : /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
563 : * stores it).
564 : */
565 : int
566 372 : _gnutls_read_key_file(gnutls_certificate_credentials_t res,
567 : const char *keyfile, gnutls_x509_crt_fmt_t type,
568 : const char *pass, unsigned int flags,
569 : gnutls_privkey_t *rkey)
570 : {
571 372 : int ret;
572 372 : size_t size;
573 372 : char *data;
574 :
575 372 : if (_gnutls_url_is_known(keyfile)) {
576 4 : if (gnutls_url_is_supported(keyfile)) {
577 : /* if no PIN function is specified, and we have a PIN,
578 : * specify one */
579 4 : if (pass != NULL && res->pin.cb == NULL) {
580 1 : snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s", pass);
581 1 : gnutls_certificate_set_pin_function(res, tmp_pin_cb, res->pin_tmp);
582 : }
583 :
584 4 : return read_key_url(res, keyfile, rkey);
585 : } else
586 0 : return
587 0 : gnutls_assert_val
588 : (GNUTLS_E_UNIMPLEMENTED_FEATURE);
589 : }
590 :
591 368 : data = read_file(keyfile, RF_BINARY | RF_SENSITIVE, &size);
592 :
593 368 : if (data == NULL) {
594 0 : gnutls_assert();
595 0 : return GNUTLS_E_FILE_ERROR;
596 : }
597 :
598 368 : ret = _gnutls_read_key_mem(res, data, size, type, pass, flags, rkey);
599 368 : zeroize_key(data, size);
600 368 : free(data);
601 :
602 368 : return ret;
603 : }
604 :
605 : /**
606 : * gnutls_certificate_set_x509_key_mem:
607 : * @res: is a #gnutls_certificate_credentials_t type.
608 : * @cert: contains a certificate list (path) for the specified private key
609 : * @key: is the private key, or %NULL
610 : * @type: is PEM or DER
611 : *
612 : * This function sets a certificate/private key pair in the
613 : * gnutls_certificate_credentials_t type. This function may be called
614 : * more than once, in case multiple keys/certificates exist for the
615 : * server.
616 : *
617 : * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
618 : * is supported. This means that certificates intended for signing cannot
619 : * be used for ciphersuites that require encryption.
620 : *
621 : * If the certificate and the private key are given in PEM encoding
622 : * then the strings that hold their values must be null terminated.
623 : *
624 : * The @key may be %NULL if you are using a sign callback, see
625 : * gnutls_sign_callback_set().
626 : *
627 : * Note that, this function by default returns zero on success and a negative value on error.
628 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
629 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
630 : *
631 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
632 : *
633 : **/
634 : int
635 10820 : gnutls_certificate_set_x509_key_mem(gnutls_certificate_credentials_t res,
636 : const gnutls_datum_t * cert,
637 : const gnutls_datum_t * key,
638 : gnutls_x509_crt_fmt_t type)
639 : {
640 10820 : return gnutls_certificate_set_x509_key_mem2(res, cert, key, type,
641 : NULL, 0);
642 : }
643 :
644 : /**
645 : * gnutls_certificate_set_x509_key_mem2:
646 : * @res: is a #gnutls_certificate_credentials_t type.
647 : * @cert: contains a certificate list (path) for the specified private key
648 : * @key: is the private key, or %NULL
649 : * @type: is PEM or DER
650 : * @pass: is the key's password
651 : * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
652 : *
653 : * This function sets a certificate/private key pair in the
654 : * gnutls_certificate_credentials_t type. This function may be called
655 : * more than once, in case multiple keys/certificates exist for the
656 : * server.
657 : *
658 : * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
659 : * is supported. This means that certificates intended for signing cannot
660 : * be used for ciphersuites that require encryption.
661 : *
662 : * If the certificate and the private key are given in PEM encoding
663 : * then the strings that hold their values must be null terminated.
664 : *
665 : * The @key may be %NULL if you are using a sign callback, see
666 : * gnutls_sign_callback_set().
667 : *
668 : * Note that, this function by default returns zero on success and a negative value on error.
669 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
670 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
671 : *
672 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
673 : **/
674 : int
675 10830 : gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
676 : const gnutls_datum_t * cert,
677 : const gnutls_datum_t * key,
678 : gnutls_x509_crt_fmt_t type,
679 : const char *pass, unsigned int flags)
680 : {
681 10830 : int ret;
682 10830 : gnutls_privkey_t rkey;
683 :
684 : /* this should be first
685 : */
686 21660 : if ((ret = _gnutls_read_key_mem(res, key ? key->data : NULL,
687 10830 : key ? key->size : 0, type, pass,
688 : flags, &rkey)) < 0)
689 : return ret;
690 :
691 10830 : if ((ret = read_cert_mem(res, rkey, cert->data, cert->size, type)) < 0) {
692 0 : gnutls_privkey_deinit(rkey);
693 0 : return ret;
694 : }
695 :
696 10830 : res->ncerts++;
697 :
698 10830 : if (key && (ret = _gnutls_check_key_cert_match(res)) < 0) {
699 1 : gnutls_assert();
700 1 : return ret;
701 : }
702 :
703 10829 : CRED_RET_SUCCESS(res);
704 : }
705 :
706 :
707 : /**
708 : * gnutls_certificate_set_x509_key:
709 : * @res: is a #gnutls_certificate_credentials_t type.
710 : * @cert_list: contains a certificate list (path) for the specified private key
711 : * @cert_list_size: holds the size of the certificate list
712 : * @key: is a #gnutls_x509_privkey_t key
713 : *
714 : * This function sets a certificate/private key pair in the
715 : * gnutls_certificate_credentials_t type. This function may be
716 : * called more than once, in case multiple keys/certificates exist for
717 : * the server. For clients that wants to send more than their own end
718 : * entity certificate (e.g., also an intermediate CA cert) then put
719 : * the certificate chain in @cert_list.
720 : *
721 : * Note that the certificates and keys provided, can be safely deinitialized
722 : * after this function is called.
723 : *
724 : * If that function fails to load the @res type is at an undefined state, it must
725 : * not be reused to load other keys or certificates.
726 : *
727 : * Note that, this function by default returns zero on success and a negative value on error.
728 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
729 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
730 : *
731 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
732 : *
733 : * Since: 2.4.0
734 : **/
735 : int
736 33 : gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
737 : gnutls_x509_crt_t * cert_list,
738 : int cert_list_size,
739 : gnutls_x509_privkey_t key)
740 : {
741 33 : int ret;
742 33 : gnutls_privkey_t pkey;
743 33 : gnutls_pcert_st *pcerts = NULL;
744 33 : gnutls_str_array_t names;
745 :
746 33 : _gnutls_str_array_init(&names);
747 :
748 : /* this should be first
749 : */
750 33 : ret = gnutls_privkey_init(&pkey);
751 33 : if (ret < 0) {
752 0 : gnutls_assert();
753 0 : return ret;
754 : }
755 :
756 33 : if (res->pin.cb)
757 0 : gnutls_privkey_set_pin_function(pkey, res->pin.cb,
758 : res->pin.data);
759 :
760 33 : ret =
761 33 : gnutls_privkey_import_x509(pkey, key,
762 : GNUTLS_PRIVKEY_IMPORT_COPY);
763 33 : if (ret < 0) {
764 0 : gnutls_assert();
765 0 : return ret;
766 : }
767 :
768 : /* load certificates */
769 33 : pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * cert_list_size);
770 33 : if (pcerts == NULL) {
771 0 : gnutls_assert();
772 0 : return GNUTLS_E_MEMORY_ERROR;
773 : }
774 :
775 33 : ret = _gnutls_get_x509_name(cert_list[0], &names);
776 33 : if (ret < 0) {
777 0 : gnutls_assert();
778 0 : goto cleanup;
779 : }
780 :
781 33 : ret =
782 33 : gnutls_pcert_import_x509_list(pcerts, cert_list, (unsigned int*)&cert_list_size,
783 : GNUTLS_X509_CRT_LIST_SORT);
784 33 : if (ret < 0) {
785 0 : gnutls_assert();
786 0 : goto cleanup;
787 : }
788 :
789 33 : ret =
790 33 : _gnutls_certificate_credential_append_keypair(res, pkey, names, pcerts,
791 : cert_list_size);
792 33 : if (ret < 0) {
793 0 : gnutls_assert();
794 0 : goto cleanup;
795 : }
796 :
797 33 : res->ncerts++;
798 :
799 : /* after this point we do not deinitialize anything on failure to avoid
800 : * double freeing. We intentionally keep everything as the credentials state
801 : * is documented to be on undefined state. */
802 33 : if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
803 1 : gnutls_assert();
804 1 : return ret;
805 : }
806 :
807 32 : CRED_RET_SUCCESS(res);
808 :
809 0 : cleanup:
810 0 : gnutls_free(pcerts);
811 0 : _gnutls_str_array_clear(&names);
812 : return ret;
813 : }
814 :
815 : /**
816 : * gnutls_certificate_get_x509_key:
817 : * @res: is a #gnutls_certificate_credentials_t type.
818 : * @index: The index of the key to obtain.
819 : * @key: Location to store the key.
820 : *
821 : * Obtains a X.509 private key that has been stored in @res with one of
822 : * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(),
823 : * gnutls_certificate_set_x509_key_file(),
824 : * gnutls_certificate_set_x509_key_file2(),
825 : * gnutls_certificate_set_x509_key_mem(), or
826 : * gnutls_certificate_set_x509_key_mem2(). The returned key must be deallocated
827 : * with gnutls_x509_privkey_deinit() when no longer needed.
828 : *
829 : * The @index matches the return value of gnutls_certificate_set_x509_key() and friends
830 : * functions, when the %GNUTLS_CERTIFICATE_API_V2 flag is set.
831 : *
832 : * If there is no key with the given index,
833 : * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the key with the
834 : * given index is not a X.509 key, %GNUTLS_E_INVALID_REQUEST is returned.
835 : *
836 : * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
837 : *
838 : * Since: 3.4.0
839 : */
840 : int
841 1 : gnutls_certificate_get_x509_key(gnutls_certificate_credentials_t res,
842 : unsigned index,
843 : gnutls_x509_privkey_t *key)
844 : {
845 1 : if (index >= res->ncerts) {
846 0 : gnutls_assert();
847 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
848 : }
849 :
850 1 : return gnutls_privkey_export_x509(res->certs[index].pkey, key);
851 : }
852 :
853 : /**
854 : * gnutls_certificate_get_x509_crt:
855 : * @res: is a #gnutls_certificate_credentials_t type.
856 : * @index: The index of the certificate list to obtain.
857 : * @crt_list: Where to store the certificate list.
858 : * @crt_list_size: Will hold the number of certificates.
859 : *
860 : * Obtains a X.509 certificate list that has been stored in @res with one of
861 : * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(),
862 : * gnutls_certificate_set_x509_key_file(),
863 : * gnutls_certificate_set_x509_key_file2(),
864 : * gnutls_certificate_set_x509_key_mem(), or
865 : * gnutls_certificate_set_x509_key_mem2(). Each certificate in the returned
866 : * certificate list must be deallocated with gnutls_x509_crt_deinit(), and the
867 : * list itself must be freed with gnutls_free().
868 : *
869 : * The @index matches the return value of gnutls_certificate_set_x509_key() and friends
870 : * functions, when the %GNUTLS_CERTIFICATE_API_V2 flag is set.
871 : *
872 : * If there is no certificate with the given index,
873 : * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the certificate
874 : * with the given index is not a X.509 certificate, %GNUTLS_E_INVALID_REQUEST
875 : * is returned. The returned certificates must be deinitialized after
876 : * use, and the @crt_list pointer must be freed using gnutls_free().
877 : *
878 : * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
879 : *
880 : * Since: 3.4.0
881 : */
882 : int
883 1 : gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res,
884 : unsigned index,
885 : gnutls_x509_crt_t **crt_list,
886 : unsigned *crt_list_size)
887 : {
888 1 : int ret;
889 1 : unsigned i;
890 :
891 1 : if (index >= res->ncerts) {
892 0 : gnutls_assert();
893 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
894 : }
895 :
896 1 : *crt_list_size = res->certs[index].cert_list_length;
897 2 : *crt_list = gnutls_malloc(
898 1 : res->certs[index].cert_list_length * sizeof (gnutls_x509_crt_t));
899 1 : if (*crt_list == NULL) {
900 0 : gnutls_assert();
901 0 : return GNUTLS_E_MEMORY_ERROR;
902 : }
903 :
904 3 : for (i = 0; i < res->certs[index].cert_list_length; ++i) {
905 2 : ret = gnutls_pcert_export_x509(&res->certs[index].cert_list[i], &(*crt_list)[i]);
906 2 : if (ret < 0) {
907 0 : while (i--)
908 0 : gnutls_x509_crt_deinit((*crt_list)[i]);
909 0 : gnutls_free(*crt_list);
910 :
911 0 : return gnutls_assert_val(ret);
912 : }
913 : }
914 :
915 : return 0;
916 : }
917 :
918 : /**
919 : * gnutls_certificate_set_trust_list:
920 : * @res: is a #gnutls_certificate_credentials_t type.
921 : * @tlist: is a #gnutls_x509_trust_list_t type
922 : * @flags: must be zero
923 : *
924 : * This function sets a trust list in the gnutls_certificate_credentials_t type.
925 : *
926 : * Note that the @tlist will become part of the credentials
927 : * structure and must not be deallocated. It will be automatically deallocated
928 : * when the @res structure is deinitialized.
929 : *
930 : * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
931 : *
932 : * Since: 3.2.2
933 : **/
934 : void
935 274 : gnutls_certificate_set_trust_list(gnutls_certificate_credentials_t res,
936 : gnutls_x509_trust_list_t tlist,
937 : unsigned flags)
938 : {
939 274 : gnutls_x509_trust_list_deinit(res->tlist, 1);
940 :
941 274 : res->tlist = tlist;
942 274 : }
943 :
944 : /**
945 : * gnutls_certificate_get_trust_list:
946 : * @res: is a #gnutls_certificate_credentials_t type.
947 : * @tlist: Location where to store the trust list.
948 : *
949 : * Obtains the list of trusted certificates stored in @res and writes a
950 : * pointer to it to the location @tlist. The pointer will point to memory
951 : * internal to @res, and must not be deinitialized. It will be automatically
952 : * deallocated when the @res structure is deinitialized.
953 : *
954 : * Since: 3.4.0
955 : **/
956 : void
957 1 : gnutls_certificate_get_trust_list(gnutls_certificate_credentials_t res,
958 : gnutls_x509_trust_list_t *tlist)
959 : {
960 1 : *tlist = res->tlist;
961 1 : }
962 :
963 : /**
964 : * gnutls_certificate_set_x509_key_file:
965 : * @res: is a #gnutls_certificate_credentials_t type.
966 : * @certfile: is a file that containing the certificate list (path) for
967 : * the specified private key, in PKCS7 format, or a list of certificates
968 : * @keyfile: is a file that contains the private key
969 : * @type: is PEM or DER
970 : *
971 : * This function sets a certificate/private key pair in the
972 : * gnutls_certificate_credentials_t type. This function may be
973 : * called more than once, in case multiple keys/certificates exist for
974 : * the server. For clients that need to send more than its own end
975 : * entity certificate, e.g., also an intermediate CA cert, then the
976 : * @certfile must contain the ordered certificate chain.
977 : *
978 : * Note that the names in the certificate provided will be considered
979 : * when selecting the appropriate certificate to use (in case of multiple
980 : * certificate/key pairs).
981 : *
982 : * This function can also accept URLs at @keyfile and @certfile. In that case it
983 : * will use the private key and certificate indicated by the URLs. Note
984 : * that the supported URLs are the ones indicated by gnutls_url_is_supported().
985 : *
986 : * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
987 : * present issuers in the token are imported (i.e., forming the required trust chain).
988 : *
989 : * If that function fails to load the @res structure is at an undefined state, it must
990 : * not be reused to load other keys or certificates.
991 : *
992 : * Note that, this function by default returns zero on success and a negative value on error.
993 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
994 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
995 : *
996 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
997 : *
998 : * Since: 3.1.11
999 : **/
1000 : int
1001 303 : gnutls_certificate_set_x509_key_file(gnutls_certificate_credentials_t res,
1002 : const char *certfile,
1003 : const char *keyfile,
1004 : gnutls_x509_crt_fmt_t type)
1005 : {
1006 303 : return gnutls_certificate_set_x509_key_file2(res, certfile,
1007 : keyfile, type, NULL,
1008 : 0);
1009 : }
1010 :
1011 : /**
1012 : * gnutls_certificate_set_x509_key_file2:
1013 : * @res: is a #gnutls_certificate_credentials_t type.
1014 : * @certfile: is a file that containing the certificate list (path) for
1015 : * the specified private key, in PKCS7 format, or a list of certificates
1016 : * @keyfile: is a file that contains the private key
1017 : * @type: is PEM or DER
1018 : * @pass: is the password of the key
1019 : * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
1020 : *
1021 : * This function sets a certificate/private key pair in the
1022 : * gnutls_certificate_credentials_t type. This function may be
1023 : * called more than once, in case multiple keys/certificates exist for
1024 : * the server. For clients that need to send more than its own end
1025 : * entity certificate, e.g., also an intermediate CA cert, then the
1026 : * @certfile must contain the ordered certificate chain.
1027 : *
1028 : * Note that the names in the certificate provided will be considered
1029 : * when selecting the appropriate certificate to use (in case of multiple
1030 : * certificate/key pairs).
1031 : *
1032 : * This function can also accept URLs at @keyfile and @certfile. In that case it
1033 : * will use the private key and certificate indicated by the URLs. Note
1034 : * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1035 : * Before GnuTLS 3.4.0 when a URL was specified, the @pass part was ignored and a
1036 : * PIN callback had to be registered, this is no longer the case in current releases.
1037 : *
1038 : * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
1039 : * present issuers in the token are imported (i.e., forming the required trust chain).
1040 : *
1041 : * If that function fails to load the @res structure is at an undefined state, it must
1042 : * not be reused to load other keys or certificates.
1043 : *
1044 : * Note that, this function by default returns zero on success and a negative value on error.
1045 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
1046 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
1047 : *
1048 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
1049 : *
1050 : **/
1051 : int
1052 368 : gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res,
1053 : const char *certfile,
1054 : const char *keyfile,
1055 : gnutls_x509_crt_fmt_t type,
1056 : const char *pass, unsigned int flags)
1057 : {
1058 368 : int ret;
1059 368 : gnutls_privkey_t rkey;
1060 :
1061 : /* this should be first
1062 : */
1063 368 : if ((ret = _gnutls_read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
1064 : return ret;
1065 :
1066 368 : if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) {
1067 2 : gnutls_privkey_deinit(rkey);
1068 2 : return ret;
1069 : }
1070 :
1071 366 : res->ncerts++;
1072 :
1073 366 : if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
1074 0 : gnutls_assert();
1075 0 : return ret;
1076 : }
1077 :
1078 366 : CRED_RET_SUCCESS(res);
1079 : }
1080 :
1081 : /**
1082 : * gnutls_certificate_set_x509_trust_mem:
1083 : * @res: is a #gnutls_certificate_credentials_t type.
1084 : * @ca: is a list of trusted CAs or a DER certificate
1085 : * @type: is DER or PEM
1086 : *
1087 : * This function adds the trusted CAs in order to verify client or
1088 : * server certificates. In case of a client this is not required to be
1089 : * called if the certificates are not verified using
1090 : * gnutls_certificate_verify_peers2(). This function may be called
1091 : * multiple times.
1092 : *
1093 : * In case of a server the CAs set here will be sent to the client if
1094 : * a certificate request is sent. This can be disabled using
1095 : * gnutls_certificate_send_x509_rdn_sequence().
1096 : *
1097 : * Returns: the number of certificates processed or a negative error code
1098 : * on error.
1099 : **/
1100 : int
1101 339 : gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials_t res,
1102 : const gnutls_datum_t * ca,
1103 : gnutls_x509_crt_fmt_t type)
1104 : {
1105 339 : int ret;
1106 :
1107 339 : ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, ca, NULL,
1108 : type, GNUTLS_TL_USE_IN_TLS, 0);
1109 339 : if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1110 1 : return 0;
1111 :
1112 : return ret;
1113 : }
1114 :
1115 : /**
1116 : * gnutls_certificate_set_x509_trust:
1117 : * @res: is a #gnutls_certificate_credentials_t type.
1118 : * @ca_list: is a list of trusted CAs
1119 : * @ca_list_size: holds the size of the CA list
1120 : *
1121 : * This function adds the trusted CAs in order to verify client
1122 : * or server certificates. In case of a client this is not required
1123 : * to be called if the certificates are not verified using
1124 : * gnutls_certificate_verify_peers2().
1125 : * This function may be called multiple times.
1126 : *
1127 : * In case of a server the CAs set here will be sent to the client if
1128 : * a certificate request is sent. This can be disabled using
1129 : * gnutls_certificate_send_x509_rdn_sequence().
1130 : *
1131 : * Returns: the number of certificates processed or a negative error code
1132 : * on error.
1133 : *
1134 : * Since: 2.4.0
1135 : **/
1136 : int
1137 0 : gnutls_certificate_set_x509_trust(gnutls_certificate_credentials_t res,
1138 : gnutls_x509_crt_t * ca_list,
1139 : int ca_list_size)
1140 : {
1141 0 : int ret, i, j;
1142 0 : gnutls_x509_crt_t *new_list = gnutls_malloc(ca_list_size * sizeof(gnutls_x509_crt_t));
1143 :
1144 0 : if (!new_list)
1145 : return GNUTLS_E_MEMORY_ERROR;
1146 :
1147 0 : for (i = 0; i < ca_list_size; i++) {
1148 0 : ret = gnutls_x509_crt_init(&new_list[i]);
1149 0 : if (ret < 0) {
1150 0 : gnutls_assert();
1151 0 : goto cleanup;
1152 : }
1153 :
1154 0 : ret = _gnutls_x509_crt_cpy(new_list[i], ca_list[i]);
1155 0 : if (ret < 0) {
1156 0 : gnutls_assert();
1157 0 : goto cleanup;
1158 : }
1159 : }
1160 :
1161 0 : ret =
1162 0 : gnutls_x509_trust_list_add_cas(res->tlist, new_list,
1163 : ca_list_size, GNUTLS_TL_USE_IN_TLS);
1164 0 : if (ret < 0) {
1165 0 : gnutls_assert();
1166 0 : goto cleanup;
1167 : }
1168 :
1169 0 : gnutls_free(new_list);
1170 0 : return ret;
1171 :
1172 0 : cleanup:
1173 0 : for (j = 0; j < i; j++)
1174 0 : gnutls_x509_crt_deinit(new_list[j]);
1175 0 : gnutls_free(new_list);
1176 :
1177 0 : return ret;
1178 : }
1179 :
1180 :
1181 : /**
1182 : * gnutls_certificate_set_x509_trust_file:
1183 : * @cred: is a #gnutls_certificate_credentials_t type.
1184 : * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1185 : * @type: is PEM or DER
1186 : *
1187 : * This function adds the trusted CAs in order to verify client or
1188 : * server certificates. In case of a client this is not required to
1189 : * be called if the certificates are not verified using
1190 : * gnutls_certificate_verify_peers2(). This function may be called
1191 : * multiple times.
1192 : *
1193 : * In case of a server the names of the CAs set here will be sent to
1194 : * the client if a certificate request is sent. This can be disabled
1195 : * using gnutls_certificate_send_x509_rdn_sequence().
1196 : *
1197 : * This function can also accept URLs. In that case it
1198 : * will import all certificates that are marked as trusted. Note
1199 : * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1200 : *
1201 : * Returns: the number of certificates processed
1202 : **/
1203 : int
1204 668 : gnutls_certificate_set_x509_trust_file(gnutls_certificate_credentials_t
1205 : cred, const char *cafile,
1206 : gnutls_x509_crt_fmt_t type)
1207 : {
1208 668 : int ret;
1209 :
1210 668 : ret = gnutls_x509_trust_list_add_trust_file(cred->tlist, cafile, NULL,
1211 : type, GNUTLS_TL_USE_IN_TLS, 0);
1212 668 : if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1213 115 : return 0;
1214 :
1215 : return ret;
1216 : }
1217 :
1218 : /**
1219 : * gnutls_certificate_set_x509_trust_dir:
1220 : * @cred: is a #gnutls_certificate_credentials_t type.
1221 : * @ca_dir: is a directory containing the list of trusted CAs (DER or PEM list)
1222 : * @type: is PEM or DER
1223 : *
1224 : * This function adds the trusted CAs present in the directory in order to
1225 : * verify client or server certificates. This function is identical
1226 : * to gnutls_certificate_set_x509_trust_file() but loads all certificates
1227 : * in a directory.
1228 : *
1229 : * Returns: the number of certificates processed
1230 : *
1231 : * Since: 3.3.6
1232 : *
1233 : **/
1234 : int
1235 0 : gnutls_certificate_set_x509_trust_dir(gnutls_certificate_credentials_t cred,
1236 : const char *ca_dir,
1237 : gnutls_x509_crt_fmt_t type)
1238 : {
1239 0 : int ret;
1240 :
1241 0 : ret = gnutls_x509_trust_list_add_trust_dir(cred->tlist, ca_dir, NULL,
1242 : type, GNUTLS_TL_USE_IN_TLS, 0);
1243 0 : if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1244 0 : return 0;
1245 :
1246 : return ret;
1247 : }
1248 :
1249 : /**
1250 : * gnutls_certificate_set_x509_system_trust:
1251 : * @cred: is a #gnutls_certificate_credentials_t type.
1252 : *
1253 : * This function adds the system's default trusted CAs in order to
1254 : * verify client or server certificates.
1255 : *
1256 : * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
1257 : * is returned.
1258 : *
1259 : * Returns: the number of certificates processed or a negative error code
1260 : * on error.
1261 : *
1262 : * Since: 3.0.20
1263 : **/
1264 : int
1265 1 : gnutls_certificate_set_x509_system_trust(gnutls_certificate_credentials_t
1266 : cred)
1267 : {
1268 1 : return gnutls_x509_trust_list_add_system_trust(cred->tlist,
1269 : GNUTLS_TL_USE_IN_TLS, 0);
1270 : }
1271 :
1272 : /**
1273 : * gnutls_certificate_set_x509_crl_mem:
1274 : * @res: is a #gnutls_certificate_credentials_t type.
1275 : * @CRL: is a list of trusted CRLs. They should have been verified before.
1276 : * @type: is DER or PEM
1277 : *
1278 : * This function adds the trusted CRLs in order to verify client or
1279 : * server certificates. In case of a client this is not required to
1280 : * be called if the certificates are not verified using
1281 : * gnutls_certificate_verify_peers2(). This function may be called
1282 : * multiple times.
1283 : *
1284 : * Returns: number of CRLs processed, or a negative error code on error.
1285 : **/
1286 : int
1287 1 : gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials_t res,
1288 : const gnutls_datum_t * CRL,
1289 : gnutls_x509_crt_fmt_t type)
1290 : {
1291 1 : unsigned flags = GNUTLS_TL_USE_IN_TLS;
1292 1 : int ret;
1293 :
1294 1 : if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
1295 0 : flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
1296 :
1297 1 : ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, NULL, CRL,
1298 : type, flags, 0);
1299 1 : if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1300 0 : return 0;
1301 :
1302 : return ret;
1303 : }
1304 :
1305 : /**
1306 : * gnutls_certificate_set_x509_crl:
1307 : * @res: is a #gnutls_certificate_credentials_t type.
1308 : * @crl_list: is a list of trusted CRLs. They should have been verified before.
1309 : * @crl_list_size: holds the size of the crl_list
1310 : *
1311 : * This function adds the trusted CRLs in order to verify client or
1312 : * server certificates. In case of a client this is not required to
1313 : * be called if the certificates are not verified using
1314 : * gnutls_certificate_verify_peers2(). This function may be called
1315 : * multiple times.
1316 : *
1317 : * Returns: number of CRLs processed, or a negative error code on error.
1318 : *
1319 : * Since: 2.4.0
1320 : **/
1321 : int
1322 1 : gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res,
1323 : gnutls_x509_crl_t * crl_list,
1324 : int crl_list_size)
1325 : {
1326 1 : int ret, i, j;
1327 1 : gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t));
1328 1 : unsigned flags = GNUTLS_TL_USE_IN_TLS;
1329 :
1330 1 : if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
1331 0 : flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
1332 :
1333 1 : if (!new_crl)
1334 : return GNUTLS_E_MEMORY_ERROR;
1335 :
1336 2 : for (i = 0; i < crl_list_size; i++) {
1337 1 : ret = gnutls_x509_crl_init(&new_crl[i]);
1338 1 : if (ret < 0) {
1339 0 : gnutls_assert();
1340 0 : goto cleanup;
1341 : }
1342 :
1343 1 : ret = _gnutls_x509_crl_cpy(new_crl[i], crl_list[i]);
1344 1 : if (ret < 0) {
1345 0 : gnutls_assert();
1346 0 : goto cleanup;
1347 : }
1348 : }
1349 :
1350 1 : ret =
1351 1 : gnutls_x509_trust_list_add_crls(res->tlist, new_crl,
1352 : crl_list_size, flags, 0);
1353 1 : if (ret < 0) {
1354 0 : gnutls_assert();
1355 0 : goto cleanup;
1356 : }
1357 :
1358 1 : free(new_crl);
1359 1 : return ret;
1360 :
1361 0 : cleanup:
1362 0 : for (j = 0; j < i; j++)
1363 0 : gnutls_x509_crl_deinit(new_crl[j]);
1364 0 : free(new_crl);
1365 :
1366 0 : return ret;
1367 : }
1368 :
1369 : /**
1370 : * gnutls_certificate_set_x509_crl_file:
1371 : * @res: is a #gnutls_certificate_credentials_t type.
1372 : * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1373 : * @type: is PEM or DER
1374 : *
1375 : * This function adds the trusted CRLs in order to verify client or server
1376 : * certificates. In case of a client this is not required
1377 : * to be called if the certificates are not verified using
1378 : * gnutls_certificate_verify_peers2().
1379 : * This function may be called multiple times.
1380 : *
1381 : * Returns: number of CRLs processed or a negative error code on error.
1382 : **/
1383 : int
1384 478 : gnutls_certificate_set_x509_crl_file(gnutls_certificate_credentials_t res,
1385 : const char *crlfile,
1386 : gnutls_x509_crt_fmt_t type)
1387 : {
1388 478 : int ret;
1389 478 : unsigned flags = GNUTLS_TL_USE_IN_TLS;
1390 :
1391 478 : if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
1392 1 : flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
1393 :
1394 478 : ret = gnutls_x509_trust_list_add_trust_file(res->tlist, NULL, crlfile,
1395 : type, flags, 0);
1396 478 : if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1397 0 : return 0;
1398 :
1399 : return ret;
1400 : }
1401 :
1402 : #include <gnutls/pkcs12.h>
1403 :
1404 :
1405 : /**
1406 : * gnutls_certificate_set_x509_simple_pkcs12_file:
1407 : * @res: is a #gnutls_certificate_credentials_t type.
1408 : * @pkcs12file: filename of file containing PKCS#12 blob.
1409 : * @type: is PEM or DER of the @pkcs12file.
1410 : * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1411 : *
1412 : * This function sets a certificate/private key pair and/or a CRL in
1413 : * the gnutls_certificate_credentials_t type. This function may
1414 : * be called more than once (in case multiple keys/certificates exist
1415 : * for the server).
1416 : *
1417 : * PKCS#12 files with a MAC, encrypted bags and PKCS #8
1418 : * private keys are supported. However,
1419 : * only password based security, and the same password for all
1420 : * operations, are supported.
1421 : *
1422 : * PKCS#12 file may contain many keys and/or certificates, and this
1423 : * function will try to auto-detect based on the key ID the certificate
1424 : * and key pair to use. If the PKCS#12 file contain the issuer of
1425 : * the selected certificate, it will be appended to the certificate
1426 : * to form a chain.
1427 : *
1428 : * If more than one private keys are stored in the PKCS#12 file,
1429 : * then only one key will be read (and it is undefined which one).
1430 : *
1431 : * It is believed that the limitations of this function is acceptable
1432 : * for most usage, and that any more flexibility would introduce
1433 : * complexity that would make it harder to use this functionality at
1434 : * all.
1435 : *
1436 : * Note that, this function by default returns zero on success and a negative value on error.
1437 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
1438 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
1439 : *
1440 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
1441 : *
1442 : **/
1443 : int
1444 5 : gnutls_certificate_set_x509_simple_pkcs12_file
1445 : (gnutls_certificate_credentials_t res, const char *pkcs12file,
1446 : gnutls_x509_crt_fmt_t type, const char *password) {
1447 5 : gnutls_datum_t p12blob;
1448 5 : size_t size;
1449 5 : int ret;
1450 :
1451 5 : p12blob.data = (void *) read_file(pkcs12file, RF_BINARY | RF_SENSITIVE,
1452 : &size);
1453 5 : p12blob.size = (unsigned int) size;
1454 5 : if (p12blob.data == NULL) {
1455 1 : gnutls_assert();
1456 1 : return GNUTLS_E_FILE_ERROR;
1457 : }
1458 :
1459 4 : ret =
1460 4 : gnutls_certificate_set_x509_simple_pkcs12_mem(res, &p12blob,
1461 : type, password);
1462 4 : zeroize_key(p12blob.data, p12blob.size);
1463 4 : free(p12blob.data);
1464 4 : p12blob.size = 0;
1465 :
1466 4 : return ret;
1467 : }
1468 :
1469 : /**
1470 : * gnutls_certificate_set_x509_simple_pkcs12_mem:
1471 : * @res: is a #gnutls_certificate_credentials_t type.
1472 : * @p12blob: the PKCS#12 blob.
1473 : * @type: is PEM or DER of the @pkcs12file.
1474 : * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1475 : *
1476 : * This function sets a certificate/private key pair and/or a CRL in
1477 : * the gnutls_certificate_credentials_t type. This function may
1478 : * be called more than once (in case multiple keys/certificates exist
1479 : * for the server).
1480 : *
1481 : * Encrypted PKCS#12 bags and PKCS#8 private keys are supported. However,
1482 : * only password based security, and the same password for all
1483 : * operations, are supported.
1484 : *
1485 : * PKCS#12 file may contain many keys and/or certificates, and this
1486 : * function will try to auto-detect based on the key ID the certificate
1487 : * and key pair to use. If the PKCS#12 file contain the issuer of
1488 : * the selected certificate, it will be appended to the certificate
1489 : * to form a chain.
1490 : *
1491 : * If more than one private keys are stored in the PKCS#12 file,
1492 : * then only one key will be read (and it is undefined which one).
1493 : *
1494 : * It is believed that the limitations of this function is acceptable
1495 : * for most usage, and that any more flexibility would introduce
1496 : * complexity that would make it harder to use this functionality at
1497 : * all.
1498 : *
1499 : * Note that, this function by default returns zero on success and a negative value on error.
1500 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
1501 : * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
1502 : *
1503 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
1504 : *
1505 : * Since: 2.8.0
1506 : **/
1507 : int
1508 4 : gnutls_certificate_set_x509_simple_pkcs12_mem
1509 : (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
1510 : gnutls_x509_crt_fmt_t type, const char *password) {
1511 4 : gnutls_pkcs12_t p12;
1512 4 : gnutls_x509_privkey_t key = NULL;
1513 4 : gnutls_x509_crt_t *chain = NULL;
1514 4 : gnutls_x509_crl_t crl = NULL;
1515 4 : unsigned int chain_size = 0, i;
1516 4 : int ret, idx;
1517 :
1518 4 : ret = gnutls_pkcs12_init(&p12);
1519 4 : if (ret < 0) {
1520 0 : gnutls_assert();
1521 0 : return ret;
1522 : }
1523 :
1524 4 : ret = gnutls_pkcs12_import(p12, p12blob, type, 0);
1525 4 : if (ret < 0) {
1526 0 : gnutls_assert();
1527 0 : gnutls_pkcs12_deinit(p12);
1528 0 : return ret;
1529 : }
1530 :
1531 4 : if (password) {
1532 4 : ret = gnutls_pkcs12_verify_mac(p12, password);
1533 4 : if (ret < 0) {
1534 0 : gnutls_assert();
1535 0 : gnutls_pkcs12_deinit(p12);
1536 0 : return ret;
1537 : }
1538 : }
1539 :
1540 4 : ret =
1541 4 : gnutls_pkcs12_simple_parse(p12, password, &key, &chain,
1542 : &chain_size, NULL, NULL, &crl, 0);
1543 4 : gnutls_pkcs12_deinit(p12);
1544 4 : if (ret < 0) {
1545 0 : gnutls_assert();
1546 0 : return ret;
1547 : }
1548 :
1549 4 : if (key && chain) {
1550 4 : ret =
1551 4 : gnutls_certificate_set_x509_key(res, chain, chain_size,
1552 : key);
1553 4 : if (ret < 0) {
1554 0 : gnutls_assert();
1555 0 : goto done;
1556 : }
1557 :
1558 4 : idx = ret;
1559 : } else {
1560 0 : gnutls_assert();
1561 0 : ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1562 0 : goto done;
1563 : }
1564 :
1565 4 : if (crl) {
1566 0 : ret = gnutls_certificate_set_x509_crl(res, &crl, 1);
1567 0 : if (ret < 0) {
1568 0 : gnutls_assert();
1569 0 : goto done;
1570 : }
1571 : }
1572 :
1573 4 : if (res->flags & GNUTLS_CERTIFICATE_API_V2)
1574 : ret = idx;
1575 : else
1576 4 : ret = 0;
1577 :
1578 4 : done:
1579 4 : if (chain) {
1580 9 : for (i = 0; i < chain_size; i++)
1581 5 : gnutls_x509_crt_deinit(chain[i]);
1582 4 : gnutls_free(chain);
1583 : }
1584 4 : if (key)
1585 4 : gnutls_x509_privkey_deinit(key);
1586 4 : if (crl)
1587 0 : gnutls_x509_crl_deinit(crl);
1588 :
1589 : return ret;
1590 : }
1591 :
1592 :
1593 :
1594 : /**
1595 : * gnutls_certificate_free_crls:
1596 : * @sc: is a #gnutls_certificate_credentials_t type.
1597 : *
1598 : * This function will delete all the CRLs associated
1599 : * with the given credentials.
1600 : **/
1601 0 : void gnutls_certificate_free_crls(gnutls_certificate_credentials_t sc)
1602 : {
1603 : /* do nothing for now */
1604 0 : return;
1605 : }
1606 :
1607 : /**
1608 : * gnutls_certificate_credentials_t:
1609 : * @cred: is a #gnutls_certificate_credentials_t type.
1610 : * @fn: A PIN callback
1611 : * @userdata: Data to be passed in the callback
1612 : *
1613 : * This function will set a callback function to be used when
1614 : * required to access a protected object. This function overrides any other
1615 : * global PIN functions.
1616 : *
1617 : * Note that this function must be called right after initialization
1618 : * to have effect.
1619 : *
1620 : * Since: 3.1.0
1621 : **/
1622 275 : void gnutls_certificate_set_pin_function(gnutls_certificate_credentials_t
1623 : cred, gnutls_pin_callback_t fn,
1624 : void *userdata)
1625 : {
1626 275 : cred->pin.cb = fn;
1627 275 : cred->pin.data = userdata;
1628 275 : }
|