libpurple/plugins/ssl/ssl-gnutls.c

branch
release-2.x.y
changeset 35978
c0b60f37a7db
parent 31155
757baa7d408f
child 35989
2b5a26ddbb69
child 36146
42ba908c25c7
equal deleted inserted replaced
35977:9b7b48f446f4 35978:c0b60f37a7db
32 #include <gnutls/gnutls.h> 32 #include <gnutls/gnutls.h>
33 #include <gnutls/x509.h> 33 #include <gnutls/x509.h>
34 34
35 typedef struct 35 typedef struct
36 { 36 {
37 gnutls_session session; 37 gnutls_session_t session;
38 guint handshake_handler; 38 guint handshake_handler;
39 guint handshake_timer; 39 guint handshake_timer;
40 } PurpleSslGnutlsData; 40 } PurpleSslGnutlsData;
41 41
42 #define PURPLE_SSL_GNUTLS_DATA(gsc) ((PurpleSslGnutlsData *)gsc->private_data) 42 #define PURPLE_SSL_GNUTLS_DATA(gsc) ((PurpleSslGnutlsData *)gsc->private_data)
282 g_byte_array_free(z, TRUE); 282 g_byte_array_free(z, TRUE);
283 } 283 }
284 g_list_free(peers); 284 g_list_free(peers);
285 285
286 { 286 {
287 const gnutls_datum *cert_list; 287 const gnutls_datum_t *cert_list;
288 unsigned int cert_list_size = 0; 288 unsigned int cert_list_size = 0;
289 gnutls_session session=gnutls_data->session; 289 gnutls_session_t session=gnutls_data->session;
290 int i; 290 int i;
291 291
292 cert_list = 292 cert_list =
293 gnutls_certificate_get_peers(session, &cert_list_size); 293 gnutls_certificate_get_peers(session, &cert_list_size);
294 294
301 gsize fpr_bin_sz = sizeof(fpr_bin); 301 gsize fpr_bin_sz = sizeof(fpr_bin);
302 gchar * fpr_asc = NULL; 302 gchar * fpr_asc = NULL;
303 gchar tbuf[256]; 303 gchar tbuf[256];
304 gsize tsz=sizeof(tbuf); 304 gsize tsz=sizeof(tbuf);
305 gchar * tasc = NULL; 305 gchar * tasc = NULL;
306 gnutls_x509_crt cert; 306 gnutls_x509_crt_t cert;
307 307
308 gnutls_x509_crt_init(&cert); 308 gnutls_x509_crt_init(&cert);
309 gnutls_x509_crt_import (cert, &cert_list[i], 309 gnutls_x509_crt_import (cert, &cert_list[i],
310 GNUTLS_X509_FMT_DER); 310 GNUTLS_X509_FMT_DER);
311 311
312 gnutls_x509_crt_get_fingerprint(cert, GNUTLS_MAC_SHA, 312 gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA,
313 fpr_bin, &fpr_bin_sz); 313 fpr_bin, &fpr_bin_sz);
314 314
315 fpr_asc = 315 fpr_asc =
316 purple_base16_encode_chunked((const guchar *)fpr_bin, fpr_bin_sz); 316 purple_base16_encode_chunked((const guchar *)fpr_bin, fpr_bin_sz);
317 317
384 384
385 static void 385 static void
386 ssl_gnutls_connect(PurpleSslConnection *gsc) 386 ssl_gnutls_connect(PurpleSslConnection *gsc)
387 { 387 {
388 PurpleSslGnutlsData *gnutls_data; 388 PurpleSslGnutlsData *gnutls_data;
389 static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 };
390 389
391 gnutls_data = g_new0(PurpleSslGnutlsData, 1); 390 gnutls_data = g_new0(PurpleSslGnutlsData, 1);
392 gsc->private_data = gnutls_data; 391 gsc->private_data = gnutls_data;
393 392
394 gnutls_init(&gnutls_data->session, GNUTLS_CLIENT); 393 gnutls_init(&gnutls_data->session, GNUTLS_CLIENT);
410 gnutls_priority_set(gnutls_data->session, default_priority); 409 gnutls_priority_set(gnutls_data->session, default_priority);
411 } 410 }
412 #else 411 #else
413 gnutls_set_default_priority(gnutls_data->session); 412 gnutls_set_default_priority(gnutls_data->session);
414 #endif 413 #endif
415
416 gnutls_certificate_type_set_priority(gnutls_data->session,
417 cert_type_priority);
418 414
419 gnutls_credentials_set(gnutls_data->session, GNUTLS_CRD_CERTIFICATE, 415 gnutls_credentials_set(gnutls_data->session, GNUTLS_CRD_CERTIFICATE,
420 xcred); 416 xcred);
421 417
422 gnutls_transport_set_ptr(gnutls_data->session, GINT_TO_POINTER(gsc->fd)); 418 gnutls_transport_set_ptr(gnutls_data->session, GINT_TO_POINTER(gsc->fd));
517 return s; 513 return s;
518 } 514 }
519 515
520 /* Forward declarations are fun! */ 516 /* Forward declarations are fun! */
521 static PurpleCertificate * 517 static PurpleCertificate *
522 x509_import_from_datum(const gnutls_datum dt, gnutls_x509_crt_fmt mode); 518 x509_import_from_datum(const gnutls_datum_t dt, gnutls_x509_crt_fmt_t mode);
523 /* indeed! */ 519 /* indeed! */
524 static gboolean 520 static gboolean
525 x509_certificate_signed_by(PurpleCertificate * crt, 521 x509_certificate_signed_by(PurpleCertificate * crt,
526 PurpleCertificate * issuer); 522 PurpleCertificate * issuer);
527 static void 523 static void
535 531
536 /* List of Certificate instances to return */ 532 /* List of Certificate instances to return */
537 GList * peer_certs = NULL; 533 GList * peer_certs = NULL;
538 534
539 /* List of raw certificates as given by GnuTLS */ 535 /* List of raw certificates as given by GnuTLS */
540 const gnutls_datum *cert_list; 536 const gnutls_datum_t *cert_list;
541 unsigned int cert_list_size = 0; 537 unsigned int cert_list_size = 0;
542 538
543 unsigned int i; 539 unsigned int i;
544 540
545 /* This should never, ever happen. */ 541 /* This should never, ever happen. */
583 static PurpleCertificateScheme x509_gnutls; 579 static PurpleCertificateScheme x509_gnutls;
584 580
585 /** Refcounted GnuTLS certificate data instance */ 581 /** Refcounted GnuTLS certificate data instance */
586 typedef struct { 582 typedef struct {
587 gint refcount; 583 gint refcount;
588 gnutls_x509_crt crt; 584 gnutls_x509_crt_t crt;
589 } x509_crtdata_t; 585 } x509_crtdata_t;
590 586
591 /** Helper functions for reference counting */ 587 /** Helper functions for reference counting */
592 static x509_crtdata_t * 588 static x509_crtdata_t *
593 x509_crtdata_addref(x509_crtdata_t *cd) 589 x509_crtdata_addref(x509_crtdata_t *cd)
625 * "over the wire" certs for SSL) 621 * "over the wire" certs for SSL)
626 * 622 *
627 * @return A newly allocated Certificate structure of the x509_gnutls scheme 623 * @return A newly allocated Certificate structure of the x509_gnutls scheme
628 */ 624 */
629 static PurpleCertificate * 625 static PurpleCertificate *
630 x509_import_from_datum(const gnutls_datum dt, gnutls_x509_crt_fmt mode) 626 x509_import_from_datum(const gnutls_datum_t dt, gnutls_x509_crt_fmt_t mode)
631 { 627 {
632 /* Internal certificate data structure */ 628 /* Internal certificate data structure */
633 x509_crtdata_t *certdat; 629 x509_crtdata_t *certdat;
634 /* New certificate to return */ 630 /* New certificate to return */
635 PurpleCertificate * crt; 631 PurpleCertificate * crt;
660 x509_import_from_file(const gchar * filename) 656 x509_import_from_file(const gchar * filename)
661 { 657 {
662 PurpleCertificate *crt; /* Certificate being constructed */ 658 PurpleCertificate *crt; /* Certificate being constructed */
663 gchar *buf; /* Used to load the raw file data */ 659 gchar *buf; /* Used to load the raw file data */
664 gsize buf_sz; /* Size of the above */ 660 gsize buf_sz; /* Size of the above */
665 gnutls_datum dt; /* Struct to pass down to GnuTLS */ 661 gnutls_datum_t dt; /* Struct to pass down to GnuTLS */
666 662
667 purple_debug_info("gnutls", 663 purple_debug_info("gnutls",
668 "Attempting to load X.509 certificate from %s\n", 664 "Attempting to load X.509 certificate from %s\n",
669 filename); 665 filename);
670 666
703 PurpleCertificate *crt; /* Certificate being constructed */ 699 PurpleCertificate *crt; /* Certificate being constructed */
704 gchar *buf; /* Used to load the raw file data */ 700 gchar *buf; /* Used to load the raw file data */
705 gchar *begin, *end; 701 gchar *begin, *end;
706 GSList *crts = NULL; 702 GSList *crts = NULL;
707 gsize buf_sz; /* Size of the above */ 703 gsize buf_sz; /* Size of the above */
708 gnutls_datum dt; /* Struct to pass down to GnuTLS */ 704 gnutls_datum_t dt; /* Struct to pass down to GnuTLS */
709 705
710 purple_debug_info("gnutls", 706 purple_debug_info("gnutls",
711 "Attempting to load X.509 certificates from %s\n", 707 "Attempting to load X.509 certificates from %s\n",
712 filename); 708 filename);
713 709
749 * @return TRUE if success, otherwise FALSE 745 * @return TRUE if success, otherwise FALSE
750 */ 746 */
751 static gboolean 747 static gboolean
752 x509_export_certificate(const gchar *filename, PurpleCertificate *crt) 748 x509_export_certificate(const gchar *filename, PurpleCertificate *crt)
753 { 749 {
754 gnutls_x509_crt crt_dat; /* GnuTLS cert struct */ 750 gnutls_x509_crt_t crt_dat; /* GnuTLS cert struct */
755 int ret; 751 int ret;
756 gchar * out_buf; /* Data to output */ 752 gchar * out_buf; /* Data to output */
757 size_t out_size; /* Output size */ 753 size_t out_size; /* Output size */
758 gboolean success = FALSE; 754 gboolean success = FALSE;
759 755
855 */ 851 */
856 static gboolean 852 static gboolean
857 x509_certificate_signed_by(PurpleCertificate * crt, 853 x509_certificate_signed_by(PurpleCertificate * crt,
858 PurpleCertificate * issuer) 854 PurpleCertificate * issuer)
859 { 855 {
860 gnutls_x509_crt crt_dat; 856 gnutls_x509_crt_t crt_dat;
861 gnutls_x509_crt issuer_dat; 857 gnutls_x509_crt_t issuer_dat;
862 unsigned int verify; /* used to store result from GnuTLS verifier */ 858 unsigned int verify; /* used to store result from GnuTLS verifier */
863 int ret; 859 int ret;
864 gchar *crt_id = NULL; 860 gchar *crt_id = NULL;
865 gchar *issuer_id = NULL; 861 gchar *issuer_id = NULL;
866 862
961 static GByteArray * 957 static GByteArray *
962 x509_sha1sum(PurpleCertificate *crt) 958 x509_sha1sum(PurpleCertificate *crt)
963 { 959 {
964 size_t hashlen = 20; /* SHA1 hashes are 20 bytes */ 960 size_t hashlen = 20; /* SHA1 hashes are 20 bytes */
965 size_t tmpsz = hashlen; /* Throw-away variable for GnuTLS to stomp on*/ 961 size_t tmpsz = hashlen; /* Throw-away variable for GnuTLS to stomp on*/
966 gnutls_x509_crt crt_dat; 962 gnutls_x509_crt_t crt_dat;
967 GByteArray *hash; /**< Final hash container */ 963 GByteArray *hash; /**< Final hash container */
968 guchar hashbuf[hashlen]; /**< Temporary buffer to contain hash */ 964 guchar hashbuf[hashlen]; /**< Temporary buffer to contain hash */
969 965
970 g_return_val_if_fail(crt, NULL); 966 g_return_val_if_fail(crt, NULL);
971 967
972 crt_dat = X509_GET_GNUTLS_DATA(crt); 968 crt_dat = X509_GET_GNUTLS_DATA(crt);
973 969
974 /* Extract the fingerprint */ 970 /* Extract the fingerprint */
975 g_return_val_if_fail( 971 g_return_val_if_fail(
976 0 == gnutls_x509_crt_get_fingerprint(crt_dat, GNUTLS_MAC_SHA, 972 0 == gnutls_x509_crt_get_fingerprint(crt_dat, GNUTLS_DIG_SHA,
977 hashbuf, &tmpsz), 973 hashbuf, &tmpsz),
978 NULL); 974 NULL);
979 975
980 /* This shouldn't happen */ 976 /* This shouldn't happen */
981 g_return_val_if_fail(tmpsz == hashlen, NULL); 977 g_return_val_if_fail(tmpsz == hashlen, NULL);
988 } 984 }
989 985
990 static gchar * 986 static gchar *
991 x509_cert_dn (PurpleCertificate *crt) 987 x509_cert_dn (PurpleCertificate *crt)
992 { 988 {
993 gnutls_x509_crt cert_dat; 989 gnutls_x509_crt_t cert_dat;
994 gchar *dn = NULL; 990 gchar *dn = NULL;
995 size_t dn_size; 991 size_t dn_size;
996 992
997 g_return_val_if_fail(crt, NULL); 993 g_return_val_if_fail(crt, NULL);
998 g_return_val_if_fail(crt->scheme == &x509_gnutls, NULL); 994 g_return_val_if_fail(crt->scheme == &x509_gnutls, NULL);
1021 } 1017 }
1022 1018
1023 static gchar * 1019 static gchar *
1024 x509_issuer_dn (PurpleCertificate *crt) 1020 x509_issuer_dn (PurpleCertificate *crt)
1025 { 1021 {
1026 gnutls_x509_crt cert_dat; 1022 gnutls_x509_crt_t cert_dat;
1027 gchar *dn = NULL; 1023 gchar *dn = NULL;
1028 size_t dn_size; 1024 size_t dn_size;
1029 1025
1030 g_return_val_if_fail(crt, NULL); 1026 g_return_val_if_fail(crt, NULL);
1031 g_return_val_if_fail(crt->scheme == &x509_gnutls, NULL); 1027 g_return_val_if_fail(crt->scheme == &x509_gnutls, NULL);
1055 } 1051 }
1056 1052
1057 static gchar * 1053 static gchar *
1058 x509_common_name (PurpleCertificate *crt) 1054 x509_common_name (PurpleCertificate *crt)
1059 { 1055 {
1060 gnutls_x509_crt cert_dat; 1056 gnutls_x509_crt_t cert_dat;
1061 gchar *cn = NULL; 1057 gchar *cn = NULL;
1062 size_t cn_size; 1058 size_t cn_size;
1063 int ret; 1059 int ret;
1064 1060
1065 g_return_val_if_fail(crt, NULL); 1061 g_return_val_if_fail(crt, NULL);
1098 } 1094 }
1099 1095
1100 static gboolean 1096 static gboolean
1101 x509_check_name (PurpleCertificate *crt, const gchar *name) 1097 x509_check_name (PurpleCertificate *crt, const gchar *name)
1102 { 1098 {
1103 gnutls_x509_crt crt_dat; 1099 gnutls_x509_crt_t crt_dat;
1104 1100
1105 g_return_val_if_fail(crt, FALSE); 1101 g_return_val_if_fail(crt, FALSE);
1106 g_return_val_if_fail(crt->scheme == &x509_gnutls, FALSE); 1102 g_return_val_if_fail(crt->scheme == &x509_gnutls, FALSE);
1107 g_return_val_if_fail(name, FALSE); 1103 g_return_val_if_fail(name, FALSE);
1108 1104
1116 } 1112 }
1117 1113
1118 static gboolean 1114 static gboolean
1119 x509_times (PurpleCertificate *crt, time_t *activation, time_t *expiration) 1115 x509_times (PurpleCertificate *crt, time_t *activation, time_t *expiration)
1120 { 1116 {
1121 gnutls_x509_crt crt_dat; 1117 gnutls_x509_crt_t crt_dat;
1122 /* GnuTLS time functions return this on error */ 1118 /* GnuTLS time functions return this on error */
1123 const time_t errval = (time_t) (-1); 1119 const time_t errval = (time_t) (-1);
1124 gboolean success = TRUE; 1120 gboolean success = TRUE;
1125 1121
1126 g_return_val_if_fail(crt, FALSE); 1122 g_return_val_if_fail(crt, FALSE);

mercurial