Browse Source

add support for ssl server certificate fingerprint checking

based on a patch by Ben Kibbey, sourceforge tracker item 3073733.
wip/ssl-fprint
Oswald Buddenhagen 14 years ago
parent
commit
3d9c2ff62b
  1. 43
      src/drv_imap.c
  2. 6
      src/mbsync.1

43
src/drv_imap.c

@ -59,6 +59,7 @@ typedef struct imap_server_conf {
char *user; char *user;
char *pass; char *pass;
#if HAVE_LIBSSL #if HAVE_LIBSSL
char *fingerprint;
char *cert_file; char *cert_file;
unsigned use_imaps:1; unsigned use_imaps:1;
unsigned require_ssl:1; unsigned require_ssl:1;
@ -189,8 +190,10 @@ static const char *Flags[] = {
/* this gets called when a certificate is to be verified */ /* this gets called when a certificate is to be verified */
static int static int
verify_cert( SSL *ssl ) verify_cert( imap_store_t *ctx )
{ {
SSL *ssl = ctx->imap->buf.sock.ssl;
imap_store_conf_t *conf = (imap_store_conf_t *)ctx->gen.conf;
X509 *cert; X509 *cert;
int err; int err;
char buf[256]; char buf[256];
@ -204,8 +207,40 @@ verify_cert( SSL *ssl )
} }
err = SSL_get_verify_result( ssl ); err = SSL_get_verify_result( ssl );
if (err == X509_V_OK) if (err == X509_V_OK) {
if (conf->server->fingerprint) {
const EVP_MD *digest_tp;
unsigned dsz, dp;
unsigned char digest[EVP_MAX_MD_SIZE];
char text[EVP_MAX_MD_SIZE * 3], *tp;
if (!(digest_tp = EVP_md5())) {
fprintf( stderr, "Error, EVP_md5() failed\n" );
return 1;
}
if (!X509_digest( cert, digest_tp, digest, &dsz )) {
fprintf( stderr, "Out of memory\n" );
return 1;
}
tp = text;
for (dp = 0; dp < dsz; dp++) {
if (dp)
*tp++ = ':';
sprintf(tp, "%02X", digest[dp]);
tp += 2;
}
*tp = 0;
if (strcasecmp( text, conf->server->fingerprint )) {
fprintf( stderr, "Error, certificate fingerprint mismatch\n" );
return 1;
} else {
info( "Certificate fingerprint ok\n" );
}
}
return 0; return 0;
}
fprintf( stderr, "Error, can't verify certificate: %s (%d)\n", fprintf( stderr, "Error, can't verify certificate: %s (%d)\n",
X509_verify_cert_error_string(err), err ); X509_verify_cert_error_string(err), err );
@ -1103,7 +1138,7 @@ start_tls( imap_store_t *ctx )
} }
/* verify the server certificate */ /* verify the server certificate */
if (verify_cert( imap->buf.sock.ssl )) if (verify_cert( ctx ))
return 1; return 1;
imap->buf.sock.use_ssl = 1; imap->buf.sock.use_ssl = 1;
@ -1776,6 +1811,8 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep, int *err )
server->use_tlsv1 = parse_bool( cfg ); server->use_tlsv1 = parse_bool( cfg );
else if (!strcasecmp( "RequireCRAM", cfg->cmd )) else if (!strcasecmp( "RequireCRAM", cfg->cmd ))
server->require_cram = parse_bool( cfg ); server->require_cram = parse_bool( cfg );
else if (!strcasecmp( "Fingerprint", cfg->cmd ))
server->fingerprint = nfstrdup( cfg->val );
#endif #endif
else if (!strcasecmp( "Tunnel", cfg->cmd )) else if (!strcasecmp( "Tunnel", cfg->cmd ))
server->tunnel = nfstrdup( cfg->val ); server->tunnel = nfstrdup( cfg->val );

6
src/mbsync.1

@ -260,6 +260,12 @@ File containing X.509 CA certificates used to verify server identities.
This option is \fImandatory\fR if SSL is used. See \fBSSL CERTIFICATES\fR below. This option is \fImandatory\fR if SSL is used. See \fBSSL CERTIFICATES\fR below.
.. ..
.TP .TP
\fBFingerprint\fR \fIstring\fR
A colon separated, hex encoded MD5 fingerprint
(as printed by \fBopenssl dgst -c\fR \fIfile\fR)
to check the server certificate against.
..
.TP
\fBUseSSLv2\fR \fIyes\fR|\fIno\fR \fBUseSSLv2\fR \fIyes\fR|\fIno\fR
Use SSLv2 for communication with the IMAP server over SSL? Use SSLv2 for communication with the IMAP server over SSL?
.br .br

Loading…
Cancel
Save