+int
+rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN], int method)
+{
+ gnutls_x509_crt_t cert;
+ gnutls_digest_algorithm_t algo;
+ unsigned int cert_list_size;
+ const gnutls_datum_t *cert_list;
+ uint8_t digest[RB_SSL_CERTFP_LEN * 2];
+ size_t digest_size;
+ int len;
+
+ 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;
+ }
+
+ switch(method)
+ {
+ case RB_SSL_CERTFP_METH_SHA1:
+ algo = GNUTLS_DIG_SHA1;
+ len = RB_SSL_CERTFP_LEN_SHA1;
+ break;
+ case RB_SSL_CERTFP_METH_SHA256:
+ algo = GNUTLS_DIG_SHA256;
+ len = RB_SSL_CERTFP_LEN_SHA256;
+ break;
+ case RB_SSL_CERTFP_METH_SHA512:
+ algo = GNUTLS_DIG_SHA512;
+ len = RB_SSL_CERTFP_LEN_SHA512;
+ break;
+ default:
+ return 0;
+ }
+
+ if (gnutls_x509_crt_get_fingerprint(cert, algo, digest, &digest_size) < 0)
+ {
+ gnutls_x509_crt_deinit(cert);
+ return 0;
+ }
+
+ memcpy(certfp, digest, len);
+
+ gnutls_x509_crt_deinit(cert);
+ return len;
+}
+