File: | lib/gnutls_x509.c |
Location: | line 679, column 3 |
Description: | Value stored to 'ret' is never read |
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 | */ |
53 | inline static int |
54 | check_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 | -*/ |
91 | int |
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 | */ |
196 | static 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 | */ |
213 | static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names) |
214 | { |
215 | size_t max_size; |
216 | int i, ret = 0, ret2; |
217 | char 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 | |
250 | static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names) |
251 | { |
252 | int ret; |
253 | gnutls_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 | */ |
278 | static int |
279 | parse_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 | |
341 | cleanup: |
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 | */ |
350 | static int |
351 | parse_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 | |
446 | cleanup: |
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 | */ |
458 | static int |
459 | read_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 | |
478 | static 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 | */ |
527 | static int |
528 | read_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 | */ |
570 | static int |
571 | read_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 | |
619 | cleanup: |
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 | */ |
631 | static int |
632 | read_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 | |
696 | cleanup: |
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 | */ |
707 | static int |
708 | read_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 | |
770 | cleanup: |
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 | */ |
780 | static int |
781 | read_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 | */ |
815 | static int |
816 | read_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 | **/ |
868 | int |
869 | gnutls_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 | |
896 | static int check_if_sorted(gnutls_pcert_st * crt, int nr) |
897 | { |
898 | gnutls_x509_crt_t x509; |
899 | char prev_dn[MAX_DN1024]; |
900 | char dn[MAX_DN1024]; |
901 | size_t prev_dn_size, dn_size; |
902 | int 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 | |
952 | cleanup: |
953 | gnutls_x509_crt_deinit(x509); |
954 | return ret; |
955 | } |
956 | |
957 | int |
958 | certificate_credential_append_crt_list (gnutls_certificate_credentials_t res, |
959 | gnutls_str_array_t names, gnutls_pcert_st * crt, int nr) |
960 | { |
961 | int 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 | |
984 | int |
985 | certificate_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 | **/ |
1021 | int |
1022 | gnutls_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 | |
1096 | cleanup: |
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 | **/ |
1124 | int |
1125 | gnutls_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 | |
1174 | cleanup: |
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 | **/ |
1199 | int |
1200 | gnutls_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 | |
1226 | static int |
1227 | add_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 | */ |
1286 | int |
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 | |
1339 | static int |
1340 | parse_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 | |
1372 | cleanup: |
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 | */ |
1380 | static int |
1381 | parse_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 | |
1420 | cleanup: |
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 | **/ |
1444 | int |
1445 | gnutls_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 | **/ |
1485 | int |
1486 | gnutls_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 | |
1525 | cleanup: |
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 | **/ |
1555 | int |
1556 | gnutls_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 | |
1595 | static int |
1596 | parse_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 | |
1622 | cleanup: |
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 | */ |
1630 | static int |
1631 | parse_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 | |
1664 | cleanup: |
1665 | gnutls_x509_crl_deinit(crl); |
1666 | return ret; |
1667 | |
1668 | } |
1669 | |
1670 | |
1671 | /* Reads a DER or PEM CRL from memory |
1672 | */ |
1673 | static int |
1674 | read_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 | **/ |
1706 | int |
1707 | gnutls_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 | **/ |
1730 | int |
1731 | gnutls_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 | |
1764 | cleanup: |
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 | **/ |
1785 | int |
1786 | gnutls_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 | |
1818 | static int |
1819 | parse_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 | |
2112 | done: |
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 | **/ |
2148 | int |
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 | **/ |
2204 | int |
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 | |
2271 | done: |
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 | **/ |
2291 | void |
2292 | gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc) |
2293 | { |
2294 | /* do nothing for now */ |
2295 | return; |
2296 | } |
2297 | |
2298 | #endif |