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