Bug Summary

File:lib/auth/cert.c
Location:line 1788, column 7
Description:Value stored to 'size' is never read

Annotated Source Code

1/*
2 * Copyright (C) 2001-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/* The certificate authentication functions which are needed in the handshake,
24 * and are common to RSA and DHE key exchange, are in this file.
25 */
26
27#include <gnutls_int.h>
28#include "gnutls_auth.h"
29#include "gnutls_errors.h"
30#include <auth/cert.h>
31#include "gnutls_dh.h"
32#include "gnutls_num.h"
33#include "libtasn1.h"
34#include "gnutls_datum.h"
35#include "ext/signature.h"
36#include <gnutls_pk.h>
37#include <algorithms.h>
38#include <gnutls_global.h>
39#include <gnutls_record.h>
40#include <gnutls_sig.h>
41#include <gnutls_state.h>
42#include <gnutls_pk.h>
43#include <gnutls_x509.h>
44#include <gnutls/abstract.h>
45#include "debug.h"
46
47#ifdef ENABLE_OPENPGP1
48#include "openpgp/gnutls_openpgp.h"
49
50static gnutls_privkey_t alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
51 key, int deinit);
52static gnutls_pcert_st *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert);
53
54#endif
55
56static gnutls_pcert_st *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
57 unsigned);
58static gnutls_privkey_t alloc_and_load_x509_key (gnutls_x509_privkey_t key,
59 int deinit);
60
61#ifdef ENABLE_PKCS111
62static gnutls_privkey_t alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t
63 key, int deinit);
64#endif
65
66#define MAX_CLIENT_SIGN_ALGOS3 3
67#define CERTTYPE_SIZE(3 +1) (MAX_CLIENT_SIGN_ALGOS3+1)
68typedef enum CertificateSigType
69{ RSA_SIGN = 1, DSA_SIGN = 2, ECDSA_SIGN = 64
70} CertificateSigType;
71
72/* Copies data from a internal certificate struct (gnutls_pcert_st) to
73 * exported certificate struct (cert_auth_info_t)
74 */
75static int
76_gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts, int subkey_used, /* openpgp only */
77 void *keyid)
78{
79 /* Copy peer's information to auth_info_t
80 */
81 int ret;
82 size_t i, j;
83
84 if (info->raw_certificate_list != NULL((void*)0))
85 {
86 for (j = 0; j < info->ncerts; j++)
87 _gnutls_free_datum (&info->raw_certificate_list[j])_gnutls_free_datum_m(&info->raw_certificate_list[j], gnutls_free
)
;
88 gnutls_free (info->raw_certificate_list);
89 }
90
91 if (ncerts == 0)
92 {
93 info->raw_certificate_list = NULL((void*)0);
94 info->ncerts = 0;
95 return 0;
96 }
97
98 info->raw_certificate_list =
99 gnutls_calloc (ncerts, sizeof (gnutls_datum_t));
100 if (info->raw_certificate_list == NULL((void*)0))
101 {
102 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",102); } while(0);
;
103 return GNUTLS_E_MEMORY_ERROR-25;
104 }
105
106 for (i = 0; i < ncerts; i++)
107 {
108 if (certs[i].cert.size > 0)
109 {
110 ret =
111 _gnutls_set_datum (&info->raw_certificate_list[i],_gnutls_set_datum_m(&info->raw_certificate_list[i],certs
[i].cert.data,certs[i].cert.size, gnutls_malloc)
112 certs[i].cert.data, certs[i].cert.size)_gnutls_set_datum_m(&info->raw_certificate_list[i],certs
[i].cert.data,certs[i].cert.size, gnutls_malloc)
;
113 if (ret < 0)
114 {
115 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",115); } while(0);
;
116 goto clear;
117 }
118 }
119 }
120 info->ncerts = ncerts;
121 info->cert_type = certs[0].type;
122
123#ifdef ENABLE_OPENPGP1
124 if (certs[0].type == GNUTLS_CRT_OPENPGP)
125 {
126 info->use_subkey = subkey_used;
127 if (keyid)
128 memcpy (info->subkey_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE8);
129 }
130#endif
131
132 return 0;
133
134clear:
135
136 for (j = 0; j < i; j++)
137 _gnutls_free_datum (&info->raw_certificate_list[j])_gnutls_free_datum_m(&info->raw_certificate_list[j], gnutls_free
)
;
138
139 gnutls_free (info->raw_certificate_list);
140 info->raw_certificate_list = NULL((void*)0);
141
142 return ret;
143}
144
145
146
147
148/* returns 0 if the algo_to-check exists in the pk_algos list,
149 * -1 otherwise.
150 */
151inline static int
152_gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
153 pk_algos, int pk_algos_length,
154 gnutls_pk_algorithm_t algo_to_check)
155{
156 int i;
157 for (i = 0; i < pk_algos_length; i++)
158 {
159 if (algo_to_check == pk_algos[i])
160 {
161 return 0;
162 }
163 }
164 return -1;
165}
166
167
168/* Returns the issuer's Distinguished name in odn, of the certificate
169 * specified in cert.
170 */
171static int
172_gnutls_cert_get_issuer_dn (gnutls_pcert_st * cert, gnutls_datum_t * odn)
173{
174 ASN1_TYPE dn;
175 int len, result;
176 int start, end;
177
178 if ((result = asn1_create_element
179 (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS0)
180 {
181 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",181); } while(0);
;
182 return _gnutls_asn2err (result);
183 }
184
185 result = asn1_der_decoding (&dn, cert->cert.data, cert->cert.size, NULL((void*)0));
186 if (result != ASN1_SUCCESS0)
187 {
188 /* couldn't decode DER */
189 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",189); } while(0);
;
190 asn1_delete_structure (&dn);
191 return _gnutls_asn2err (result);
192 }
193
194 result = asn1_der_decoding_startEnd (dn, cert->cert.data, cert->cert.size,
195 "tbsCertificate.issuer", &start, &end);
196
197 if (result != ASN1_SUCCESS0)
198 {
199 /* couldn't decode DER */
200 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",200); } while(0);
;
201 asn1_delete_structure (&dn);
202 return _gnutls_asn2err (result);
203 }
204 asn1_delete_structure (&dn);
205
206 len = end - start + 1;
207
208 odn->size = len;
209 odn->data = &cert->cert.data[start];
210
211 return 0;
212}
213
214
215/* Locates the most appropriate x509 certificate using the
216 * given DN. If indx == -1 then no certificate was found.
217 *
218 * That is to guess which certificate to use, based on the
219 * CAs and sign algorithms supported by the peer server.
220 */
221static int
222_find_x509_cert (const gnutls_certificate_credentials_t cred,
223 opaque * _data, size_t _data_size,
224 const gnutls_pk_algorithm_t * pk_algos,
225 int pk_algos_length, int *indx)
226{
227 unsigned size;
228 gnutls_datum_t odn = { NULL((void*)0), 0 };
229 opaque *data = _data;
230 ssize_t data_size = _data_size;
231 unsigned i, j;
232 int result, cert_pk;
233
234 *indx = -1;
235
236 do
237 {
238
239 DECR_LENGTH_RET (data_size, 2, 0)do { data_size-=2; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",239); } while(0);; return 0;} } while (0)
;
240 size = _gnutls_read_uint16 (data);
241 DECR_LENGTH_RET (data_size, size, 0)do { data_size-=size; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",241); } while(0);; return 0;} } while (0)
;
242 data += 2;
243
244 for (i = 0; i < cred->ncerts; i++)
245 {
246 for (j = 0; j < cred->certs[i].cert_list_length; j++)
247 {
248 if ((result =
249 _gnutls_cert_get_issuer_dn (&cred->certs[i].cert_list[j],
250 &odn)) < 0)
251 {
252 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",252); } while(0);
;
253 return result;
254 }
255
256 if (odn.size != size)
257 continue;
258
259 /* If the DN matches and
260 * the *_SIGN algorithm matches
261 * the cert is our cert!
262 */
263 cert_pk =
264 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
265 NULL((void*)0));
266
267 if ((memcmp (odn.data, data, size) == 0) &&
268 (_gnutls_check_pk_algo_in_list
269 (pk_algos, pk_algos_length, cert_pk) == 0))
270 {
271 *indx = i;
272 break;
273 }
274 }
275 if (*indx != -1)
276 break;
277 }
278
279 if (*indx != -1)
280 break;
281
282 /* move to next record */
283 data += size;
284
285 }
286 while (1);
287
288 return 0;
289
290}
291
292#ifdef ENABLE_OPENPGP1
293/* Locates the most appropriate openpgp cert
294 */
295static int
296_find_openpgp_cert (const gnutls_certificate_credentials_t cred,
297 gnutls_pk_algorithm_t * pk_algos,
298 int pk_algos_length, int *indx)
299{
300 unsigned i, j;
301
302 *indx = -1;
303
304 for (i = 0; i < cred->ncerts; i++)
305 {
306 for (j = 0; j < cred->certs[i].cert_list_length; j++)
307 {
308
309 /* If the *_SIGN algorithm matches
310 * the cert is our cert!
311 */
312 if ((_gnutls_check_pk_algo_in_list
313 (pk_algos, pk_algos_length,
314 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
315 NULL((void*)0))) == 0)
316 && (cred->certs[i].cert_list[0].type == GNUTLS_CRT_OPENPGP))
317 {
318 *indx = i;
319 break;
320 }
321 }
322 if (*indx != -1)
323 break;
324 }
325
326 return 0;
327}
328#endif
329
330/* Returns the number of issuers in the server's
331 * certificate request packet.
332 */
333static int
334get_issuers_num (gnutls_session_t session, opaque * data, ssize_t data_size)
335{
336 int issuers_dn_len = 0, result;
337 unsigned size;
338
339 /* Count the number of the given issuers;
340 * This is used to allocate the issuers_dn without
341 * using realloc().
342 */
343
344 if (data_size == 0 || data == NULL((void*)0))
345 return 0;
346
347 if (data_size > 0)
348 do
349 {
350 /* This works like DECR_LEN()
351 */
352 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
353 DECR_LENGTH_COM (data_size, 2, goto error)do { data_size-=2; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",353); } while(0);; goto error;} } while (0)
;
354 size = _gnutls_read_uint16 (data);
355
356 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
357 DECR_LENGTH_COM (data_size, size, goto error)do { data_size-=size; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",357); } while(0);; goto error;} } while (0)
;
358
359 data += 2;
360
361 if (size > 0)
362 {
363 issuers_dn_len++;
364 data += size;
365 }
366
367 if (data_size == 0)
368 break;
369
370 }
371 while (1);
372
373 return issuers_dn_len;
374
375error:
376 return result;
377}
378
379/* Returns the issuers in the server's certificate request
380 * packet.
381 */
382static int
383get_issuers (gnutls_session_t session,
384 gnutls_datum_t * issuers_dn, int issuers_len,
385 opaque * data, size_t data_size)
386{
387 int i;
388 unsigned size;
389
390 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
391 return 0;
392
393 /* put the requested DNs to req_dn, only in case
394 * of X509 certificates.
395 */
396 if (issuers_len > 0)
397 {
398
399 for (i = 0; i < issuers_len; i++)
400 {
401 /* The checks here for the buffer boundaries
402 * are not needed since the buffer has been
403 * parsed above.
404 */
405 data_size -= 2;
406
407 size = _gnutls_read_uint16 (data);
408
409 data += 2;
410
411 issuers_dn[i].data = data;
412 issuers_dn[i].size = size;
413
414 data += size;
415 }
416 }
417
418 return 0;
419}
420
421static void
422st_to_st2 (gnutls_retr2_st * st2, gnutls_retr_st * st)
423{
424 st2->cert_type = st->type;
425 if (st->type == GNUTLS_CRT_OPENPGP)
426 {
427 st2->key_type = GNUTLS_PRIVKEY_OPENPGP;
428 }
429 else
430 {
431 st2->key_type = GNUTLS_PRIVKEY_X509;
432 }
433 st2->ncerts = st->ncerts;
434 st2->deinit_all = st->deinit_all;
435
436 switch (st2->cert_type)
437 {
438 case GNUTLS_CRT_OPENPGP:
439 st2->cert.pgp = st->cert.pgp;
440 st2->key.pgp = st->key.pgp;
441 break;
442 case GNUTLS_CRT_X509:
443 st2->cert.x509 = st->cert.x509;
444 st2->key.x509 = st->key.x509;
445 break;
446 default:
447 return;
448 }
449
450}
451
452/* Calls the client get callback.
453 */
454static int
455call_get_cert_callback (gnutls_session_t session,
456 const gnutls_datum_t * issuers_dn,
457 int issuers_dn_length,
458 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
459{
460 unsigned i;
461 gnutls_pcert_st *local_certs = NULL((void*)0);
462 gnutls_privkey_t local_key = NULL((void*)0);
463 int ret = GNUTLS_E_INTERNAL_ERROR-59;
464 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
465 gnutls_certificate_credentials_t cred;
466 gnutls_retr2_st st2;
467 gnutls_pcert_st *pcert = NULL((void*)0);
468 unsigned int pcert_length = 0;
469
470 cred = (gnutls_certificate_credentials_t)
471 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
472 if (cred == NULL((void*)0))
473 {
474 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",474); } while(0);
;
475 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
476 }
477
478 memset (&st2, 0, sizeof (st2));
479
480 if (cred->get_cert_callback2)
481 {
482 /* we avoid all allocations and transformations */
483 ret = cred->get_cert_callback2 (session, issuers_dn, issuers_dn_length,
484 pk_algos, pk_algos_length,
485 &pcert, &pcert_length, &local_key);
486 if (ret < 0)
487 return gnutls_assert_val (GNUTLS_E_USER_ERROR)gnutls_assert_val_int(-320, "cert.c", 487);
488
489 if (pcert_length > 0 && type != pcert[0].type)
490 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "cert.c", 490);
491
492 if (pcert_length == 0)
493 {
494 pcert = NULL((void*)0);
495 local_key = NULL((void*)0);
496 }
497 _gnutls_selected_certs_set (session, pcert, pcert_length, local_key, 0);
498
499 return 0;
500
501 }
502 else if (cred->get_cert_callback)
503 {
504 ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
505 pk_algos, pk_algos_length, &st2);
506
507 }
508 else
509 { /* compatibility mode */
510 gnutls_retr_st st;
511 memset (&st, 0, sizeof (st));
512 if (session->security_parameters.entity == GNUTLS_SERVER1)
513 {
514 if (cred->server_get_cert_callback == NULL((void*)0))
515 {
516 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",516); } while(0);
;
517 return GNUTLS_E_INTERNAL_ERROR-59;
518 }
519 ret = cred->server_get_cert_callback (session, &st);
520 if (ret >= 0)
521 st_to_st2 (&st2, &st);
522 }
523 else
524 { /* CLIENT */
525
526 if (cred->client_get_cert_callback == NULL((void*)0))
527 {
528 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",528); } while(0);
;
529 return GNUTLS_E_INTERNAL_ERROR-59;
530 }
531 ret = cred->client_get_cert_callback (session,
532 issuers_dn, issuers_dn_length,
533 pk_algos, pk_algos_length,
534 &st);
535 if (ret >= 0)
536 st_to_st2 (&st2, &st);
537 }
538 }
539
540 if (ret < 0)
541 {
542 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",542); } while(0);
;
543 return GNUTLS_E_USER_ERROR-320;
544 }
545
546 if (st2.ncerts == 0)
547 return 0; /* no certificate was selected */
548
549 if (type != st2.cert_type)
550 {
551 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",551); } while(0);
;
552 ret = GNUTLS_E_INVALID_REQUEST-50;
553 goto cleanup;
554 }
555
556
557 if (type == GNUTLS_CRT_X509)
558 {
559 local_certs = alloc_and_load_x509_certs (st2.cert.x509, st2.ncerts);
560 }
561 else
562 { /* PGP */
563 if (st2.ncerts > 1)
564 {
565 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",565); } while(0);
;
566 ret = GNUTLS_E_INVALID_REQUEST-50;
567 goto cleanup;
568 }
569#ifdef ENABLE_OPENPGP1
570 {
571 local_certs = alloc_and_load_pgp_certs (st2.cert.pgp);
572 }
573#else
574 ret = GNUTLS_E_UNIMPLEMENTED_FEATURE-1250;
575 goto cleanup;
576#endif
577 }
578
579 if (local_certs == NULL((void*)0))
580 {
581 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",581); } while(0);
;
582 ret = GNUTLS_E_MEMORY_ERROR-25;
583 goto cleanup;
584 }
585
586 switch (st2.key_type)
587 {
588 case GNUTLS_PRIVKEY_OPENPGP:
589#ifdef ENABLE_OPENPGP1
590 if (st2.key.pgp != NULL((void*)0))
591 {
592 local_key = alloc_and_load_pgp_key (st2.key.pgp, st2.deinit_all);
593 if (local_key == NULL((void*)0))
594 {
595 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",595); } while(0);
;
596 ret = GNUTLS_E_INTERNAL_ERROR-59;
597 goto cleanup;
598 }
599 }
600#endif
601 break;
602 case GNUTLS_PRIVKEY_PKCS11:
603#ifdef ENABLE_PKCS111
604 if (st2.key.pkcs11 != NULL((void*)0))
605 {
606 local_key =
607 alloc_and_load_pkcs11_key (st2.key.pkcs11, st2.deinit_all);
608 if (local_key == NULL((void*)0))
609 {
610 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",610); } while(0);
;
611 ret = GNUTLS_E_INTERNAL_ERROR-59;
612 goto cleanup;
613 }
614 }
615#endif
616 break;
617 case GNUTLS_PRIVKEY_X509:
618 if (st2.key.x509 != NULL((void*)0))
619 {
620 local_key = alloc_and_load_x509_key (st2.key.x509, st2.deinit_all);
621 if (local_key == NULL((void*)0))
622 {
623 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",623); } while(0);
;
624 ret = GNUTLS_E_INTERNAL_ERROR-59;
625 goto cleanup;
626 }
627 }
628 break;
629 default:
630 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",630); } while(0);
;
631 ret = GNUTLS_E_INVALID_REQUEST-50;
632 goto cleanup;
633 }
634
635 _gnutls_selected_certs_set (session, local_certs,
636 (local_certs != NULL((void*)0)) ? st2.ncerts : 0,
637 local_key, 1);
638
639 ret = 0;
640
641cleanup:
642
643 if (st2.cert_type == GNUTLS_CRT_X509)
644 {
645 if (st2.deinit_all)
646 {
647 for (i = 0; i < st2.ncerts; i++)
648 {
649 gnutls_x509_crt_deinit (st2.cert.x509[i]);
650 }
651 gnutls_free(st2.cert.x509);
652 }
653 }
654 else
655 {
656#ifdef ENABLE_OPENPGP1
657 if (st2.deinit_all)
658 {
659 gnutls_openpgp_crt_deinit (st2.cert.pgp);
660 }
661#endif
662 }
663
664 if (ret < 0)
665 {
666 if (local_key != NULL((void*)0))
667 gnutls_privkey_deinit (local_key);
668 }
669
670 return ret;
671}
672
673/* Finds the appropriate certificate depending on the cA Distinguished name
674 * advertized by the server. If none matches then returns 0 and -1 as index.
675 * In case of an error a negative error code, is returned.
676 *
677 * 20020128: added ability to select a certificate depending on the SIGN
678 * algorithm (only in automatic mode).
679 */
680static int
681_select_client_cert (gnutls_session_t session,
682 opaque * _data, size_t _data_size,
683 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
684{
685 int result;
686 int indx = -1;
687 gnutls_certificate_credentials_t cred;
688 opaque *data = _data;
689 ssize_t data_size = _data_size;
690 int issuers_dn_length;
691 gnutls_datum_t *issuers_dn = NULL((void*)0);
692
693 cred = (gnutls_certificate_credentials_t)
694 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
695 if (cred == NULL((void*)0))
696 {
697 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",697); } while(0);
;
698 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
699 }
700
701 if (cred->client_get_cert_callback != NULL((void*)0)
702 || cred->get_cert_callback != NULL((void*)0) || cred->get_cert_callback2 != NULL((void*)0))
703 {
704
705 /* use a callback to get certificate
706 */
707 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
708 issuers_dn_length = 0;
709 else
710 {
711 issuers_dn_length = get_issuers_num (session, data, data_size);
712 if (issuers_dn_length < 0)
713 {
714 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",714); } while(0);
;
715 return issuers_dn_length;
716 }
717
718 if (issuers_dn_length > 0)
719 {
720 issuers_dn =
721 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
722 if (issuers_dn == NULL((void*)0))
723 {
724 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",724); } while(0);
;
725 return GNUTLS_E_MEMORY_ERROR-25;
726 }
727
728 result =
729 get_issuers (session, issuers_dn, issuers_dn_length,
730 data, data_size);
731 if (result < 0)
732 {
733 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",733); } while(0);
;
734 goto cleanup;
735 }
736 }
737 }
738
739 result =
740 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
741 pk_algos, pk_algos_length);
742 goto cleanup;
743
744 }
745 else
746 {
747 /* If we have no callbacks, try to guess.
748 */
749 result = 0;
750
751 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
752 result =
753 _find_x509_cert (cred, _data, _data_size,
754 pk_algos, pk_algos_length, &indx);
755
756#ifdef ENABLE_OPENPGP1
757 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
758 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
759#endif
760
761 if (result < 0)
762 {
763 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",763); } while(0);
;
764 return result;
765 }
766
767 if (indx >= 0)
768 {
769 _gnutls_selected_certs_set (session,
770 &cred->certs[indx].cert_list[0],
771 cred->certs[indx].cert_list_length,
772 cred->pkey[indx], 0);
773 }
774 else
775 {
776 _gnutls_selected_certs_set (session, NULL((void*)0), 0, NULL((void*)0), 0);
777 }
778
779 result = 0;
780 }
781
782cleanup:
783 gnutls_free (issuers_dn);
784 return result;
785
786}
787
788/* Generate client certificate
789 */
790
791static int
792_gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
793{
794 int ret, i;
795 gnutls_pcert_st *apr_cert_list;
796 gnutls_privkey_t apr_pkey;
797 int apr_cert_list_length;
798
799 /* find the appropriate certificate
800 */
801 if ((ret =
802 _gnutls_get_selected_cert (session, &apr_cert_list,
803 &apr_cert_list_length, &apr_pkey)) < 0)
804 {
805 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",805); } while(0);
;
806 return ret;
807 }
808
809 ret = 3;
810 for (i = 0; i < apr_cert_list_length; i++)
811 {
812 ret += apr_cert_list[i].cert.size + 3;
813 /* hold size
814 * for uint24 */
815 }
816
817 /* if no certificates were found then send:
818 * 0B 00 00 03 00 00 00 // Certificate with no certs
819 * instead of:
820 * 0B 00 00 00 // empty certificate handshake
821 *
822 * ( the above is the whole handshake message, not
823 * the one produced here )
824 */
825
826 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
827 if (ret < 0)
828 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 828);
829
830 for (i = 0; i < apr_cert_list_length; i++)
831 {
832 ret =
833 _gnutls_buffer_append_data_prefix (data, 24,
834 apr_cert_list[i].cert.data,
835 apr_cert_list[i].cert.size);
836 if (ret < 0)
837 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 837);
838 }
839
840 return data->length;
841}
842
843enum PGPKeyDescriptorType
844{ PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
845
846#ifdef ENABLE_OPENPGP1
847static int
848_gnutls_gen_openpgp_certificate (gnutls_session_t session,
849 gnutls_buffer_st * data)
850{
851 int ret;
852 gnutls_pcert_st *apr_cert_list;
853 gnutls_privkey_t apr_pkey;
854 int apr_cert_list_length;
855 uint8_t type;
856 uint8_t fpr[20];
857 size_t fpr_size;
858 unsigned int use_subkey = 0;
859
860 /* find the appropriate certificate */
861 if ((ret =
862 _gnutls_get_selected_cert (session, &apr_cert_list,
863 &apr_cert_list_length, &apr_pkey)) < 0)
864 {
865 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",865); } while(0);
;
866 return ret;
867 }
868
869 ret = 3 + 1 + 3;
870
871
872
873 if (apr_cert_list_length > 0)
874 {
875 fpr_size = sizeof (fpr);
876 ret =
877 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
878 &fpr_size, &use_subkey);
879 if (ret < 0)
880 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 880);
881
882 if (use_subkey != 0)
883 ret += 1 + fpr_size; /* for the keyid */
884
885 ret += apr_cert_list[0].cert.size;
886 }
887
888 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
889 if (ret < 0)
890 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 890);
891
892
893 if (apr_cert_list_length > 0)
894 {
895 if (use_subkey != 0)
896 {
897 type = PGP_KEY_SUBKEY;
898
899 ret = _gnutls_buffer_append_data (data, &type, 1);
900 if (ret < 0)
901 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 901);
902
903 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
904 if (ret < 0)
905 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 905);
906 }
907 else
908 {
909 type = PGP_KEY;
910 ret = _gnutls_buffer_append_data (data, &type, 1);
911 if (ret < 0)
912 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 912);
913 }
914
915 ret =
916 _gnutls_buffer_append_data_prefix (data, 24,
917 apr_cert_list[0].cert.data,
918 apr_cert_list[0].cert.size);
919 if (ret < 0)
920 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 920);
921 }
922 else /* empty - no certificate */
923 {
924 type = PGP_KEY;
925
926 ret = _gnutls_buffer_append_data (data, &type, 1);
927 if (ret < 0)
928 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 928);
929
930 ret = _gnutls_buffer_append_prefix (data, 24, 0);
931 if (ret < 0)
932 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 932);
933 }
934
935 return data->length;
936}
937
938static int
939_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
940 gnutls_buffer_st * data)
941{
942 int ret, packet_size;
943 uint8_t type, fpr[20];
944 size_t fpr_size;
945 gnutls_pcert_st *apr_cert_list;
946 gnutls_privkey_t apr_pkey;
947 int apr_cert_list_length;
948 unsigned int use_subkey = 0;
949
950 /* find the appropriate certificate */
951 if ((ret =
952 _gnutls_get_selected_cert (session, &apr_cert_list,
953 &apr_cert_list_length, &apr_pkey)) < 0)
954 {
955 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",955); } while(0);
;
956 return ret;
957 }
958
959 fpr_size = sizeof (fpr);
960 ret =
961 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
962 &fpr_size, &use_subkey);
963 if (ret < 0)
964 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 964);
965
966 packet_size = 3 + 1;
967
968 if (use_subkey)
969 packet_size += 1 + fpr_size; /* for the keyid */
970
971 /* Only v4 fingerprints are sent
972 */
973 if (apr_cert_list_length > 0)
974 packet_size += 20 + 1;
975 else /* empty certificate case */
976 return _gnutls_gen_openpgp_certificate (session, data);
977
978 ret = _gnutls_buffer_append_prefix (data, 24, packet_size - 3);
979 if (ret < 0)
980 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 980);
981
982 if (use_subkey)
983 {
984 type = PGP_KEY_FINGERPRINT_SUBKEY;
985 ret = _gnutls_buffer_append_data (data, &type, 1);
986 if (ret < 0)
987 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 987);
988
989 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
990 if (ret < 0)
991 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 991);
992 }
993 else
994 {
995 type = PGP_KEY_FINGERPRINT; /* key fingerprint */
996 ret = _gnutls_buffer_append_data (data, &type, 1);
997 if (ret < 0)
998 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 998);
999 }
1000
1001 fpr_size = sizeof (fpr);
1002 if ((ret =
1003 _gnutls_openpgp_fingerprint (&apr_cert_list[0].cert, fpr,
1004 &fpr_size)) < 0)
1005 {
1006 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1006); } while(0);
;
1007 return ret;
1008 }
1009
1010 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
1011 if (ret < 0)
1012 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 1012);
1013
1014 return data->length;
1015}
1016#endif
1017
1018
1019int
1020_gnutls_gen_cert_client_certificate (gnutls_session_t session,
1021 gnutls_buffer_st * data)
1022{
1023 switch (session->security_parameters.cert_type)
1024 {
1025#ifdef ENABLE_OPENPGP1
1026 case GNUTLS_CRT_OPENPGP:
1027 if (_gnutls_openpgp_send_fingerprint (session) == 0)
1028 return _gnutls_gen_openpgp_certificate (session, data);
1029 else
1030 return _gnutls_gen_openpgp_certificate_fpr (session, data);
1031#endif
1032 case GNUTLS_CRT_X509:
1033 return _gnutls_gen_x509_crt (session, data);
1034
1035 default:
1036 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1036); } while(0);
;
1037 return GNUTLS_E_INTERNAL_ERROR-59;
1038 }
1039}
1040
1041int
1042_gnutls_gen_cert_server_certificate (gnutls_session_t session,
1043 gnutls_buffer_st * data)
1044{
1045 switch (session->security_parameters.cert_type)
1046 {
1047#ifdef ENABLE_OPENPGP1
1048 case GNUTLS_CRT_OPENPGP:
1049 return _gnutls_gen_openpgp_certificate (session, data);
1050#endif
1051 case GNUTLS_CRT_X509:
1052 return _gnutls_gen_x509_crt (session, data);
1053 default:
1054 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1054); } while(0);
;
1055 return GNUTLS_E_INTERNAL_ERROR-59;
1056 }
1057}
1058
1059/* Process server certificate
1060 */
1061
1062#define CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit
(&peer_certificate_list[x])
for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1063static int
1064_gnutls_proc_x509_server_certificate (gnutls_session_t session,
1065 opaque * data, size_t data_size)
1066{
1067 int size, len, ret;
1068 opaque *p = data;
1069 cert_auth_info_t info;
1070 gnutls_certificate_credentials_t cred;
1071 ssize_t dsize = data_size;
1072 int i;
1073 gnutls_pcert_st *peer_certificate_list;
1074 size_t peer_certificate_list_size = 0, j, x;
1075 gnutls_datum_t tmp;
1076
1077 cred = (gnutls_certificate_credentials_t)
1078 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
1079 if (cred == NULL((void*)0))
1080 {
1081 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1081); } while(0);
;
1082 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1083 }
1084
1085
1086 if ((ret =
1087 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1088 sizeof (cert_auth_info_st), 1)) < 0)
1089 {
1090 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1090); } while(0);
;
1091 return ret;
1092 }
1093
1094 info = _gnutls_get_auth_info (session);
1095
1096 if (data == NULL((void*)0) || data_size == 0)
1097 {
1098 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1098); } while(0);
;
1099 /* no certificate was sent */
1100 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
1101 }
1102
1103 DECR_LEN (dsize, 3)do { dsize-=3; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1103
); } while(0);; return -9;} } while (0)
;
1104 size = _gnutls_read_uint24 (p);
1105 p += 3;
1106
1107 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1108 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1109 */
1110 if (size == 0 || size == 3)
1111 {
1112 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1112); } while(0);
;
1113 /* no certificate was sent */
1114 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
1115 }
1116
1117 i = dsize;
1118 while (i > 0)
1119 {
1120 DECR_LEN (dsize, 3)do { dsize-=3; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1120
); } while(0);; return -9;} } while (0)
;
1121 len = _gnutls_read_uint24 (p);
1122 p += 3;
1123 DECR_LEN (dsize, len)do { dsize-=len; if (dsize<0) {do { if (__builtin_expect((
_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",1123); } while(0);; return -9;} } while (0)
;
1124 peer_certificate_list_size++;
1125 p += len;
1126 i -= len + 3;
1127 }
1128
1129 if (peer_certificate_list_size == 0)
1130 {
1131 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1131); } while(0);
;
1132 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
1133 }
1134
1135 /* Ok we now allocate the memory to hold the
1136 * certificate list
1137 */
1138
1139 peer_certificate_list =
1140 gnutls_calloc (1,
1141 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1142 if (peer_certificate_list == NULL((void*)0))
1143 {
1144 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1144); } while(0);
;
1145 return GNUTLS_E_MEMORY_ERROR-25;
1146 }
1147
1148 p = data + 3;
1149
1150 /* Now we start parsing the list (again).
1151 * We don't use DECR_LEN since the list has
1152 * been parsed before.
1153 */
1154
1155 for (j = 0; j < peer_certificate_list_size; j++)
1156 {
1157 len = _gnutls_read_uint24 (p);
1158 p += 3;
1159
1160 tmp.size = len;
1161 tmp.data = p;
1162
1163 ret =
1164 gnutls_pcert_import_x509_raw (&peer_certificate_list
1165 [j], &tmp, GNUTLS_X509_FMT_DER, 0);
1166 if (ret < 0)
1167 {
1168 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1168); } while(0);
;
1169 goto cleanup;
1170 }
1171
1172 p += len;
1173 }
1174
1175
1176 if ((ret =
1177 _gnutls_copy_certificate_auth_info (info,
1178 peer_certificate_list,
1179 peer_certificate_list_size, 0,
1180 NULL((void*)0))) < 0)
1181 {
1182 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1182); } while(0);
;
1183 goto cleanup;
1184 }
1185
1186 if ((ret =
1187 _gnutls_check_key_usage (&peer_certificate_list[0],
1188 gnutls_kx_get (session))) < 0)
1189 {
1190 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1190); } while(0);
;
1191 goto cleanup;
1192 }
1193
1194 ret = 0;
1195
1196cleanup:
1197 CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit
(&peer_certificate_list[x])
;
1198 gnutls_free (peer_certificate_list);
1199 return ret;
1200
1201}
1202
1203#ifdef ENABLE_OPENPGP1
1204static int
1205_gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
1206 opaque * data, size_t data_size)
1207{
1208 int size, ret, len;
1209 opaque *p = data;
1210 cert_auth_info_t info;
1211 gnutls_certificate_credentials_t cred;
1212 ssize_t dsize = data_size;
1213 int x, key_type;
1214 gnutls_pcert_st *peer_certificate_list = NULL((void*)0);
1215 int peer_certificate_list_size = 0;
1216 gnutls_datum_t tmp, akey = { NULL((void*)0), 0 };
1217 uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE8];
1218 unsigned int subkey_id_set = 0;
1219
1220 cred = (gnutls_certificate_credentials_t)
1221 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
1222 if (cred == NULL((void*)0))
1223 {
1224 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1224); } while(0);
;
1225 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1226 }
1227
1228 if ((ret =
1229 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1230 sizeof (cert_auth_info_st), 1)) < 0)
1231 {
1232 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1232); } while(0);
;
1233 return ret;
1234 }
1235
1236 info = _gnutls_get_auth_info (session);
1237
1238 if (data == NULL((void*)0) || data_size == 0)
1239 {
1240 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1240); } while(0);
;
1241 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
1242 }
1243
1244 DECR_LEN (dsize, 3)do { dsize-=3; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1244
); } while(0);; return -9;} } while (0)
;
1245 size = _gnutls_read_uint24 (p);
1246 p += 3;
1247
1248 if (size == 0)
1249 {
1250 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1250); } while(0);
;
1251 /* no certificate was sent */
1252 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
1253 }
1254
1255 /* Read PGPKeyDescriptor */
1256 DECR_LEN (dsize, 1)do { dsize-=1; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1256
); } while(0);; return -9;} } while (0)
;
1257 key_type = *p;
1258 p++;
1259
1260 /* Try to read the keyid if present */
1261 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1262 {
1263 /* check size */
1264 if (*p != GNUTLS_OPENPGP_KEYID_SIZE8)
1265 {
1266 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1266); } while(0);
;
1267 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE-61;
1268 }
1269
1270 DECR_LEN (dsize, 1)do { dsize-=1; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1270
); } while(0);; return -9;} } while (0)
;
1271 p++;
1272
1273 DECR_LEN (dsize, GNUTLS_OPENPGP_KEYID_SIZE)do { dsize-=8; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1273
); } while(0);; return -9;} } while (0)
;
1274 memcpy (subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE8);
1275 p += GNUTLS_OPENPGP_KEYID_SIZE8;
1276
1277 subkey_id_set = 1;
1278
1279 }
1280
1281 /* read the actual key or fingerprint */
1282 if (key_type == PGP_KEY_FINGERPRINT
1283 || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1284 { /* the fingerprint */
1285
1286 DECR_LEN (dsize, 1)do { dsize-=1; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1286
); } while(0);; return -9;} } while (0)
;
1287 len = (uint8_t) * p;
1288 p++;
1289
1290 if (len != 20)
1291 {
1292 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1292); } while(0);
;
1293 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED-94;
1294 }
1295
1296 DECR_LEN (dsize, 20)do { dsize-=20; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1296
); } while(0);; return -9;} } while (0)
;
1297
1298 /* request the actual key from our database, or
1299 * a key server or anything.
1300 */
1301 if ((ret =
1302 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1303 {
1304 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1304); } while(0);
;
1305 return ret;
1306 }
1307 tmp = akey;
1308 peer_certificate_list_size++;
1309
1310 }
1311 else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
1312 { /* the whole key */
1313
1314 /* Read the actual certificate */
1315 DECR_LEN (dsize, 3)do { dsize-=3; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1315
); } while(0);; return -9;} } while (0)
;
1316 len = _gnutls_read_uint24 (p);
1317 p += 3;
1318
1319 if (len == 0)
1320 {
1321 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1321); } while(0);
;
1322 /* no certificate was sent */
1323 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
1324 }
1325
1326 DECR_LEN (dsize, len)do { dsize-=len; if (dsize<0) {do { if (__builtin_expect((
_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",1326); } while(0);; return -9;} } while (0)
;
1327 peer_certificate_list_size++;
1328
1329 tmp.size = len;
1330 tmp.data = p;
1331
1332 }
1333 else
1334 {
1335 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1335); } while(0);
;
1336 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE-61;
1337 }
1338
1339 /* ok we now have the peer's key in tmp datum
1340 */
1341
1342 if (peer_certificate_list_size == 0)
1343 {
1344 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1344); } while(0);
;
1345 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
1346 }
1347
1348 peer_certificate_list =
1349 gnutls_calloc (1,
1350 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1351 if (peer_certificate_list == NULL((void*)0))
1352 {
1353 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1353); } while(0);
;
1354 ret = GNUTLS_E_MEMORY_ERROR-25;
1355 goto cleanup;
1356 }
1357
1358 ret =
1359 gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0],
1360 &tmp,
1361 GNUTLS_OPENPGP_FMT_RAW,
1362 (subkey_id_set != 0) ? subkey_id : NULL((void*)0),
1363 0);
1364 if (ret < 0)
1365 {
1366 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1366); } while(0);
;
1367 goto cleanup;
1368 }
1369
1370 ret =
1371 _gnutls_copy_certificate_auth_info (info,
1372 peer_certificate_list,
1373 peer_certificate_list_size,
1374 subkey_id_set,
1375 (subkey_id_set !=
1376 0) ? subkey_id : NULL((void*)0));
1377 if (ret < 0)
1378 {
1379 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1379); } while(0);
;
1380 goto cleanup;
1381 }
1382
1383 if ((ret =
1384 _gnutls_check_key_usage (&peer_certificate_list[0],
1385 gnutls_kx_get (session))) < 0)
1386 {
1387 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1387); } while(0);
;
1388 goto cleanup;
1389 }
1390
1391 ret = 0;
1392
1393cleanup:
1394
1395 _gnutls_free_datum (&akey)_gnutls_free_datum_m(&akey, gnutls_free);
1396 CLEAR_CERTSfor(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit
(&peer_certificate_list[x])
;
1397 gnutls_free (peer_certificate_list);
1398 return ret;
1399
1400}
1401#endif
1402
1403int
1404_gnutls_proc_certificate (gnutls_session_t session,
1405 opaque * data, size_t data_size)
1406{
1407 int ret;
1408 gnutls_certificate_credentials_t cred;
1409
1410 cred =
1411 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
1412 GNUTLS_CRD_CERTIFICATE,
1413 NULL((void*)0));
1414 if (cred == NULL((void*)0))
1415 {
1416 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1416); } while(0);
;
1417 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1418 }
1419
1420 switch (session->security_parameters.cert_type)
1421 {
1422#ifdef ENABLE_OPENPGP1
1423 case GNUTLS_CRT_OPENPGP:
1424 ret = _gnutls_proc_openpgp_server_certificate (session,
1425 data, data_size);
1426 break;
1427#endif
1428 case GNUTLS_CRT_X509:
1429 ret = _gnutls_proc_x509_server_certificate (session, data, data_size);
1430 break;
1431 default:
1432 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1432); } while(0);
;
1433 return GNUTLS_E_INTERNAL_ERROR-59;
1434 }
1435
1436 if (ret == 0 && cred->verify_callback != NULL((void*)0))
1437 {
1438 ret = cred->verify_callback (session);
1439 if (ret != 0)
1440 ret = GNUTLS_E_CERTIFICATE_ERROR-43;
1441 }
1442
1443 return ret;
1444}
1445
1446
1447/* Checks if we support the given signature algorithm
1448 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1449 * if true;
1450 */
1451inline static int
1452_gnutls_check_supported_sign_algo (CertificateSigType algo)
1453{
1454 switch (algo)
1455 {
1456 case RSA_SIGN:
1457 return GNUTLS_PK_RSA;
1458 case DSA_SIGN:
1459 return GNUTLS_PK_DSA;
1460 case ECDSA_SIGN:
1461 return GNUTLS_PK_EC;
1462 }
1463
1464 return -1;
1465}
1466
1467int
1468_gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1469 size_t data_size)
1470{
1471 int size, ret;
1472 opaque *p;
1473 gnutls_certificate_credentials_t cred;
1474 ssize_t dsize;
1475 int i;
1476 gnutls_pk_algorithm_t pk_algos[MAX_CLIENT_SIGN_ALGOS3];
1477 int pk_algos_length;
1478 gnutls_protocol_t ver = gnutls_protocol_get_version_gnutls_protocol_get_version (session);
1479
1480 cred = (gnutls_certificate_credentials_t)
1481 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
1482 if (cred == NULL((void*)0))
1483 {
1484 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1484); } while(0);
;
1485 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1486 }
1487
1488 if ((ret =
1489 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1490 sizeof (cert_auth_info_st), 0)) < 0)
1491 {
1492 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1492); } while(0);
;
1493 return ret;
1494 }
1495
1496 p = data;
1497 dsize = data_size;
1498
1499 DECR_LEN (dsize, 1)do { dsize-=1; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1499
); } while(0);; return -9;} } while (0)
;
1500 size = p[0];
1501 p++;
1502 /* check if the sign algorithm is supported.
1503 */
1504 pk_algos_length = 0;
1505 for (i = 0; i < size; i++, p++)
1506 {
1507 DECR_LEN (dsize, 1)do { dsize-=1; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1507
); } while(0);; return -9;} } while (0)
;
1508 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1509 {
1510 if (pk_algos_length < MAX_CLIENT_SIGN_ALGOS3)
1511 {
1512 pk_algos[pk_algos_length++] = ret;
1513 }
1514 }
1515 }
1516
1517 if (pk_algos_length == 0)
1518 {
1519 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1519); } while(0);
;
1520 return GNUTLS_E_UNKNOWN_PK_ALGORITHM-80;
1521 }
1522
1523 if (_gnutls_version_has_selectable_sighash (ver))
1524 {
1525 /* read supported hashes */
1526 int hash_num;
1527 DECR_LEN (dsize, 2)do { dsize-=2; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1527
); } while(0);; return -9;} } while (0)
;
1528 hash_num = _gnutls_read_uint16 (p);
1529 p += 2;
1530 DECR_LEN (dsize, hash_num)do { dsize-=hash_num; if (dsize<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",1530); } while(0);; return -9;} } while (0)
;
1531
1532 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1533 if (ret < 0)
1534 {
1535 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1535); } while(0);
;
1536 return ret;
1537 }
1538
1539 p += hash_num;
1540 }
1541
1542 /* read the certificate authorities */
1543 DECR_LEN (dsize, 2)do { dsize-=2; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1543
); } while(0);; return -9;} } while (0)
;
1544 size = _gnutls_read_uint16 (p);
1545 p += 2;
1546
1547 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1548 && size != 0)
1549 {
1550 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1550); } while(0);
;
1551 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
1552 }
1553
1554 DECR_LEN (dsize, size)do { dsize-=size; if (dsize<0) {do { if (__builtin_expect(
(_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",1554); } while(0);; return -9;} } while (0)
;
1555
1556 /* now we ask the user to tell which one
1557 * he wants to use.
1558 */
1559 if ((ret =
1560 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1561 {
1562 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1562); } while(0);
;
1563 return ret;
1564 }
1565
1566 /* We should reply with a certificate message,
1567 * even if we have no certificate to send.
1568 */
1569 session->key->certificate_requested = 1;
1570
1571 return 0;
1572}
1573
1574int
1575_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session,
1576 gnutls_buffer_st * data)
1577{
1578 int ret;
1579 gnutls_pcert_st *apr_cert_list;
1580 gnutls_privkey_t apr_pkey;
1581 int apr_cert_list_length;
1582 gnutls_datum_t signature = { NULL((void*)0), 0 };
1583 int total_data;
1584 gnutls_sign_algorithm_t sign_algo;
1585 gnutls_protocol_t ver = gnutls_protocol_get_version_gnutls_protocol_get_version (session);
1586
1587 /* find the appropriate certificate */
1588 if ((ret =
1589 _gnutls_get_selected_cert (session, &apr_cert_list,
1590 &apr_cert_list_length, &apr_pkey)) < 0)
1591 {
1592 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1592); } while(0);
;
1593 return ret;
1594 }
1595
1596 if (apr_cert_list_length > 0)
1597 {
1598 if ((ret =
1599 _gnutls_handshake_sign_cert_vrfy (session,
1600 &apr_cert_list[0],
1601 apr_pkey, &signature)) < 0)
1602 {
1603 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1603); } while(0);
;
1604 return ret;
1605 }
1606 sign_algo = ret;
1607 }
1608 else
1609 {
1610 return 0;
1611 }
1612
1613 total_data = signature.size + 2;
1614
1615 /* add hash and signature algorithms */
1616 if (_gnutls_version_has_selectable_sighash (ver))
1617 {
1618 total_data += 2;
1619 }
1620
1621 if (_gnutls_version_has_selectable_sighash (ver))
1622 {
1623 const sign_algorithm_st *aid;
1624 uint8_t p[2];
1625 /* error checking is not needed here since we have used those algorithms */
1626 aid = _gnutls_sign_to_tls_aid (sign_algo);
1627 if (aid == NULL((void*)0))
1628 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM)gnutls_assert_val_int(-105, "cert.c", 1628);
1629
1630 p[0] = aid->hash_algorithm;
1631 p[1] = aid->sign_algorithm;
1632 ret = _gnutls_buffer_append_data (data, p, 2);
1633 if (ret < 0)
1634 {
1635 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1635); } while(0);
;
1636 goto cleanup;
1637 }
1638 }
1639
1640 ret =
1641 _gnutls_buffer_append_data_prefix (data, 16, signature.data,
1642 signature.size);
1643 if (ret < 0)
1644 {
1645 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1645); } while(0);
;
1646 goto cleanup;
1647 }
1648
1649 ret = data->length;
1650
1651cleanup:
1652 _gnutls_free_datum (&signature)_gnutls_free_datum_m(&signature, gnutls_free);
1653 return ret;
1654}
1655
1656int
1657_gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1658 opaque * data, size_t data_size)
1659{
1660 int size, ret;
1661 ssize_t dsize = data_size;
1662 opaque *pdata = data;
1663 gnutls_datum_t sig;
1664 cert_auth_info_t info = _gnutls_get_auth_info (session);
1665 gnutls_pcert_st peer_cert;
1666 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1667 gnutls_protocol_t ver = gnutls_protocol_get_version_gnutls_protocol_get_version (session);
1668
1669 if (info == NULL((void*)0) || info->ncerts == 0)
1670 {
1671 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1671); } while(0);
;
1672 /* we need this in order to get peer's certificate */
1673 return GNUTLS_E_INTERNAL_ERROR-59;
1674 }
1675
1676 if (_gnutls_version_has_selectable_sighash (ver))
1677 {
1678 sign_algorithm_st aid;
1679
1680 DECR_LEN (dsize, 2)do { dsize-=2; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1680
); } while(0);; return -9;} } while (0)
;
1681 aid.hash_algorithm = pdata[0];
1682 aid.sign_algorithm = pdata[1];
1683
1684 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1685 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
1686 {
1687 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1687); } while(0);
;
1688 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM-106;
1689 }
1690 pdata += 2;
1691 }
1692
1693 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1694 if (ret < 0)
1695 {
1696 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1696); } while(0);
;
1697 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM-106;
1698 }
1699
1700 DECR_LEN (dsize, 2)do { dsize-=2; if (dsize<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "cert.c",1700
); } while(0);; return -9;} } while (0)
;
1701 size = _gnutls_read_uint16 (pdata);
1702 pdata += 2;
1703
1704 DECR_LEN (dsize, size)do { dsize-=size; if (dsize<0) {do { if (__builtin_expect(
(_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "cert.c",1704); } while(0);; return -9;} } while (0)
;
1705
1706 sig.data = pdata;
1707 sig.size = size;
1708
1709 ret = _gnutls_get_auth_info_pcert (&peer_cert,
1710 session->security_parameters.cert_type,
1711 info);
1712
1713 if (ret < 0)
1714 {
1715 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1715); } while(0);
;
1716 return ret;
1717 }
1718
1719 if ((ret =
1720 _gnutls_handshake_verify_cert_vrfy (session, &peer_cert, &sig,
1721 sign_algo)) < 0)
1722 {
1723 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1723); } while(0);
;
1724 gnutls_pcert_deinit (&peer_cert);
1725 return ret;
1726 }
1727 gnutls_pcert_deinit (&peer_cert);
1728
1729 return 0;
1730}
1731
1732int
1733_gnutls_gen_cert_server_cert_req (gnutls_session_t session,
1734 gnutls_buffer_st * data)
1735{
1736 gnutls_certificate_credentials_t cred;
1737 int size, ret;
1738 uint8_t tmp_data[CERTTYPE_SIZE(3 +1)];
1739 gnutls_protocol_t ver = gnutls_protocol_get_version_gnutls_protocol_get_version (session);
1740
1741 /* Now we need to generate the RDN sequence. This is
1742 * already in the CERTIFICATE_CRED structure, to improve
1743 * performance.
1744 */
1745
1746 cred = (gnutls_certificate_credentials_t)
1747 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
1748 if (cred == NULL((void*)0))
1749 {
1750 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1750); } while(0);
;
1751 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1752 }
1753
1754 size = CERTTYPE_SIZE(3 +1) + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1755 */
1756
1757 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1758 session->internals.ignore_rdn_sequence == 0)
1759 size += cred->x509_rdn_sequence.size;
1760
1761 if (_gnutls_version_has_selectable_sighash (ver))
1762 /* Need two bytes to announce the number of supported hash
1763 functions (see below). */
1764 size += MAX_SIGN_ALGO_SIZE(2 + 16 * 2);
1765
1766 tmp_data[0] = CERTTYPE_SIZE(3 +1) - 1;
1767 tmp_data[1] = RSA_SIGN;
1768 tmp_data[2] = DSA_SIGN;
1769 tmp_data[3] = ECDSA_SIGN; /* only these for now */
1770
1771 ret = _gnutls_buffer_append_data (data, tmp_data, CERTTYPE_SIZE(3 +1));
1772 if (ret < 0)
1773 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 1773);
1774
1775 if (_gnutls_version_has_selectable_sighash (ver))
1776 {
1777 uint8_t p[MAX_SIGN_ALGO_SIZE(2 + 16 * 2)];
1778
1779 ret =
1780 _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE(2 + 16 * 2));
1781 if (ret < 0)
1782 {
1783 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1783); } while(0);
;
1784 return ret;
1785 }
1786
1787 /* recalculate size */
1788 size -= MAX_SIGN_ALGO_SIZE(2 + 16 * 2) + ret;
Value stored to 'size' is never read
1789
1790 ret = _gnutls_buffer_append_data (data, p, ret);
1791 if (ret < 0)
1792 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 1792);
1793 }
1794
1795 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1796 session->internals.ignore_rdn_sequence == 0)
1797 {
1798 ret =
1799 _gnutls_buffer_append_data_prefix (data, 16,
1800 cred->x509_rdn_sequence.data,
1801 cred->x509_rdn_sequence.size);
1802 if (ret < 0)
1803 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 1803);
1804 }
1805 else
1806 {
1807 ret = _gnutls_buffer_append_prefix (data, 16, 0);
1808 if (ret < 0)
1809 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 1809);
1810 }
1811
1812 return data->length;
1813}
1814
1815
1816/* This function will return the appropriate certificate to use.
1817 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1818 * The return value is a negative error code on error.
1819 *
1820 * It is normal to return 0 with no certificates in client side.
1821 *
1822 */
1823int
1824_gnutls_get_selected_cert (gnutls_session_t session,
1825 gnutls_pcert_st ** apr_cert_list,
1826 int *apr_cert_list_length,
1827 gnutls_privkey_t * apr_pkey)
1828{
1829 if (session->security_parameters.entity == GNUTLS_SERVER1)
1830 {
1831
1832 /* select_client_cert() has been called before.
1833 */
1834
1835 *apr_cert_list = session->internals.selected_cert_list;
1836 *apr_pkey = session->internals.selected_key;
1837 *apr_cert_list_length = session->internals.selected_cert_list_length;
1838
1839 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL((void*)0))
1840 {
1841 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1841); } while(0);
;
1842 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1843 }
1844
1845 }
1846 else
1847 { /* CLIENT SIDE
1848 */
1849
1850 /* we have already decided which certificate
1851 * to send.
1852 */
1853 *apr_cert_list = session->internals.selected_cert_list;
1854 *apr_cert_list_length = session->internals.selected_cert_list_length;
1855 *apr_pkey = session->internals.selected_key;
1856
1857 }
1858
1859 return 0;
1860}
1861
1862/* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1863 * space for them.
1864 */
1865static gnutls_pcert_st *
1866alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1867{
1868 gnutls_pcert_st *local_certs;
1869 int ret = 0;
1870 unsigned i, j;
1871
1872 if (certs == NULL((void*)0))
1873 return NULL((void*)0);
1874
1875 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st) * ncerts);
1876 if (local_certs == NULL((void*)0))
1877 {
1878 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1878); } while(0);
;
1879 return NULL((void*)0);
1880 }
1881
1882 for (i = 0; i < ncerts; i++)
1883 {
1884 ret = gnutls_pcert_import_x509 (&local_certs[i], certs[i], 0);
1885 if (ret < 0)
1886 break;
1887 }
1888
1889 if (ret < 0)
1890 {
1891 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1891); } while(0);
;
1892 for (j = 0; j < i; j++)
1893 {
1894 gnutls_pcert_deinit (&local_certs[j]);
1895 }
1896 gnutls_free (local_certs);
1897 return NULL((void*)0);
1898 }
1899
1900 return local_certs;
1901}
1902
1903/* converts the given x509 key to gnutls_privkey* and allocates
1904 * space for it.
1905 */
1906static gnutls_privkey_t
1907alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1908{
1909 gnutls_privkey_t local_key;
1910 int ret = 0;
1911
1912 if (key == NULL((void*)0))
1913 return NULL((void*)0);
1914
1915 ret = gnutls_privkey_init (&local_key);
1916 if (ret < 0)
1917 {
1918 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1918); } while(0);
;
1919 return NULL((void*)0);
1920 }
1921
1922 ret =
1923 gnutls_privkey_import_x509 (local_key, key,
1924 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE(1<<0) :
1925 0);
1926 if (ret < 0)
1927 {
1928 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1928); } while(0);
;
1929 gnutls_privkey_deinit (local_key);
1930 return NULL((void*)0);
1931 }
1932
1933 return local_key;
1934}
1935
1936/* converts the given pgp certificate to gnutls_cert* and allocates
1937 * space for them.
1938 */
1939#ifdef ENABLE_OPENPGP1
1940static gnutls_pcert_st *
1941alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1942{
1943 gnutls_pcert_st *local_certs;
1944 int ret = 0;
1945
1946 if (cert == NULL((void*)0))
1947 return NULL((void*)0);
1948
1949 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st));
1950 if (local_certs == NULL((void*)0))
1951 {
1952 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1952); } while(0);
;
1953 return NULL((void*)0);
1954 }
1955
1956 ret = gnutls_pcert_import_openpgp (local_certs, cert, 0);
1957 if (ret < 0)
1958 {
1959 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1959); } while(0);
;
1960 return NULL((void*)0);
1961 }
1962
1963 if (ret < 0)
1964 {
1965 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1965); } while(0);
;
1966 gnutls_pcert_deinit (local_certs);
1967 gnutls_free (local_certs);
1968 return NULL((void*)0);
1969 }
1970
1971 return local_certs;
1972}
1973
1974/* converts the given raw key to gnutls_privkey* and allocates
1975 * space for it.
1976 */
1977static gnutls_privkey_t
1978alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1979{
1980 gnutls_privkey_t local_key;
1981 int ret = 0;
1982
1983 if (key == NULL((void*)0))
1984 return NULL((void*)0);
1985
1986 ret = gnutls_privkey_init (&local_key);
1987 if (ret < 0)
1988 {
1989 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1989); } while(0);
;
1990 return NULL((void*)0);
1991 }
1992
1993 ret =
1994 gnutls_privkey_import_openpgp (local_key, key,
1995 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE(1<<0)
1996 : 0);
1997 if (ret < 0)
1998 {
1999 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",1999); } while(0);
;
2000 gnutls_privkey_deinit (local_key);
2001 return NULL((void*)0);
2002 }
2003
2004 return local_key;
2005}
2006#endif
2007
2008#ifdef ENABLE_PKCS111
2009
2010/* converts the given raw key to gnutls_privkey* and allocates
2011 * space for it.
2012 */
2013static gnutls_privkey_t
2014alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
2015{
2016 gnutls_privkey_t local_key;
2017 int ret = 0;
2018
2019 if (key == NULL((void*)0))
2020 return NULL((void*)0);
2021
2022 ret = gnutls_privkey_init (&local_key);
2023 if (ret < 0)
2024 {
2025 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",2025); } while(0);
;
2026 return NULL((void*)0);
2027 }
2028
2029 ret =
2030 gnutls_privkey_import_pkcs11 (local_key, key,
2031 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE(1<<0)
2032 : 0);
2033 if (ret < 0)
2034 {
2035 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",2035); } while(0);
;
2036 gnutls_privkey_deinit (local_key);
2037 return NULL((void*)0);
2038 }
2039
2040 return local_key;
2041}
2042
2043#endif
2044
2045void
2046_gnutls_selected_certs_deinit (gnutls_session_t session)
2047{
2048 if (session->internals.selected_need_free != 0)
2049 {
2050 int i;
2051
2052 for (i = 0; i < session->internals.selected_cert_list_length; i++)
2053 {
2054 gnutls_pcert_deinit (&session->internals.selected_cert_list[i]);
2055 }
2056 gnutls_free (session->internals.selected_cert_list);
2057 session->internals.selected_cert_list = NULL((void*)0);
2058 session->internals.selected_cert_list_length = 0;
2059
2060 gnutls_privkey_deinit(session->internals.selected_key);
2061 session->internals.selected_key = NULL((void*)0);
2062 }
2063
2064 return;
2065}
2066
2067void
2068_gnutls_selected_certs_set (gnutls_session_t session,
2069 gnutls_pcert_st * certs, int ncerts,
2070 gnutls_privkey_t key, int need_free)
2071{
2072 _gnutls_selected_certs_deinit (session);
2073
2074 session->internals.selected_cert_list = certs;
2075 session->internals.selected_cert_list_length = ncerts;
2076 session->internals.selected_key = key;
2077 session->internals.selected_need_free = need_free;
2078
2079}
2080
2081static void get_server_name(gnutls_session_t session, uint8_t* name, size_t max_name_size)
2082{
2083int ret, i;
2084size_t max_name;
2085unsigned int type;
2086
2087 ret = 0;
2088 for (i=0; !(ret<0);i++)
2089 {
2090 max_name = max_name_size;
2091 ret = gnutls_server_name_get (session, name, &max_name, &type, i);
2092 if (ret >= 0 && type == GNUTLS_NAME_DNS)
2093 return;
2094 }
2095
2096 name[0] = 0;
2097
2098 return;
2099}
2100
2101/* finds the most appropriate certificate in the cert list.
2102 * The 'appropriate' is defined by the user.
2103 *
2104 * requested_algo holds the parameters required by the peer (RSA, DSA
2105 * or -1 for any).
2106 *
2107 * Returns 0 on success and a negative error code on error. The
2108 * selected certificate will be in session->internals.selected_*.
2109 *
2110 */
2111int
2112_gnutls_server_select_cert (gnutls_session_t session,
2113 gnutls_pk_algorithm_t * pk_algos,
2114 size_t pk_algos_size)
2115{
2116 unsigned i, j;
2117 int idx, ret;
2118 gnutls_certificate_credentials_t cred;
2119 char server_name[MAX_CN256];
2120
2121 cred = (gnutls_certificate_credentials_t)
2122 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL((void*)0));
2123 if (cred == NULL((void*)0))
2124 {
2125 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",2125); } while(0);
;
2126 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
2127 }
2128
2129 /* If the callback which retrieves certificate has been set,
2130 * use it and leave.
2131 */
2132 if (cred->server_get_cert_callback != NULL((void*)0) || cred->server_get_cert_callback
2133 || cred->get_cert_callback2)
2134 {
2135 ret = call_get_cert_callback (session, NULL((void*)0), 0, NULL((void*)0), 0);
2136 if (ret < 0)
2137 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "cert.c", 2137);
2138 return ret;
2139 }
2140
2141 /* Otherwise... */
2142
2143 get_server_name(session, server_name, sizeof(server_name));
2144
2145 idx = -1; /* default is use no certificate */
2146
2147 /* find certificates that match the requested server_name
2148 */
2149
2150 if (server_name[0] != 0)
2151 {
2152 for (i = 0; i < cred->ncerts; i++)
2153 {
2154 if (cred->certs[i].names != NULL((void*)0) && _gnutls_str_array_match(cred->certs[i].names, server_name) != 0)
2155 {
2156 /* if requested algorithms are also compatible select it */
2157 gnutls_pk_algorithmgnutls_pk_algorithm_t pk =
2158 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2159 NULL((void*)0));
2160
2161 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session, server_name,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session
, server_name, gnutls_certificate_type_get_name (session->
security_parameters.cert_type), session->security_parameters
.cert_type); } while(0)
2162 gnutls_certificate_type_get_name (session->security_parameters.cert_type),do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session
, server_name, gnutls_certificate_type_get_name (session->
security_parameters.cert_type), session->security_parameters
.cert_type); } while(0)
2163 session->security_parameters.cert_type)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session
, server_name, gnutls_certificate_type_get_name (session->
security_parameters.cert_type), session->security_parameters
.cert_type); } while(0)
;
2164
2165 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2166 {
2167 for (j = 0; j < pk_algos_size; j++)
2168 if (pk_algos[j] == pk)
2169 {
2170 idx = i;
2171 goto finished;
2172 }
2173 }
2174 }
2175 }
2176 }
2177
2178 for (j = 0; j < pk_algos_size; j++)
2179 {
2180 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n"
, session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j], gnutls_certificate_type_get_name
(session->security_parameters. cert_type), session->security_parameters
.cert_type); } while(0)
2181 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n"
, session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j], gnutls_certificate_type_get_name
(session->security_parameters. cert_type), session->security_parameters
.cert_type); } while(0)
2182 session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j],do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n"
, session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j], gnutls_certificate_type_get_name
(session->security_parameters. cert_type), session->security_parameters
.cert_type); } while(0)
2183 gnutls_certificate_type_get_name (session->security_parameters.do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n"
, session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j], gnutls_certificate_type_get_name
(session->security_parameters. cert_type), session->security_parameters
.cert_type); } while(0)
2184 cert_type),do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n"
, session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j], gnutls_certificate_type_get_name
(session->security_parameters. cert_type), session->security_parameters
.cert_type); } while(0)
2185 session->security_parameters.cert_type)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n"
, session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j], gnutls_certificate_type_get_name
(session->security_parameters. cert_type), session->security_parameters
.cert_type); } while(0)
;
2186
2187 for (i = 0; i < cred->ncerts; i++)
2188 {
2189 gnutls_pk_algorithmgnutls_pk_algorithm_t pk =
2190 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2191 NULL((void*)0));
2192 /* find one compatible certificate
2193 */
2194 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n"
, session, i, gnutls_pk_get_name (pk), pk, gnutls_certificate_type_get_name
(cred->certs[i].cert_list[0].type), cred->certs[i].cert_list
[0].type); } while(0)
2195 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n"
, session, i, gnutls_pk_get_name (pk), pk, gnutls_certificate_type_get_name
(cred->certs[i].cert_list[0].type), cred->certs[i].cert_list
[0].type); } while(0)
2196 session, i, gnutls_pk_get_name (pk), pk,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n"
, session, i, gnutls_pk_get_name (pk), pk, gnutls_certificate_type_get_name
(cred->certs[i].cert_list[0].type), cred->certs[i].cert_list
[0].type); } while(0)
2197 gnutls_certificate_type_get_name (cred->certs[i].cert_list[0].type),do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n"
, session, i, gnutls_pk_get_name (pk), pk, gnutls_certificate_type_get_name
(cred->certs[i].cert_list[0].type), cred->certs[i].cert_list
[0].type); } while(0)
2198 cred->certs[i].cert_list[0].type)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n"
, session, i, gnutls_pk_get_name (pk), pk, gnutls_certificate_type_get_name
(cred->certs[i].cert_list[0].type), cred->certs[i].cert_list
[0].type); } while(0)
;
2199
2200 if (pk_algos[j] == pk)
2201 {
2202 /* if cert type matches
2203 */
2204 /* *INDENT-OFF* */
2205 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2206 {
2207 idx = i;
2208 goto finished;
2209 }
2210 /* *INDENT-ON* */
2211 }
2212 }
2213 }
2214
2215 /* store the certificate pointer for future use, in the handshake.
2216 * (This will allow not calling this callback again.)
2217 */
2218finished:
2219 if (idx >= 0)
2220 {
2221 _gnutls_selected_certs_set (session,
2222 &cred->certs[idx].cert_list[0],
2223 cred->certs[idx].cert_list_length,
2224 cred->pkey[idx], 0);
2225 }
2226 else
2227 {
2228 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "cert.c",2228); } while(0);
;
2229 /* Certificate does not support REQUESTED_ALGO. */
2230 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
2231 }
2232
2233 return 0;
2234}
2235
2236/* Frees the rsa_info_st structure.
2237 */
2238void
2239_gnutls_free_rsa_info (rsa_info_st * rsa)
2240{
2241 _gnutls_free_datum (&rsa->modulus)_gnutls_free_datum_m(&rsa->modulus, gnutls_free);
2242 _gnutls_free_datum (&rsa->exponent)_gnutls_free_datum_m(&rsa->exponent, gnutls_free);
2243}