+
+
+/*****************************************************
+* Certificate operator routines
+*****************************************************/
+uschar *
+tls_cert_der_b64(void * cert)
+{
+BIO * bp = BIO_new(BIO_s_mem());
+uschar * cp = NULL;
+
+if (!i2d_X509_bio(bp, (X509 *)cert))
+ log_write(0, LOG_MAIN, "TLS error in certificate export: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+else
+ {
+ long len = BIO_get_mem_data(bp, &cp);
+ cp = b64encode(cp, (int)len);
+ }
+
+BIO_free(bp);
+return cp;
+}
+
+
+static uschar *
+fingerprint(X509 * cert, const EVP_MD * fdig)
+{
+int j;
+unsigned int n;
+uschar md[EVP_MAX_MD_SIZE];
+uschar * cp;
+
+if (!X509_digest(cert,fdig,md,&n))
+ {
+ expand_string_message = US"tls_cert_fprt: out of mem\n";
+ return NULL;
+ }
+cp = store_get(n*2+1);
+for (j = 0; j < (int)n; j++) sprintf(CS cp+2*j, "%02X", md[j]);
+return(cp);
+}
+
+uschar *
+tls_cert_fprt_md5(void * cert)
+{
+return fingerprint((X509 *)cert, EVP_md5());
+}
+
+uschar *
+tls_cert_fprt_sha1(void * cert)
+{
+return fingerprint((X509 *)cert, EVP_sha1());
+}
+
+uschar *
+tls_cert_fprt_sha256(void * cert)
+{
+return fingerprint((X509 *)cert, EVP_sha256());
+}
+
+