Bug Summary

File:lib/gnutls_x509.c
Location:line 679, column 3
Description:Value stored to 'ret' is never read

Annotated Source Code

1/*
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GnuTLS.
7 *
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
20 *
21 */
22
23#include <gnutls_int.h>
24#include "gnutls_auth.h"
25#include "gnutls_errors.h"
26#include <auth/cert.h>
27#include "gnutls_dh.h"
28#include "gnutls_num.h"
29#include "gnutls_datum.h"
30#include <gnutls_pk.h>
31#include <algorithms.h>
32#include <gnutls_global.h>
33#include <gnutls_record.h>
34#include <gnutls_sig.h>
35#include <gnutls_state.h>
36#include <gnutls_pk.h>
37#include <gnutls_str.h>
38#include <debug.h>
39#include <x509_b64.h>
40#include <gnutls_x509.h>
41#include "x509/common.h"
42#include "x509/x509_int.h"
43#include <gnutls_str_array.h>
44#include "read-file.h"
45
46/*
47 * some x509 certificate parsing functions.
48 */
49
50/* Check if the number of bits of the key in the certificate
51 * is unacceptable.
52 */
53inline static int
54check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
55{
56 int ret;
57 unsigned int bits;
58
59 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
60 if (ret < 0)
61 {
62 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",62); } while(0);
;
63 return ret;
64 }
65
66 if (bits > max_bits && max_bits > 0)
67 {
68 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",68); } while(0);
;
69 return GNUTLS_E_CONSTRAINT_ERROR-101;
70 }
71
72 return 0;
73}
74
75
76#define CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) { if (peer_certificate_list
[x]) gnutls_x509_crt_deinit(peer_certificate_list[x]); } gnutls_free
( peer_certificate_list)
for(x=0;x<peer_certificate_list_size;x++) { \
77 if (peer_certificate_list[x]) \
78 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
79 } \
80 gnutls_free( peer_certificate_list)
81
82/*-
83 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
84 * @session: is a gnutls session
85 *
86 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
87 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
88 * However you must also check the peer's name in order to check if the verified certificate belongs to the
89 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
90 -*/
91int
92_gnutls_x509_cert_verify_peers (gnutls_session_t session,
93 unsigned int *status)
94{
95 cert_auth_info_t info;
96 gnutls_certificate_credentials_t cred;
97 gnutls_x509_crt_t *peer_certificate_list;
98 int peer_certificate_list_size, i, x, ret;
99
100 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST)if (gnutls_auth_get_type(session) != GNUTLS_CRD_CERTIFICATE) {
do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",100); } while(0);; return
-50; }
;
101
102 info = _gnutls_get_auth_info (session);
103 if (info == NULL((void*)0))
104 {
105 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",105); } while(0);
;
106 return GNUTLS_E_INVALID_REQUEST-50;
107 }
108
109 cred = (gnutls_certificate_credentials_t)
110 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
111 if (cred == NULL((void*)0))
112 {
113 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",113); } while(0);
;
114 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
115 }
116
117 if (info->raw_certificate_list == NULL((void*)0) || info->ncerts == 0)
118 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
119
120 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
121 {
122 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",122); } while(0);
;
123 return GNUTLS_E_CONSTRAINT_ERROR-101;
124 }
125
126 /* generate a list of gnutls_certs based on the auth info
127 * raw certs.
128 */
129 peer_certificate_list_size = info->ncerts;
130 peer_certificate_list =
131 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
132 if (peer_certificate_list == NULL((void*)0))
133 {
134 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",134); } while(0);
;
135 return GNUTLS_E_MEMORY_ERROR-25;
136 }
137
138 for (i = 0; i < peer_certificate_list_size; i++)
139 {
140 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
141 if (ret < 0)
142 {
143 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",143); } while(0);
;
144 CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) { if (peer_certificate_list
[x]) gnutls_x509_crt_deinit(peer_certificate_list[x]); } gnutls_free
( peer_certificate_list)
;
145 return ret;
146 }
147
148 ret =
149 gnutls_x509_crt_import (peer_certificate_list[i],
150 &info->raw_certificate_list[i],
151 GNUTLS_X509_FMT_DER);
152 if (ret < 0)
153 {
154 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",154); } while(0);
;
155 CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) { if (peer_certificate_list
[x]) gnutls_x509_crt_deinit(peer_certificate_list[x]); } gnutls_free
( peer_certificate_list)
;
156 return ret;
157 }
158
159 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
160 if (ret < 0)
161 {
162 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",162); } while(0);
;
163 CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) { if (peer_certificate_list
[x]) gnutls_x509_crt_deinit(peer_certificate_list[x]); } gnutls_free
( peer_certificate_list)
;
164 return ret;
165 }
166
167 }
168
169 /* Verify certificate
170 */
171
172 ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
173 peer_certificate_list_size,
174 cred->verify_flags | session->internals.
175 priorities.additional_verify_flags,
176 status, NULL((void*)0));
177
178 CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) { if (peer_certificate_list
[x]) gnutls_x509_crt_deinit(peer_certificate_list[x]); } gnutls_free
( peer_certificate_list)
;
179
180 if (ret < 0)
181 {
182 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",182); } while(0);
;
183 return ret;
184 }
185
186 return 0;
187}
188
189/*
190 * Read certificates and private keys, from files, memory etc.
191 */
192
193/* returns error if the certificate has different algorithm than
194 * the given key parameters.
195 */
196static int
197_gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
198{
199 unsigned int pk = gnutls_pubkey_get_pk_algorithm(res->certs[res->ncerts-1].cert_list[0].pubkey, NULL((void*)0));
200
201 if (gnutls_privkey_get_pk_algorithm (res->pkey[res->ncerts - 1], NULL((void*)0)) !=
202 pk)
203 {
204 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",204); } while(0);
;
205 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH-60;
206 }
207
208 return 0;
209}
210
211/* Returns the name of the certificate of a null name
212 */
213static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names)
214{
215size_t max_size;
216int i, ret = 0, ret2;
217char name[MAX_CN256];
218
219 for (i = 0; !(ret < 0); i++)
220 {
221 max_size = sizeof(name);
222
223 ret = gnutls_x509_crt_get_subject_alt_name(crt, i, name, &max_size, NULL((void*)0));
224 if (ret == GNUTLS_SAN_DNSNAME)
225 {
226 ret2 = _gnutls_str_array_append(names, name, max_size);
227 if (ret2 < 0)
228 {
229 _gnutls_str_array_clear(names);
230 return gnutls_assert_val(ret2)gnutls_assert_val_int(ret2, "gnutls_x509.c", 230);
231 }
232 }
233 }
234
235 max_size = sizeof(name);
236 ret = gnutls_x509_crt_get_dn_by_oid (crt, OID_X520_COMMON_NAME"2.5.4.3", 0, 0, name, &max_size);
237 if (ret >= 0)
238 {
239 ret = _gnutls_str_array_append(names, name, max_size);
240 if (ret < 0)
241 {
242 _gnutls_str_array_clear(names);
243 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 243);
244 }
245 }
246
247 return 0;
248}
249
250static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names)
251{
252int ret;
253gnutls_x509_crt_t crt;
254
255 ret = gnutls_x509_crt_init (&crt);
256 if (ret < 0)
257 {
258 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",258); } while(0);
;
259 return ret;
260 }
261
262 ret = gnutls_x509_crt_import (crt, raw, type);
263 if (ret < 0)
264 {
265 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",265); } while(0);
;
266 gnutls_x509_crt_deinit (crt);
267 return ret;
268 }
269
270 ret = get_x509_name(crt, names);
271 gnutls_x509_crt_deinit (crt);
272 return ret;
273}
274
275/* Reads a DER encoded certificate list from memory and stores it to a
276 * gnutls_cert structure. Returns the number of certificates parsed.
277 */
278static int
279parse_der_cert_mem (gnutls_certificate_credentials_t res,
280 const void *input_cert, int input_cert_size)
281{
282 gnutls_datum_t tmp;
283 gnutls_x509_crt_t crt;
284 gnutls_pcert_st *ccert;
285 int ret;
286 gnutls_str_array_t names;
287
288 _gnutls_str_array_init(&names);
289
290 ccert = gnutls_malloc (sizeof (*ccert));
291 if (ccert == NULL((void*)0))
292 {
293 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",293); } while(0);
;
294 return GNUTLS_E_MEMORY_ERROR-25;
295 }
296
297 ret = gnutls_x509_crt_init (&crt);
298 if (ret < 0)
299 {
300 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",300); } while(0);
;
301 goto cleanup;
302 }
303
304 tmp.data = (opaque *) input_cert;
305 tmp.size = input_cert_size;
306
307 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
308 if (ret < 0)
309 {
310 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",310); } while(0);
;
311 gnutls_x509_crt_deinit (crt);
312 goto cleanup;
313 }
314
315 ret = get_x509_name(crt, &names);
316 if (ret < 0)
317 {
318 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",318); } while(0);
;
319 gnutls_x509_crt_deinit (crt);
320 goto cleanup;
321 }
322
323 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
324 gnutls_x509_crt_deinit (crt);
325
326 if (ret < 0)
327 {
328 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",328); } while(0);
;
329 goto cleanup;
330 }
331
332 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
333 if (ret < 0)
334 {
335 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",335); } while(0);
;
336 goto cleanup;
337 }
338
339 return ret;
340
341cleanup:
342 _gnutls_str_array_clear(&names);
343 gnutls_free (ccert);
344 return ret;
345}
346
347/* Reads a base64 encoded certificate list from memory and stores it to
348 * a gnutls_cert structure. Returns the number of certificate parsed.
349 */
350static int
351parse_pem_cert_mem (gnutls_certificate_credentials_t res,
352 const char *input_cert, int input_cert_size)
353{
354 int size;
355 const char *ptr;
356 gnutls_datum_t tmp;
357 int ret, count, i;
358 gnutls_pcert_st *certs = NULL((void*)0);
359 gnutls_str_array_t names;
360
361 _gnutls_str_array_init(&names);
362
363 /* move to the certificate
364 */
365 ptr = memmemrpl_memmem (input_cert, input_cert_size,
366 PEM_CERT_SEP"-----BEGIN CERTIFICATE", sizeof (PEM_CERT_SEP"-----BEGIN CERTIFICATE") - 1);
367 if (ptr == NULL((void*)0))
368 ptr = memmemrpl_memmem (input_cert, input_cert_size,
369 PEM_CERT_SEP2"-----BEGIN X509 CERTIFICATE", sizeof (PEM_CERT_SEP2"-----BEGIN X509 CERTIFICATE") - 1);
370
371 if (ptr == NULL((void*)0))
372 {
373 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",373); } while(0);
;
374 return GNUTLS_E_BASE64_DECODING_ERROR-34;
375 }
376 size = input_cert_size - (ptr - input_cert);
377
378 count = 0;
379
380 do
381 {
382 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_pcert_st));
383
384 if (certs == NULL((void*)0))
385 {
386 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",386); } while(0);
;
387 ret = GNUTLS_E_MEMORY_ERROR-25;
388 goto cleanup;
389 }
390
391 tmp.data = (void*)ptr;
392 tmp.size = size;
393
394 if (count == 0)
395 {
396 ret = get_x509_name_raw(&tmp, GNUTLS_X509_FMT_PEM, &names);
397 if (ret < 0)
398 {
399 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",399); } while(0);
;
400 goto cleanup;
401 }
402 }
403
404 ret = gnutls_pcert_import_x509_raw (&certs[count], &tmp, GNUTLS_X509_FMT_PEM, 0);
405 if (ret < 0)
406 {
407 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",407); } while(0);
;
408 goto cleanup;
409 }
410
411 /* now we move ptr after the pem header
412 */
413 ptr++;
414 /* find the next certificate (if any)
415 */
416 size = input_cert_size - (ptr - input_cert);
417
418 if (size > 0)
419 {
420 char *ptr3;
421
422 ptr3 = memmemrpl_memmem (ptr, size, PEM_CERT_SEP"-----BEGIN CERTIFICATE", sizeof (PEM_CERT_SEP"-----BEGIN CERTIFICATE") - 1);
423 if (ptr3 == NULL((void*)0))
424 ptr3 = memmemrpl_memmem (ptr, size, PEM_CERT_SEP2"-----BEGIN X509 CERTIFICATE",
425 sizeof (PEM_CERT_SEP2"-----BEGIN X509 CERTIFICATE") - 1);
426
427 ptr = ptr3;
428 }
429 else
430 ptr = NULL((void*)0);
431
432 count++;
433
434 }
435 while (ptr != NULL((void*)0));
436
437 ret = certificate_credential_append_crt_list (res, names, certs, count);
438 if (ret < 0)
439 {
440 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",440); } while(0);
;
441 goto cleanup;
442 }
443
444 return count;
445
446cleanup:
447 _gnutls_str_array_clear(&names);
448 for (i=0;i<count;i++)
449 gnutls_pcert_deinit(&certs[i]);
450 gnutls_free(certs);
451 return ret;
452}
453
454
455
456/* Reads a DER or PEM certificate from memory
457 */
458static int
459read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
460 int cert_size, gnutls_x509_crt_fmt_t type)
461{
462 int ret;
463
464 if (type == GNUTLS_X509_FMT_DER)
465 ret = parse_der_cert_mem (res, cert, cert_size);
466 else
467 ret = parse_pem_cert_mem (res, cert, cert_size);
468
469 if (ret < 0)
470 {
471 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",471); } while(0);
;
472 return ret;
473 }
474
475 return ret;
476}
477
478static int
479_gnutls_x509_raw_privkey_to_privkey (gnutls_privkey_t * privkey,
480 const gnutls_datum_t * raw_key,
481 gnutls_x509_crt_fmt_t type)
482{
483 gnutls_x509_privkey_t tmpkey;
484 int ret;
485
486 ret = gnutls_x509_privkey_init (&tmpkey);
487 if (ret < 0)
488 {
489 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",489); } while(0);
;
490 return ret;
491 }
492
493 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
494 if (ret < 0)
495 {
496 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",496); } while(0);
;
497 gnutls_x509_privkey_deinit (tmpkey);
498 return ret;
499 }
500
501 ret = gnutls_privkey_init (privkey);
502 if (ret < 0)
503 {
504 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",504); } while(0);
;
505 gnutls_x509_privkey_deinit (tmpkey);
506 return ret;
507 }
508
509 ret =
510 gnutls_privkey_import_x509 (*privkey, tmpkey,
511 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE(1<<0));
512 if (ret < 0)
513 {
514 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",514); } while(0);
;
515 gnutls_x509_privkey_deinit (tmpkey);
516 gnutls_privkey_deinit (*privkey);
517 return ret;
518 }
519
520 return 0;
521}
522
523/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
524 * indicates the certificate format. KEY can be NULL, to indicate
525 * that GnuTLS doesn't know the private key.
526 */
527static int
528read_key_mem (gnutls_certificate_credentials_t res,
529 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
530{
531 int ret;
532 gnutls_datum_t tmp;
533 gnutls_privkey_t privkey;
534
535 if (key)
536 {
537 tmp.data = (opaque *) key;
538 tmp.size = key_size;
539
540 ret = _gnutls_x509_raw_privkey_to_privkey (&privkey, &tmp, type);
541 if (ret < 0)
542 {
543 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",543); } while(0);
;
544 return ret;
545 }
546
547 ret = certificate_credentials_append_pkey (res, privkey);
548 if (ret < 0)
549 {
550 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",550); } while(0);
;
551 gnutls_privkey_deinit (privkey);
552 return ret;
553 }
554
555 }
556 else
557 {
558 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",558); } while(0);
;
559 return GNUTLS_E_INVALID_REQUEST-50;
560 }
561
562
563 return 0;
564}
565
566#ifdef ENABLE_PKCS111
567
568/* Reads a private key from a token.
569 */
570static int
571read_key_url (gnutls_certificate_credentials_t res, const char *url)
572{
573 int ret;
574 gnutls_pkcs11_privkey_t key1 = NULL((void*)0);
575 gnutls_privkey_t pkey = NULL((void*)0);
576
577 /* allocate space for the pkey list
578 */
579
580 ret = gnutls_pkcs11_privkey_init (&key1);
581 if (ret < 0)
582 {
583 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",583); } while(0);
;
584 return ret;
585 }
586
587 ret = gnutls_pkcs11_privkey_import_url (key1, url, 0);
588 if (ret < 0)
589 {
590 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",590); } while(0);
;
591 goto cleanup;
592 }
593
594 ret = gnutls_privkey_init (&pkey);
595 if (ret < 0)
596 {
597 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",597); } while(0);
;
598 goto cleanup;
599 }
600
601 ret =
602 gnutls_privkey_import_pkcs11 (pkey, key1,
603 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE(1<<0));
604 if (ret < 0)
605 {
606 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",606); } while(0);
;
607 goto cleanup;
608 }
609
610 ret = certificate_credentials_append_pkey (res, pkey);
611 if (ret < 0)
612 {
613 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",613); } while(0);
;
614 goto cleanup;
615 }
616
617 return 0;
618
619cleanup:
620 if (pkey)
621 gnutls_privkey_deinit (pkey);
622
623 if (key1)
624 gnutls_pkcs11_privkey_deinit (key1);
625
626 return ret;
627}
628
629/* Reads a private key from a token.
630 */
631static int
632read_cas_url (gnutls_certificate_credentials_t res, const char *url)
633{
634 int ret;
635 gnutls_x509_crt_t *xcrt_list = NULL((void*)0);
636 gnutls_pkcs11_obj_t *pcrt_list = NULL((void*)0);
637 unsigned int pcrt_list_size = 0;
638
639 /* FIXME: should we use login? */
640 ret =
641 gnutls_pkcs11_obj_list_import_url (NULL((void*)0), &pcrt_list_size, url,
642 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
643 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER-51)
644 {
645 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",645); } while(0);
;
646 return ret;
647 }
648
649 if (pcrt_list_size == 0)
650 {
651 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",651); } while(0);
;
652 return 0;
653 }
654
655 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
656 if (pcrt_list == NULL((void*)0))
657 {
658 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",658); } while(0);
;
659 return GNUTLS_E_MEMORY_ERROR-25;
660 }
661
662 ret =
663 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
664 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
665 if (ret < 0)
666 {
667 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",667); } while(0);
;
668 goto cleanup;
669 }
670
671 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
672 if (xcrt_list == NULL((void*)0))
673 {
674 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",674); } while(0);
;
675 ret = GNUTLS_E_MEMORY_ERROR-25;
676 goto cleanup;
677 }
678
679 ret =
Value stored to 'ret' is never read
680 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
681 0);
682 if (xcrt_list == NULL((void*)0))
683 {
684 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",684); } while(0);
;
685 ret = GNUTLS_E_MEMORY_ERROR-25;
686 goto cleanup;
687 }
688
689 ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
690 if (ret < 0)
691 {
692 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",692); } while(0);
;
693 goto cleanup;
694 }
695
696cleanup:
697 gnutls_free (xcrt_list);
698 gnutls_free (pcrt_list);
699
700 return ret;
701
702}
703
704
705/* Reads a private key from a token.
706 */
707static int
708read_cert_url (gnutls_certificate_credentials_t res, const char *url)
709{
710 int ret;
711 gnutls_x509_crt_t crt;
712 gnutls_pcert_st *ccert;
713 gnutls_str_array_t names;
714
715 _gnutls_str_array_init(&names);
716
717 ccert = gnutls_malloc (sizeof (*ccert));
718 if (ccert == NULL((void*)0))
719 {
720 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",720); } while(0);
;
721 return GNUTLS_E_MEMORY_ERROR-25;
722 }
723
724 ret = gnutls_x509_crt_init (&crt);
725 if (ret < 0)
726 {
727 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",727); } while(0);
;
728 goto cleanup;
729 }
730
731 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
732 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56)
733 ret =
734 gnutls_x509_crt_import_pkcs11_url (crt, url,
735 GNUTLS_PKCS11_OBJ_FLAG_LOGIN(1<<0));
736
737 if (ret < 0)
738 {
739 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",739); } while(0);
;
740 gnutls_x509_crt_deinit (crt);
741 goto cleanup;
742 }
743
744 ret = get_x509_name(crt, &names);
745 if (ret < 0)
746 {
747 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",747); } while(0);
;
748 gnutls_x509_crt_deinit (crt);
749 goto cleanup;
750 }
751
752 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
753 gnutls_x509_crt_deinit (crt);
754
755 if (ret < 0)
756 {
757 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",757); } while(0);
;
758 goto cleanup;
759 }
760
761 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
762 if (ret < 0)
763 {
764 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",764); } while(0);
;
765 goto cleanup;
766 }
767
768 return 0;
769
770cleanup:
771 _gnutls_str_array_clear(&names);
772 gnutls_free (ccert);
773 return ret;
774}
775
776#endif /* ENABLE_PKCS11 */
777
778/* Reads a certificate file
779 */
780static int
781read_cert_file (gnutls_certificate_credentials_t res,
782 const char *certfile, gnutls_x509_crt_fmt_t type)
783{
784 int ret;
785 size_t size;
786 char *data;
787
788#ifdef ENABLE_PKCS111
789 if (strncmp (certfile, "pkcs11:", 7) == 0)
790 {
791 return read_cert_url (res, certfile);
792 }
793#endif /* ENABLE_PKCS11 */
794
795 data = read_binary_file_gnutls_read_binary_file (certfile, &size);
796
797 if (data == NULL((void*)0))
798 {
799 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",799); } while(0);
;
800 return GNUTLS_E_FILE_ERROR-64;
801 }
802
803 ret = read_cert_mem (res, data, size, type);
804 free (data);
805
806 return ret;
807
808}
809
810
811
812/* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
813 * stores it).
814 */
815static int
816read_key_file (gnutls_certificate_credentials_t res,
817 const char *keyfile, gnutls_x509_crt_fmt_t type)
818{
819 int ret;
820 size_t size;
821 char *data;
822
823#ifdef ENABLE_PKCS111
824 if (strncmp (keyfile, "pkcs11:", 7) == 0)
825 {
826 return read_key_url (res, keyfile);
827 }
828#endif /* ENABLE_PKCS11 */
829
830 data = read_binary_file_gnutls_read_binary_file (keyfile, &size);
831
832 if (data == NULL((void*)0))
833 {
834 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",834); } while(0);
;
835 return GNUTLS_E_FILE_ERROR-64;
836 }
837
838 ret = read_key_mem (res, data, size, type);
839 free (data);
840
841 return ret;
842}
843
844/**
845 * gnutls_certificate_set_x509_key_mem:
846 * @res: is a #gnutls_certificate_credentials_t structure.
847 * @cert: contains a certificate list (path) for the specified private key
848 * @key: is the private key, or %NULL
849 * @type: is PEM or DER
850 *
851 * This function sets a certificate/private key pair in the
852 * gnutls_certificate_credentials_t structure. This function may be called
853 * more than once, in case multiple keys/certificates exist for the
854 * server.
855 *
856 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
857 * is supported. This means that certificates intended for signing cannot
858 * be used for ciphersuites that require encryption.
859 *
860 * If the certificate and the private key are given in PEM encoding
861 * then the strings that hold their values must be null terminated.
862 *
863 * The @key may be %NULL if you are using a sign callback, see
864 * gnutls_sign_callback_set().
865 *
866 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
867 **/
868int
869gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
870 const gnutls_datum_t * cert,
871 const gnutls_datum_t * key,
872 gnutls_x509_crt_fmt_t type)
873{
874 int ret;
875
876 /* this should be first
877 */
878 if ((ret = read_key_mem (res, key ? key->data : NULL((void*)0),
879 key ? key->size : 0, type)) < 0)
880 return ret;
881
882 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
883 return ret;
884
885 res->ncerts++;
886
887 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
888 {
889 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",889); } while(0);
;
890 return ret;
891 }
892
893 return 0;
894}
895
896static int check_if_sorted(gnutls_pcert_st * crt, int nr)
897{
898gnutls_x509_crt_t x509;
899char prev_dn[MAX_DN1024];
900char dn[MAX_DN1024];
901size_t prev_dn_size, dn_size;
902int i, ret;
903
904 /* check if the X.509 list is ordered */
905 if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
906 {
907
908 for (i=0;i<nr;i++)
909 {
910 ret = gnutls_x509_crt_init(&x509);
911 if (ret < 0)
912 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 912);
913
914 ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
915 if (ret < 0)
916 {
917 ret = gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 917);
918 goto cleanup;
919 }
920
921 if (i>0)
922 {
923 dn_size = sizeof(dn);
924 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
925 if (ret < 0)
926 {
927 ret = gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 927);
928 goto cleanup;
929 }
930
931 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
932 {
933 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED)gnutls_assert_val_int(-324, "gnutls_x509.c", 933);
934 goto cleanup;
935 }
936 }
937
938 prev_dn_size = sizeof(prev_dn);
939 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
940 if (ret < 0)
941 {
942 ret = gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 942);
943 goto cleanup;
944 }
945
946 gnutls_x509_crt_deinit(x509);
947 }
948 }
949
950 return 0;
951
952cleanup:
953 gnutls_x509_crt_deinit(x509);
954 return ret;
955}
956
957int
958certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
959 gnutls_str_array_t names, gnutls_pcert_st * crt, int nr)
960{
961int ret;
962
963 ret = check_if_sorted(crt, nr);
964 if (ret < 0)
965 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 965);
966
967 res->certs = gnutls_realloc_fast (res->certs,
968 (1 + res->ncerts) *
969 sizeof (certs_st));
970 if (res->certs == NULL((void*)0))
971 {
972 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",972); } while(0);
;
973 return GNUTLS_E_MEMORY_ERROR-25;
974 }
975
976 res->certs[res->ncerts].cert_list = crt;
977 res->certs[res->ncerts].cert_list_length = nr;
978 res->certs[res->ncerts].names = names;
979
980 return 0;
981
982}
983
984int
985certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
986 gnutls_privkey_t pkey)
987{
988 res->pkey = gnutls_realloc_fast (res->pkey,
989 (1 + res->ncerts) *
990 sizeof (gnutls_privkey_t));
991 if (res->pkey == NULL((void*)0))
992 {
993 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",993); } while(0);
;
994 return GNUTLS_E_MEMORY_ERROR-25;
995 }
996 res->pkey[res->ncerts] = pkey;
997 return 0;
998
999}
1000
1001/**
1002 * gnutls_certificate_set_x509_key:
1003 * @res: is a #gnutls_certificate_credentials_t structure.
1004 * @cert_list: contains a certificate list (path) for the specified private key
1005 * @cert_list_size: holds the size of the certificate list
1006 * @key: is a gnutls_x509_privkey_t key
1007 *
1008 * This function sets a certificate/private key pair in the
1009 * gnutls_certificate_credentials_t structure. This function may be
1010 * called more than once, in case multiple keys/certificates exist for
1011 * the server. For clients that wants to send more than its own end
1012 * entity certificate (e.g., also an intermediate CA cert) then put
1013 * the certificate chain in @cert_list.
1014 *
1015 *
1016 *
1017 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1018 *
1019 * Since: 2.4.0
1020 **/
1021int
1022gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
1023 gnutls_x509_crt_t * cert_list,
1024 int cert_list_size,
1025 gnutls_x509_privkey_t key)
1026{
1027 int ret, i;
1028 gnutls_privkey_t pkey;
1029 gnutls_pcert_st *pcerts = NULL((void*)0);
1030 gnutls_str_array_t names;
1031
1032 _gnutls_str_array_init(&names);
1033
1034 /* this should be first
1035 */
1036 ret = gnutls_privkey_init (&pkey);
1037 if (ret < 0)
1038 {
1039 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1039); } while(0);
;
1040 return ret;
1041 }
1042
1043 ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY(1<<1));
1044 if (ret < 0)
1045 {
1046 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1046); } while(0);
;
1047 return ret;
1048 }
1049
1050 ret = certificate_credentials_append_pkey (res, pkey);
1051 if (ret < 0)
1052 {
1053 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1053); } while(0);
;
1054 return ret;
1055 }
1056
1057 /* load certificates */
1058 pcerts = gnutls_malloc (sizeof (gnutls_pcert_st) * cert_list_size);
1059 if (pcerts == NULL((void*)0))
1060 {
1061 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1061); } while(0);
;
1062 return GNUTLS_E_MEMORY_ERROR-25;
1063 }
1064
1065 ret = get_x509_name(cert_list[0], &names);
1066 if (ret < 0)
1067 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 1067);
1068
1069 for (i = 0; i < cert_list_size; i++)
1070 {
1071 ret = gnutls_pcert_import_x509 (&pcerts[i], cert_list[i], 0);
1072 if (ret < 0)
1073 {
1074 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1074); } while(0);
;
1075 goto cleanup;
1076 }
1077 }
1078
1079 ret = certificate_credential_append_crt_list (res, names, pcerts, cert_list_size);
1080 if (ret < 0)
1081 {
1082 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1082); } while(0);
;
1083 goto cleanup;
1084 }
1085
1086 res->ncerts++;
1087
1088 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1089 {
1090 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1090); } while(0);
;
1091 return ret;
1092 }
1093
1094 return 0;
1095
1096cleanup:
1097 _gnutls_str_array_clear(&names);
1098 return ret;
1099}
1100
1101/**
1102 * gnutls_certificate_set_key:
1103 * @res: is a #gnutls_certificate_credentials_t structure.
1104 * @names: is an array of DNS name of the certificate (NULL if none)
1105 * @names_size: holds the size of the names list
1106 * @pcert_list: contains a certificate list (path) for the specified private key
1107 * @pcert_list_size: holds the size of the certificate list
1108 * @key: is a gnutls_x509_privkey_t key
1109 *
1110 * This function sets a certificate/private key pair in the
1111 * gnutls_certificate_credentials_t structure. This function may be
1112 * called more than once, in case multiple keys/certificates exist for
1113 * the server. For clients that wants to send more than its own end
1114 * entity certificate (e.g., also an intermediate CA cert) then put
1115 * the certificate chain in @pcert_list. The @pcert_list and @key will
1116 * become part of the credentials structure and must not
1117 * be deallocated. They will be automatically deallocated when
1118 * @res is deinitialized.
1119 *
1120 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1121 *
1122 * Since: 3.0.0
1123 **/
1124int
1125gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
1126 const char** names,
1127 int names_size,
1128 gnutls_pcert_st * pcert_list,
1129 int pcert_list_size,
1130 gnutls_privkey_t key)
1131{
1132 int ret, i;
1133 gnutls_str_array_t str_names;
1134
1135 _gnutls_str_array_init(&str_names);
1136
1137 if (names != NULL((void*)0) && names_size > 0)
1138 {
1139 for (i=0;i<names_size;i++)
1140 {
1141 ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
1142 if (ret < 0)
1143 {
1144 ret = gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_x509.c", 1144);
1145 goto cleanup;
1146 }
1147 }
1148 }
1149
1150 ret = certificate_credentials_append_pkey (res, key);
1151 if (ret < 0)
1152 {
1153 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1153); } while(0);
;
1154 goto cleanup;
1155 }
1156
1157 ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
1158 if (ret < 0)
1159 {
1160 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1160); } while(0);
;
1161 goto cleanup;
1162 }
1163
1164 res->ncerts++;
1165
1166 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1167 {
1168 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1168); } while(0);
;
1169 return ret;
1170 }
1171
1172 return 0;
1173
1174cleanup:
1175 _gnutls_str_array_clear(&str_names);
1176 return ret;
1177}
1178
1179/**
1180 * gnutls_certificate_set_x509_key_file:
1181 * @res: is a #gnutls_certificate_credentials_t structure.
1182 * @certfile: is a file that containing the certificate list (path) for
1183 * the specified private key, in PKCS7 format, or a list of certificates
1184 * @keyfile: is a file that contains the private key
1185 * @type: is PEM or DER
1186 *
1187 * This function sets a certificate/private key pair in the
1188 * gnutls_certificate_credentials_t structure. This function may be
1189 * called more than once, in case multiple keys/certificates exist for
1190 * the server. For clients that need to send more than its own end
1191 * entity certificate, e.g., also an intermediate CA cert, then the
1192 * @certfile must contain the ordered certificate chain.
1193 *
1194 * This function can also accept PKCS #11 URLs at @keyfile and @certfile. In that case it
1195 * will import the private key and certificate indicated by the URLs.
1196 *
1197 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1198 **/
1199int
1200gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1201 const char *certfile,
1202 const char *keyfile,
1203 gnutls_x509_crt_fmt_t type)
1204{
1205 int ret;
1206
1207 /* this should be first
1208 */
1209 if ((ret = read_key_file (res, keyfile, type)) < 0)
1210 return ret;
1211
1212 if ((ret = read_cert_file (res, certfile, type)) < 0)
1213 return ret;
1214
1215 res->ncerts++;
1216
1217 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1218 {
1219 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1219); } while(0);
;
1220 return ret;
1221 }
1222
1223 return 0;
1224}
1225
1226static int
1227add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
1228 unsigned int crt_size)
1229{
1230 gnutls_datum_t tmp;
1231 int ret;
1232 size_t newsize;
1233 unsigned char *newdata;
1234 unsigned i;
1235
1236 /* Add DN of the last added CAs to the RDN sequence
1237 * This will be sent to clients when a certificate
1238 * request message is sent.
1239 */
1240
1241 /* FIXME: in case of a client it is not needed
1242 * to do that. This would save time and memory.
1243 * However we don't have that information available
1244 * here.
1245 * Further, this function is now much more efficient,
1246 * so optimizing that is less important.
1247 */
1248
1249 for (i = 0; i < crt_size; i++)
1250 {
1251 if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
1252 {
1253 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1253); } while(0);
;
1254 return ret;
1255 }
1256
1257 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1258 if (newsize < res->x509_rdn_sequence.size)
1259 {
1260 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1260); } while(0);
;
1261 _gnutls_free_datum (&tmp)_gnutls_free_datum_m(&tmp, gnutls_free);
1262 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
1263 }
1264
1265 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1266 if (newdata == NULL((void*)0))
1267 {
1268 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1268); } while(0);
;
1269 _gnutls_free_datum (&tmp)_gnutls_free_datum_m(&tmp, gnutls_free);
1270 return GNUTLS_E_MEMORY_ERROR-25;
1271 }
1272
1273 _gnutls_write_datum16 (newdata + res->x509_rdn_sequence.size, tmp);
1274 _gnutls_free_datum (&tmp)_gnutls_free_datum_m(&tmp, gnutls_free);
1275
1276 res->x509_rdn_sequence.size = newsize;
1277 res->x509_rdn_sequence.data = newdata;
1278 }
1279
1280 return 0;
1281}
1282
1283/* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1284 * certificate (uses the KeyUsage field).
1285 */
1286int
1287_gnutls_check_key_usage (const gnutls_pcert_st* cert, gnutls_kx_algorithm_t alg)
1288{
1289 unsigned int key_usage = 0;
1290 int encipher_type;
1291
1292 if (cert == NULL((void*)0))
1293 {
1294 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1294); } while(0);
;
1295 return GNUTLS_E_INTERNAL_ERROR-59;
1296 }
1297
1298 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1299 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1300 {
1301
1302 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
1303
1304 encipher_type = _gnutls_kx_encipher_type (alg);
1305
1306 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1307 {
1308 /* If key_usage has been set in the certificate
1309 */
1310
1311 if (encipher_type == CIPHER_ENCRYPT)
1312 {
1313 /* If the key exchange method requires an encipher
1314 * type algorithm, and key's usage does not permit
1315 * encipherment, then fail.
1316 */
1317 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT32))
1318 {
1319 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1319); } while(0);
;
1320 return GNUTLS_E_KEY_USAGE_VIOLATION-48;
1321 }
1322 }
1323
1324 if (encipher_type == CIPHER_SIGN)
1325 {
1326 /* The same as above, but for sign only keys
1327 */
1328 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE128))
1329 {
1330 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1330); } while(0);
;
1331 return GNUTLS_E_KEY_USAGE_VIOLATION-48;
1332 }
1333 }
1334 }
1335 }
1336 return 0;
1337}
1338
1339static int
1340parse_pem_ca_mem (gnutls_certificate_credentials_t res,
1341 const opaque * input_cert, int input_cert_size)
1342{
1343 gnutls_x509_crt_t *x509_cert_list;
1344 unsigned int x509_ncerts;
1345 gnutls_datum_t tmp;
1346 int ret;
1347
1348 tmp.data = (void*)input_cert;
1349 tmp.size = input_cert_size;
1350
1351 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
1352 GNUTLS_X509_FMT_PEM, 0);
1353 if (ret < 0)
1354 {
1355 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1355); } while(0);
;
1356 return ret;
1357 }
1358
1359 if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
1360 {
1361 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1361); } while(0);
;
1362 goto cleanup;
1363 }
1364
1365 ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
1366 if (ret < 0)
1367 {
1368 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1368); } while(0);
;
1369 goto cleanup;
1370 }
1371
1372cleanup:
1373 gnutls_free(x509_cert_list);
1374 return ret;
1375}
1376
1377/* Reads a DER encoded certificate list from memory and stores it to a
1378 * gnutls_cert structure. Returns the number of certificates parsed.
1379 */
1380static int
1381parse_der_ca_mem (gnutls_certificate_credentials_t res,
1382 const void *input_cert, int input_cert_size)
1383{
1384 gnutls_x509_crt_t crt;
1385 gnutls_datum_t tmp;
1386 int ret;
1387
1388 tmp.data = (void*)input_cert;
1389 tmp.size = input_cert_size;
1390
1391 ret = gnutls_x509_crt_init( &crt);
1392 if (ret < 0)
1393 {
1394 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1394); } while(0);
;
1395 return ret;
1396 }
1397
1398 ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
1399 if (ret < 0)
1400 {
1401 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1401); } while(0);
;
1402 goto cleanup;
1403 }
1404
1405 if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
1406 {
1407 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1407); } while(0);
;
1408 goto cleanup;
1409 }
1410
1411 ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
1412 if (ret < 0)
1413 {
1414 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1414); } while(0);
;
1415 goto cleanup;
1416 }
1417
1418 return ret;
1419
1420cleanup:
1421 gnutls_x509_crt_deinit(crt);
1422 return ret;
1423}
1424
1425/**
1426 * gnutls_certificate_set_x509_trust_mem:
1427 * @res: is a #gnutls_certificate_credentials_t structure.
1428 * @ca: is a list of trusted CAs or a DER certificate
1429 * @type: is DER or PEM
1430 *
1431 * This function adds the trusted CAs in order to verify client or
1432 * server certificates. In case of a client this is not required to be
1433 * called if the certificates are not verified using
1434 * gnutls_certificate_verify_peers2(). This function may be called
1435 * multiple times.
1436 *
1437 * In case of a server the CAs set here will be sent to the client if
1438 * a certificate request is sent. This can be disabled using
1439 * gnutls_certificate_send_x509_rdn_sequence().
1440 *
1441 * Returns: the number of certificates processed or a negative error code
1442 * on error.
1443 **/
1444int
1445gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1446 const gnutls_datum_t * ca,
1447 gnutls_x509_crt_fmt_t type)
1448{
1449 int ret;
1450
1451 if (type == GNUTLS_X509_FMT_DER)
1452 ret = parse_der_ca_mem (res,
1453 ca->data, ca->size);
1454 else
1455 ret = parse_pem_ca_mem (res,
1456 ca->data, ca->size);
1457
1458 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND-49)
1459 return 0;
1460
1461 return ret;
1462}
1463
1464/**
1465 * gnutls_certificate_set_x509_trust:
1466 * @res: is a #gnutls_certificate_credentials_t structure.
1467 * @ca_list: is a list of trusted CAs
1468 * @ca_list_size: holds the size of the CA list
1469 *
1470 * This function adds the trusted CAs in order to verify client
1471 * or server certificates. In case of a client this is not required
1472 * to be called if the certificates are not verified using
1473 * gnutls_certificate_verify_peers2().
1474 * This function may be called multiple times.
1475 *
1476 * In case of a server the CAs set here will be sent to the client if
1477 * a certificate request is sent. This can be disabled using
1478 * gnutls_certificate_send_x509_rdn_sequence().
1479 *
1480 * Returns: the number of certificates processed or a negative error code
1481 * on error.
1482 *
1483 * Since: 2.4.0
1484 **/
1485int
1486gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1487 gnutls_x509_crt_t * ca_list,
1488 int ca_list_size)
1489{
1490 int ret, i, j;
1491 gnutls_x509_crt_t new_list[ca_list_size];
1492
1493 for (i = 0; i < ca_list_size; i++)
1494 {
1495 ret = gnutls_x509_crt_init (&new_list[i]);
1496 if (ret < 0)
1497 {
1498 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1498); } while(0);
;
1499 goto cleanup;
1500 }
1501
1502 ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
1503 if (ret < 0)
1504 {
1505 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1505); } while(0);
;
1506 goto cleanup;
1507 }
1508 }
1509
1510 if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
1511 {
1512 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1512); } while(0);
;
1513 goto cleanup;
1514 }
1515
1516 ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
1517 if (ret < 0)
1518 {
1519 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1519); } while(0);
;
1520 goto cleanup;
1521 }
1522
1523 return ret;
1524
1525cleanup:
1526 for (j=0;j<i;i++)
1527 gnutls_x509_crt_deinit(new_list[j]);
1528
1529 return ret;
1530}
1531
1532
1533/**
1534 * gnutls_certificate_set_x509_trust_file:
1535 * @cred: is a #gnutls_certificate_credentials_t structure.
1536 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1537 * @type: is PEM or DER
1538 *
1539 * This function adds the trusted CAs in order to verify client or
1540 * server certificates. In case of a client this is not required to
1541 * be called if the certificates are not verified using
1542 * gnutls_certificate_verify_peers2(). This function may be called
1543 * multiple times.
1544 *
1545 * In case of a server the names of the CAs set here will be sent to
1546 * the client if a certificate request is sent. This can be disabled
1547 * using gnutls_certificate_send_x509_rdn_sequence().
1548 *
1549 * This function can also accept PKCS #11 URLs. In that case it
1550 * will import all certificates that are marked as trusted.
1551 *
1552 * Returns: number of certificates processed, or a negative error code on
1553 * error.
1554 **/
1555int
1556gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred,
1557 const char *cafile,
1558 gnutls_x509_crt_fmt_t type)
1559{
1560 int ret;
1561 gnutls_datum_t cas;
1562 size_t size;
1563
1564#ifdef ENABLE_PKCS111
1565 if (strncmp (cafile, "pkcs11:", 7) == 0)
1566 {
1567 return read_cas_url (cred, cafile);
1568 }
1569#endif
1570
1571 cas.data = read_binary_file_gnutls_read_binary_file (cafile, &size);
1572 if (cas.data == NULL((void*)0))
1573 {
1574 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1574); } while(0);
;
1575 return GNUTLS_E_FILE_ERROR-64;
1576 }
1577
1578 cas.size = size;
1579
1580 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, type);
1581
1582 free (cas.data);
1583
1584 if (ret < 0)
1585 {
1586 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1586); } while(0);
;
1587 return ret;
1588 }
1589
1590 return ret;
1591}
1592
1593#ifdef ENABLE_PKI1
1594
1595static int
1596parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
1597 const opaque * input_crl, int input_crl_size)
1598{
1599 gnutls_x509_crl_t *x509_crl_list;
1600 unsigned int x509_ncrls;
1601 gnutls_datum_t tmp;
1602 int ret;
1603
1604 tmp.data = (void*)input_crl;
1605 tmp.size = input_crl_size;
1606
1607 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
1608 GNUTLS_X509_FMT_PEM, 0);
1609 if (ret < 0)
1610 {
1611 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1611); } while(0);
;
1612 return ret;
1613 }
1614
1615 ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
1616 if (ret < 0)
1617 {
1618 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1618); } while(0);
;
1619 goto cleanup;
1620 }
1621
1622cleanup:
1623 gnutls_free(x509_crl_list);
1624 return ret;
1625}
1626
1627/* Reads a DER encoded certificate list from memory and stores it to a
1628 * gnutls_cert structure. Returns the number of certificates parsed.
1629 */
1630static int
1631parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
1632 const void *input_crl, int input_crl_size)
1633{
1634 gnutls_x509_crl_t crl;
1635 gnutls_datum_t tmp;
1636 int ret;
1637
1638 tmp.data = (void*)input_crl;
1639 tmp.size = input_crl_size;
1640
1641 ret = gnutls_x509_crl_init( &crl);
1642 if (ret < 0)
1643 {
1644 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1644); } while(0);
;
1645 return ret;
1646 }
1647
1648 ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
1649 if (ret < 0)
1650 {
1651 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1651); } while(0);
;
1652 goto cleanup;
1653 }
1654
1655 ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
1656 if (ret < 0)
1657 {
1658 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1658); } while(0);
;
1659 goto cleanup;
1660 }
1661
1662 return ret;
1663
1664cleanup:
1665 gnutls_x509_crl_deinit(crl);
1666 return ret;
1667
1668}
1669
1670
1671/* Reads a DER or PEM CRL from memory
1672 */
1673static int
1674read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1675 int crl_size, gnutls_x509_crt_fmt_t type)
1676{
1677 int ret;
1678
1679 if (type == GNUTLS_X509_FMT_DER)
1680 ret = parse_der_crl_mem (res->tlist, crl, crl_size);
1681 else
1682 ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
1683
1684 if (ret < 0)
1685 {
1686 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1686); } while(0);
;
1687 }
1688
1689 return ret;
1690}
1691
1692/**
1693 * gnutls_certificate_set_x509_crl_mem:
1694 * @res: is a #gnutls_certificate_credentials_t structure.
1695 * @CRL: is a list of trusted CRLs. They should have been verified before.
1696 * @type: is DER or PEM
1697 *
1698 * This function adds the trusted CRLs in order to verify client or
1699 * server certificates. In case of a client this is not required to
1700 * be called if the certificates are not verified using
1701 * gnutls_certificate_verify_peers2(). This function may be called
1702 * multiple times.
1703 *
1704 * Returns: number of CRLs processed, or a negative error code on error.
1705 **/
1706int
1707gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1708 const gnutls_datum_t * CRL,
1709 gnutls_x509_crt_fmt_t type)
1710{
1711 return read_crl_mem (res, CRL->data, CRL->size, type);
1712}
1713
1714/**
1715 * gnutls_certificate_set_x509_crl:
1716 * @res: is a #gnutls_certificate_credentials_t structure.
1717 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1718 * @crl_list_size: holds the size of the crl_list
1719 *
1720 * This function adds the trusted CRLs in order to verify client or
1721 * server certificates. In case of a client this is not required to
1722 * be called if the certificates are not verified using
1723 * gnutls_certificate_verify_peers2(). This function may be called
1724 * multiple times.
1725 *
1726 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1727 *
1728 * Since: 2.4.0
1729 **/
1730int
1731gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1732 gnutls_x509_crl_t * crl_list,
1733 int crl_list_size)
1734{
1735 int ret, i, j;
1736 gnutls_x509_crl_t new_crl[crl_list_size];
1737
1738 for (i = 0; i < crl_list_size; i++)
1739 {
1740 ret = gnutls_x509_crl_init (&new_crl[i]);
1741 if (ret < 0)
1742 {
1743 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1743); } while(0);
;
1744 goto cleanup;
1745 }
1746
1747 ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
1748 if (ret < 0)
1749 {
1750 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1750); } while(0);
;
1751 goto cleanup;
1752 }
1753 }
1754
1755 ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
1756 if (ret < 0)
1757 {
1758 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1758); } while(0);
;
1759 goto cleanup;
1760 }
1761
1762 return ret;
1763
1764cleanup:
1765 for (j=0;j<i;j++)
1766 gnutls_x509_crl_deinit(new_crl[j]);
1767
1768 return ret;
1769}
1770
1771/**
1772 * gnutls_certificate_set_x509_crl_file:
1773 * @res: is a #gnutls_certificate_credentials_t structure.
1774 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1775 * @type: is PEM or DER
1776 *
1777 * This function adds the trusted CRLs in order to verify client or server
1778 * certificates. In case of a client this is not required
1779 * to be called if the certificates are not verified using
1780 * gnutls_certificate_verify_peers2().
1781 * This function may be called multiple times.
1782 *
1783 * Returns: number of CRLs processed or a negative error code on error.
1784 **/
1785int
1786gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1787 const char *crlfile,
1788 gnutls_x509_crt_fmt_t type)
1789{
1790 int ret;
1791 size_t size;
1792 char *data = read_binary_file_gnutls_read_binary_file (crlfile, &size);
1793
1794 if (data == NULL((void*)0))
1795 {
1796 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1796); } while(0);
;
1797 return GNUTLS_E_FILE_ERROR-64;
1798 }
1799
1800 if (type == GNUTLS_X509_FMT_DER)
1801 ret = parse_der_crl_mem (res->tlist, data, size);
1802 else
1803 ret = parse_pem_crl_mem (res->tlist, data, size);
1804
1805 free (data);
1806
1807 if (ret < 0)
1808 {
1809 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1809); } while(0);
;
1810 return ret;
1811 }
1812
1813 return ret;
1814}
1815
1816#include <gnutls/pkcs12.h>
1817
1818static int
1819parse_pkcs12 (gnutls_certificate_credentials_t res,
1820 gnutls_pkcs12_t p12,
1821 const char *password,
1822 gnutls_x509_privkey_t * key,
1823 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1824{
1825 gnutls_pkcs12_bag_t bag = NULL((void*)0);
1826 int idx = 0;
1827 int ret;
1828 size_t cert_id_size = 0;
1829 size_t key_id_size = 0;
1830 opaque cert_id[20];
1831 opaque key_id[20];
1832 int privkey_ok = 0;
1833
1834 *cert = NULL((void*)0);
1835 *key = NULL((void*)0);
1836 *crl = NULL((void*)0);
1837
1838 /* find the first private key */
1839 for (;;)
1840 {
1841 int elements_in_bag;
1842 int i;
1843
1844 ret = gnutls_pkcs12_bag_init (&bag);
1845 if (ret < 0)
1846 {
1847 bag = NULL((void*)0);
1848 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1848); } while(0);
;
1849 goto done;
1850 }
1851
1852 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1853 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56)
1854 break;
1855 if (ret < 0)
1856 {
1857 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1857); } while(0);
;
1858 goto done;
1859 }
1860
1861 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1862 if (ret < 0)
1863 {
1864 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1864); } while(0);
;
1865 goto done;
1866 }
1867
1868 if (ret == GNUTLS_BAG_ENCRYPTED)
1869 {
1870 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1871 if (ret < 0)
1872 {
1873 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1873); } while(0);
;
1874 goto done;
1875 }
1876 }
1877
1878 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1879 if (elements_in_bag < 0)
1880 {
1881 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1881); } while(0);
;
1882 goto done;
1883 }
1884
1885 for (i = 0; i < elements_in_bag; i++)
1886 {
1887 int type;
1888 gnutls_datum_t data;
1889
1890 type = gnutls_pkcs12_bag_get_type (bag, i);
1891 if (type < 0)
1892 {
1893 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1893); } while(0);
;
1894 goto done;
1895 }
1896
1897 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1898 if (ret < 0)
1899 {
1900 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1900); } while(0);
;
1901 goto done;
1902 }
1903
1904 switch (type)
1905 {
1906 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1907 case GNUTLS_BAG_PKCS8_KEY:
1908 if (*key != NULL((void*)0)) /* too simple to continue */
1909 {
1910 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1910); } while(0);
;
1911 break;
1912 }
1913
1914 ret = gnutls_x509_privkey_init (key);
1915 if (ret < 0)
1916 {
1917 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1917); } while(0);
;
1918 goto done;
1919 }
1920
1921 ret = gnutls_x509_privkey_import_pkcs8
1922 (*key, &data, GNUTLS_X509_FMT_DER, password,
1923 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1924 if (ret < 0)
1925 {
1926 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1926); } while(0);
;
1927 gnutls_x509_privkey_deinit (*key);
1928 goto done;
1929 }
1930
1931 key_id_size = sizeof (key_id);
1932 ret =
1933 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
1934 &key_id_size);
1935 if (ret < 0)
1936 {
1937 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1937); } while(0);
;
1938 gnutls_x509_privkey_deinit (*key);
1939 goto done;
1940 }
1941
1942 privkey_ok = 1; /* break */
1943 break;
1944 default:
1945 break;
1946 }
1947 }
1948
1949 idx++;
1950 gnutls_pkcs12_bag_deinit (bag);
1951
1952 if (privkey_ok != 0) /* private key was found */
1953 break;
1954 }
1955
1956 if (privkey_ok == 0) /* no private key */
1957 {
1958 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1958); } while(0);
;
1959 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
1960 }
1961
1962 /* now find the corresponding certificate
1963 */
1964 idx = 0;
1965 bag = NULL((void*)0);
1966 for (;;)
1967 {
1968 int elements_in_bag;
1969 int i;
1970
1971 ret = gnutls_pkcs12_bag_init (&bag);
1972 if (ret < 0)
1973 {
1974 bag = NULL((void*)0);
1975 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1975); } while(0);
;
1976 goto done;
1977 }
1978
1979 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1980 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56)
1981 break;
1982 if (ret < 0)
1983 {
1984 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1984); } while(0);
;
1985 goto done;
1986 }
1987
1988 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1989 if (ret < 0)
1990 {
1991 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",1991); } while(0);
;
1992 goto done;
1993 }
1994
1995 if (ret == GNUTLS_BAG_ENCRYPTED)
1996 {
1997 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1998 if (ret < 0)
1999 {
2000 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2000); } while(0);
;
2001 goto done;
2002 }
2003 }
2004
2005 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
2006 if (elements_in_bag < 0)
2007 {
2008 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2008); } while(0);
;
2009 goto done;
2010 }
2011
2012 for (i = 0; i < elements_in_bag; i++)
2013 {
2014 int type;
2015 gnutls_datum_t data;
2016
2017 type = gnutls_pkcs12_bag_get_type (bag, i);
2018 if (type < 0)
2019 {
2020 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2020); } while(0);
;
2021 goto done;
2022 }
2023
2024 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
2025 if (ret < 0)
2026 {
2027 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2027); } while(0);
;
2028 goto done;
2029 }
2030
2031 switch (type)
2032 {
2033 case GNUTLS_BAG_CERTIFICATE:
2034 if (*cert != NULL((void*)0)) /* no need to set it again */
2035 {
2036 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2036); } while(0);
;
2037 break;
2038 }
2039
2040 ret = gnutls_x509_crt_init (cert);
2041 if (ret < 0)
2042 {
2043 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2043); } while(0);
;
2044 goto done;
2045 }
2046
2047 ret =
2048 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
2049 if (ret < 0)
2050 {
2051 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2051); } while(0);
;
2052 gnutls_x509_crt_deinit (*cert);
2053 goto done;
2054 }
2055
2056 /* check if the key id match */
2057 cert_id_size = sizeof (cert_id);
2058 ret =
2059 gnutls_x509_crt_get_key_id (*cert, 0, cert_id, &cert_id_size);
2060 if (ret < 0)
2061 {
2062 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2062); } while(0);
;
2063 gnutls_x509_crt_deinit (*cert);
2064 goto done;
2065 }
2066
2067 if (memcmp (cert_id, key_id, cert_id_size) != 0)
2068 { /* they don't match - skip the certificate */
2069 gnutls_x509_crt_deinit (*cert);
2070 *cert = NULL((void*)0);
2071 }
2072 break;
2073
2074 case GNUTLS_BAG_CRL:
2075 if (*crl != NULL((void*)0))
2076 {
2077 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2077); } while(0);
;
2078 break;
2079 }
2080
2081 ret = gnutls_x509_crl_init (crl);
2082 if (ret < 0)
2083 {
2084 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2084); } while(0);
;
2085 goto done;
2086 }
2087
2088 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
2089 if (ret < 0)
2090 {
2091 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2091); } while(0);
;
2092 gnutls_x509_crl_deinit (*crl);
2093 goto done;
2094 }
2095 break;
2096
2097 case GNUTLS_BAG_ENCRYPTED:
2098 /* XXX Bother to recurse one level down? Unlikely to
2099 use the same password anyway. */
2100 case GNUTLS_BAG_EMPTY:
2101 default:
2102 break;
2103 }
2104 }
2105
2106 idx++;
2107 gnutls_pkcs12_bag_deinit (bag);
2108 }
2109
2110 ret = 0;
2111
2112done:
2113 if (bag)
2114 gnutls_pkcs12_bag_deinit (bag);
2115
2116 return ret;
2117}
2118
2119/**
2120 * gnutls_certificate_set_x509_simple_pkcs12_file:
2121 * @res: is a #gnutls_certificate_credentials_t structure.
2122 * @pkcs12file: filename of file containing PKCS#12 blob.
2123 * @type: is PEM or DER of the @pkcs12file.
2124 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2125 *
2126 * This function sets a certificate/private key pair and/or a CRL in
2127 * the gnutls_certificate_credentials_t structure. This function may
2128 * be called more than once (in case multiple keys/certificates exist
2129 * for the server).
2130 *
2131 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
2132 * private keys are supported. However,
2133 * only password based security, and the same password for all
2134 * operations, are supported.
2135 *
2136 * PKCS#12 file may contain many keys and/or certificates, and there
2137 * is no way to identify which key/certificate pair you want. You
2138 * should make sure the PKCS#12 file only contain one key/certificate
2139 * pair and/or one CRL.
2140 *
2141 * It is believed that the limitations of this function is acceptable
2142 * for most usage, and that any more flexibility would introduce
2143 * complexity that would make it harder to use this functionality at
2144 * all.
2145 *
2146 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2147 **/
2148int
2149 gnutls_certificate_set_x509_simple_pkcs12_file
2150 (gnutls_certificate_credentials_t res, const char *pkcs12file,
2151 gnutls_x509_crt_fmt_t type, const char *password)
2152{
2153 gnutls_datum_t p12blob;
2154 size_t size;
2155 int ret;
2156
2157 p12blob.data = read_binary_file_gnutls_read_binary_file (pkcs12file, &size);
2158 p12blob.size = (unsigned int) size;
2159 if (p12blob.data == NULL((void*)0))
2160 {
2161 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2161); } while(0);
;
2162 return GNUTLS_E_FILE_ERROR-64;
2163 }
2164
2165 ret =
2166 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
2167 password);
2168 free (p12blob.data);
2169
2170 return ret;
2171}
2172
2173/**
2174 * gnutls_certificate_set_x509_simple_pkcs12_mem:
2175 * @res: is a #gnutls_certificate_credentials_t structure.
2176 * @p12blob: the PKCS#12 blob.
2177 * @type: is PEM or DER of the @pkcs12file.
2178 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2179 *
2180 * This function sets a certificate/private key pair and/or a CRL in
2181 * the gnutls_certificate_credentials_t structure. This function may
2182 * be called more than once (in case multiple keys/certificates exist
2183 * for the server).
2184 *
2185 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2186 * supported. Encrypted PKCS#8 private keys are supported. However,
2187 * only password based security, and the same password for all
2188 * operations, are supported.
2189 *
2190 * PKCS#12 file may contain many keys and/or certificates, and there
2191 * is no way to identify which key/certificate pair you want. You
2192 * should make sure the PKCS#12 file only contain one key/certificate
2193 * pair and/or one CRL.
2194 *
2195 * It is believed that the limitations of this function is acceptable
2196 * for most usage, and that any more flexibility would introduce
2197 * complexity that would make it harder to use this functionality at
2198 * all.
2199 *
2200 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2201 *
2202 * Since: 2.8.0
2203 **/
2204int
2205 gnutls_certificate_set_x509_simple_pkcs12_mem
2206 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
2207 gnutls_x509_crt_fmt_t type, const char *password)
2208{
2209 gnutls_pkcs12_t p12;
2210 gnutls_x509_privkey_t key = NULL((void*)0);
2211 gnutls_x509_crt_t cert = NULL((void*)0);
2212 gnutls_x509_crl_t crl = NULL((void*)0);
2213 int ret;
2214
2215 ret = gnutls_pkcs12_init (&p12);
2216 if (ret < 0)
2217 {
2218 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2218); } while(0);
;
2219 return ret;
2220 }
2221
2222 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
2223 if (ret < 0)
2224 {
2225 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2225); } while(0);
;
2226 gnutls_pkcs12_deinit (p12);
2227 return ret;
2228 }
2229
2230 if (password)
2231 {
2232 ret = gnutls_pkcs12_verify_mac (p12, password);
2233 if (ret < 0)
2234 {
2235 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2235); } while(0);
;
2236 gnutls_pkcs12_deinit (p12);
2237 return ret;
2238 }
2239 }
2240
2241 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
2242 gnutls_pkcs12_deinit (p12);
2243 if (ret < 0)
2244 {
2245 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2245); } while(0);
;
2246 return ret;
2247 }
2248
2249 if (key && cert)
2250 {
2251 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
2252 if (ret < 0)
2253 {
2254 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2254); } while(0);
;
2255 goto done;
2256 }
2257 }
2258
2259 if (crl)
2260 {
2261 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
2262 if (ret < 0)
2263 {
2264 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_x509.c",2264); } while(0);
;
2265 goto done;
2266 }
2267 }
2268
2269 ret = 0;
2270
2271done:
2272 if (cert)
2273 gnutls_x509_crt_deinit (cert);
2274 if (key)
2275 gnutls_x509_privkey_deinit (key);
2276 if (crl)
2277 gnutls_x509_crl_deinit (crl);
2278
2279 return ret;
2280}
2281
2282
2283
2284/**
2285 * gnutls_certificate_free_crls:
2286 * @sc: is a #gnutls_certificate_credentials_t structure.
2287 *
2288 * This function will delete all the CRLs associated
2289 * with the given credentials.
2290 **/
2291void
2292gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
2293{
2294 /* do nothing for now */
2295 return;
2296}
2297
2298#endif