]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - libratbox/src/gnutls.c
strip_colour(): strip ASCII 29 (mIRC 7 italics).
[irc/rqf/shadowircd.git] / libratbox / src / gnutls.c
index 51a25defe9dd54e119af66a7ca0b913784929056..e1c0d8f130e856afc3e59b8c283f2b845e6f15ba 100644 (file)
@@ -20,7 +20,6 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
  *  USA
  *
- *  $Id: gnutls.c 26092 2008-09-19 15:13:52Z androsyn $
  */
 
 #include <libratbox_config.h>
@@ -30,6 +29,7 @@
 #ifdef HAVE_GNUTLS
 
 #include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
 #include <gcrypt.h>
 
 static gnutls_certificate_credentials x509;
@@ -108,27 +108,21 @@ rb_ssl_tryaccept(rb_fde_t *F, void *data)
 
        ret = do_ssl_handshake(F, rb_ssl_tryaccept);
 
-       switch (ret)
-       {
-       case -1:
-               F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
-               break;
-       case 0:
-               /* do_ssl_handshake does the rb_setselect stuff */
+       /* do_ssl_handshake does the rb_setselect */
+       if(ret == 0)
                return;
-       default:
-               break;
-
 
-       }
+       ad = F->accept;
+       F->accept = NULL;
        rb_settimeout(F, 0, NULL, NULL);
        rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
+       
+       if(ret > 0)
+               ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
+       else
+               ad->callback(F, RB_ERROR_SSL, NULL, 0, ad->data);
 
-       ad = F->accept;
-       F->accept = NULL;
-       ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
        rb_free(ad);
-
 }
 
 void
@@ -150,6 +144,7 @@ rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
        gnutls_credentials_set(*ssl, GNUTLS_CRD_CERTIFICATE, x509);
        gnutls_dh_set_prime_bits(*ssl, 1024);
        gnutls_transport_set_ptr(*ssl, (gnutls_transport_ptr_t) (long int)new_F->fd);
+       gnutls_certificate_server_set_request(*ssl, GNUTLS_CERT_REQUEST);
        if(do_ssl_handshake(new_F, rb_ssl_tryaccept))
        {
                struct acceptdata *ad = new_F->accept;
@@ -181,6 +176,7 @@ rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrl
        gnutls_credentials_set(SSL_P(new_F), GNUTLS_CRD_CERTIFICATE, x509);
        gnutls_dh_set_prime_bits(SSL_P(new_F), 1024);
        gnutls_transport_set_ptr(SSL_P(new_F), (gnutls_transport_ptr_t) (long int)rb_get_fd(new_F));
+       gnutls_certificate_server_set_request(SSL_P(new_F), GNUTLS_CERT_REQUEST);
        if(do_ssl_handshake(F, rb_ssl_tryaccept))
        {
                struct acceptdata *ad = F->accept;
@@ -502,10 +498,59 @@ rb_get_ssl_strerror(rb_fde_t *F)
        return gnutls_strerror(F->ssl_errno);
 }
 
+int
+rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN])
+{
+       gnutls_x509_crt_t cert;
+       unsigned int cert_list_size;
+       const gnutls_datum_t *cert_list;
+       uint8_t digest[RB_SSL_CERTFP_LEN * 2];
+       size_t digest_size;
+
+       if (gnutls_certificate_type_get(SSL_P(F)) != GNUTLS_CRT_X509)
+               return 0;
+
+       if (gnutls_x509_crt_init(&cert) < 0)
+               return 0;
+
+       cert_list_size = 0;
+       cert_list = gnutls_certificate_get_peers(SSL_P(F), &cert_list_size);
+       if (cert_list == NULL)
+       {
+               gnutls_x509_crt_deinit(cert);
+               return 0;
+       }
+
+       if (gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
+       {
+               gnutls_x509_crt_deinit(cert);
+               return 0;
+       }
+
+       if (gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &digest_size) < 0)
+       {
+               gnutls_x509_crt_deinit(cert);
+               return 0;
+       }
+
+       memcpy(certfp, digest, RB_SSL_CERTFP_LEN);
+
+       gnutls_x509_crt_deinit(cert);
+       return 1;
+}
+
 int
 rb_supports_ssl(void)
 {
        return 1;
 }
 
+void
+rb_get_ssl_info(char *buf, size_t len)
+{
+       rb_snprintf(buf, len, "GNUTLS: compiled (%s), library(%s)", 
+                   LIBGNUTLS_VERSION, gnutls_check_version(NULL));
+}
+  
+        
 #endif /* HAVE_GNUTLS */