summaryrefslogtreecommitdiff
path: root/imap
diff options
context:
space:
mode:
Diffstat (limited to 'imap')
-rw-r--r--imap/src/osdep/unix/ssl_unix.c83
1 files changed, 71 insertions, 12 deletions
diff --git a/imap/src/osdep/unix/ssl_unix.c b/imap/src/osdep/unix/ssl_unix.c
index 16b4228c..9498eb0e 100644
--- a/imap/src/osdep/unix/ssl_unix.c
+++ b/imap/src/osdep/unix/ssl_unix.c
@@ -33,6 +33,10 @@
#include <bio.h>
#include <crypto.h>
#include <rand.h>
+#ifdef OPENSSL_1_1_0
+#include <rsa.h>
+#include <bn.h>
+#endif /* OPENSSL_1_1_0 */
#undef STRING
#undef crypt
@@ -78,7 +82,14 @@ static long ssl_compare_hostnames (unsigned char *s,unsigned char *pat);
static char *ssl_getline_work (SSLSTREAM *stream,unsigned long *size,
long *contd);
static long ssl_abort (SSLSTREAM *stream);
-static RSA *ssl_genkey (SSL *con,int export,int keylength);
+
+#ifdef OPENSSL_1_1_0
+#define SSL_CTX_TYPE SSL_CTX
+#else
+#define SSL_CTX_TYPE SSL
+#endif /* OPENSSL_1_1_0 */
+
+static RSA *ssl_genkey (SSL_CTX_TYPE *con,int export,int keylength);
/* Secure Sockets Layer network driver dispatch */
@@ -128,7 +139,11 @@ void ssl_onceonlyinit (void)
/* apply runtime linkage */
mail_parameters (NIL,SET_SSLDRIVER,(void *) &ssldriver);
mail_parameters (NIL,SET_SSLSTART,(void *) ssl_start);
+#ifdef OPENSSL_1_1_0
+ OPENSSL_init_ssl(0, NULL);
+#else
SSL_library_init (); /* add all algorithms */
+#endif /* OPENSSL_1_1_0 */
}
}
@@ -163,16 +178,26 @@ SSLSTREAM *ssl_aopen (NETMBX *mb,char *service,char *usrbuf)
*/
const SSL_METHOD *ssl_connect_mthd(int flag)
{
+#ifdef OPENSSL_1_1_0
if(flag & NET_TRYTLS1)
- return TLSv1_client_method();
+ return TLS_client_method();
+#else
+ if(flag & NET_TRYTLS1)
+ return TLSv1_client_method();
+#endif /* OPENSSL_1_1_0 */
#ifdef TLSV1_2
else if(flag & NET_TRYTLS1_1)
return TLSv1_1_client_method();
else if(flag & NET_TRYTLS1_2)
return TLSv1_2_client_method();
-#endif
+#endif /* TLSV1_2 */
+#ifdef OPENSSL_1_1_0
+ else if(flag & NET_TRYDTLS1)
+ return DTLS_client_method();
+#else
else if(flag & NET_TRYDTLS1)
return DTLSv1_client_method();
+#endif /* OPENSSL_1_1_0 */
else return SSLv23_client_method();
}
@@ -242,7 +267,7 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags)
BIO *bio;
X509 *cert;
unsigned long sl,tl;
- char *s,*t,*err,tmp[MAILTMPLEN];
+ char *s,*t,*err,tmp[MAILTMPLEN], buf[256];
sslcertificatequery_t scq =
(sslcertificatequery_t) mail_parameters (NIL,GET_SSLCERTIFICATEQUERY,NIL);
sslclientcert_t scc =
@@ -300,9 +325,10 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags)
(err = ssl_validate_cert (cert = SSL_get_peer_certificate (stream->con),
host))) {
/* application callback */
- if (scq) return (*scq) (err,host,cert ? cert->name : "???") ? NIL : "";
+ X509_NAME_oneline (X509_get_subject_name(cert), buf, sizeof(buf));
+ if (scq) return (*scq) (err,host,cert ? buf : "???") ? NIL : "";
/* error message to return via mm_log() */
- sprintf (tmp,"*%.128s: %.255s",err,cert ? cert->name : "???");
+ sprintf (tmp,"*%.128s: %.255s",err,cert ? buf : "???");
return ssl_last_error = cpystr (tmp);
}
return NIL;
@@ -346,20 +372,28 @@ static int ssl_open_verify (int ok,X509_STORE_CTX *ctx)
static char *ssl_validate_cert (X509 *cert,char *host)
{
int i,n;
- char *s,*t,*ret;
+ char *s=NULL,*t,*ret;
void *ext;
GENERAL_NAME *name;
+ X509_NAME *cname;
+ X509_NAME_ENTRY *e;
+ char buf[256];
/* make sure have a certificate */
if (!cert) ret = "No certificate from server";
/* and that it has a name */
- else if (!cert->name) ret = "No name in certificate";
+ else if (!(cname = X509_get_subject_name(cert))) ret = "No name in certificate";
/* locate CN */
- else if ((s = strstr (cert->name,"/CN=")) != NULL) {
- if ((t = strchr (s += 4,'/')) != NULL) *t = '\0';
+ else{
+ if((e = X509_NAME_get_entry(cname, X509_NAME_entry_count(cname)-1)) != NULL){
+ X509_NAME_get_text_by_OBJ(cname, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf));
+ s = (char *) buf;
+ }
+ else s = NULL;
+ }
+ if (s != NULL) {
/* host name matches pattern? */
ret = ssl_compare_hostnames (host,s) ? NIL :
"Server name does not match certificate";
- if (t) *t = '/'; /* restore smashed delimiter */
/* if mismatch, see if in extensions */
if (ret && (ext = X509_get_ext_d2i (cert,NID_subject_alt_name,NIL,NIL)) &&
(n = sk_GENERAL_NAME_num (ext)))
@@ -719,8 +753,13 @@ void ssl_server_init (char *server)
SSLSTREAM *stream = (SSLSTREAM *) memset (fs_get (sizeof (SSLSTREAM)),0,
sizeof (SSLSTREAM));
ssl_onceonlyinit (); /* make sure algorithms added */
+#ifdef OPENSSL_1_1_0
+ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS|OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+#else
ERR_load_crypto_strings ();
SSL_load_error_strings ();
+#endif /* OPENSSL_1_1_0 */
/* build specific certificate/key file names */
sprintf (cert,"%s/%s-%s.pem",SSL_CERT_DIRECTORY,server,tcp_serveraddr ());
sprintf (key,"%s/%s-%s.pem",SSL_KEY_DIRECTORY,server,tcp_serveraddr ());
@@ -732,9 +771,15 @@ void ssl_server_init (char *server)
if (stat (key,&sbuf)) strcpy (key,cert);
}
/* create context */
+#ifdef OPENSSL_1_1_0
+ if (!(stream->context = SSL_CTX_new (start_tls ?
+ TLS_server_method () :
+ SSLv23_server_method ())))
+#else
if (!(stream->context = SSL_CTX_new (start_tls ?
TLSv1_server_method () :
SSLv23_server_method ())))
+#endif /* OPENSSL_1_1_0 */
syslog (LOG_ALERT,"Unable to create SSL context, host=%.80s",
tcp_clienthost ());
else { /* set context options */
@@ -754,8 +799,13 @@ void ssl_server_init (char *server)
key,tcp_clienthost ());
else { /* generate key if needed */
+#ifdef OPENSSL_1_1_0
+ if (0)
+ ssl_genkey(stream->context, 0, 0);
+#else
if (SSL_CTX_need_tmp_RSA (stream->context))
SSL_CTX_set_tmp_rsa_callback (stream->context,ssl_genkey);
+#endif /* OPENSSL_1_1_0 */
/* create new SSL connection */
if (!(stream->con = SSL_new (stream->context)))
syslog (LOG_ALERT,"Unable to create SSL connection, host=%.80s",
@@ -798,19 +848,28 @@ void ssl_server_init (char *server)
* Returns: generated key, always
*/
-static RSA *ssl_genkey (SSL *con,int export,int keylength)
+static RSA *ssl_genkey (SSL_CTX_TYPE *con,int export,int keylength)
{
unsigned long i;
static RSA *key = NIL;
if (!key) { /* if don't have a key already */
/* generate key */
+#ifdef OPENSSL_1_1_0
+ BIGNUM *e = BN_new();
+ if (!RSA_generate_key_ex (key, export ? keylength : 1024, e,NIL)) {
+#else
if (!(key = RSA_generate_key (export ? keylength : 1024,RSA_F4,NIL,NIL))) {
+#endif /* OPENSSL_1_1_0 */
syslog (LOG_ALERT,"Unable to generate temp key, host=%.80s",
tcp_clienthost ());
while ((i = ERR_get_error ()) != 0L)
syslog (LOG_ALERT,"SSL error status: %s",ERR_error_string (i,NIL));
exit (1);
}
+#ifdef OPENSSL_1_1_0
+ BN_free(e);
+ e = NULL;
+#endif /* OPENSSL_1_1_0 */
}
return key;
}