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