Unify the SSL privsep key loading functions.
authorreyk <reyk@openbsd.org>
Tue, 20 May 2014 17:33:36 +0000 (17:33 +0000)
committerreyk <reyk@openbsd.org>
Tue, 20 May 2014 17:33:36 +0000 (17:33 +0000)
ok eric@

usr.sbin/relayd/relay.c
usr.sbin/relayd/relayd.h
usr.sbin/relayd/ssl.c
usr.sbin/smtpd/ssl.c
usr.sbin/smtpd/ssl.h

index d6d4cf6..02d52ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: relay.c,v 1.169 2014/04/22 08:04:23 reyk Exp $        */
+/*     $OpenBSD: relay.c,v 1.170 2014/05/20 17:33:36 reyk Exp $        */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -1914,7 +1914,7 @@ relay_ssl_ctx_create(struct relay *rlay)
 
        log_debug("%s: loading private key", __func__);
        if (!ssl_ctx_fake_private_key(ctx,
-           &rlay->rl_conf.ssl_keyid,
+           &rlay->rl_conf.ssl_keyid, sizeof(rlay->rl_conf.ssl_keyid),
            rlay->rl_ssl_cert, rlay->rl_conf.ssl_cert_len,
            &rlay->rl_ssl_x509, &rlay->rl_ssl_pkey))
                goto err;
@@ -1924,9 +1924,9 @@ relay_ssl_ctx_create(struct relay *rlay)
 
        if (rlay->rl_conf.ssl_cacert_len) {
                log_debug("%s: loading CA private key", __func__);
-               if (!ssl_ctx_load_pkey(ctx,
-                   &rlay->rl_conf.ssl_cakeyid, rlay->rl_ssl_cacert,
-                   rlay->rl_conf.ssl_cacert_len,
+               if (!ssl_load_pkey(&rlay->rl_conf.ssl_cakeyid,
+                   sizeof(rlay->rl_conf.ssl_cakeyid),
+                   rlay->rl_ssl_cacert, rlay->rl_conf.ssl_cacert_len,
                    &rlay->rl_ssl_cacertx509, &rlay->rl_ssl_capkey))
                        goto err;
        }
index d5adaac..9e95790 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: relayd.h,v 1.179 2014/05/08 13:08:48 blambert Exp $   */
+/*     $OpenBSD: relayd.h,v 1.180 2014/05/20 17:33:36 reyk Exp $       */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -1111,10 +1111,10 @@ SSL_CTX *ssl_ctx_create(struct relayd *);
 void    ssl_error(const char *, const char *);
 char   *ssl_load_key(struct relayd *, const char *, off_t *, char *);
 X509   *ssl_update_certificate(X509 *, EVP_PKEY *, EVP_PKEY *, X509 *);
-int     ssl_ctx_load_pkey(SSL_CTX *, void *, char *, off_t,
-           X509 **, EVP_PKEY **);
-int     ssl_ctx_fake_private_key(SSL_CTX *, void *, char *, off_t,
+int     ssl_load_pkey(const void *, size_t, char *, off_t,
            X509 **, EVP_PKEY **);
+int     ssl_ctx_fake_private_key(SSL_CTX *, const void *, size_t,
+           char *, off_t, X509 **, EVP_PKEY **);
 
 /* ssl_privsep.c */
 int     ssl_ctx_use_certificate_chain(SSL_CTX *, char *, off_t);
index 9f09d6b..4544d53 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssl.c,v 1.23 2014/05/06 11:03:02 reyk Exp $   */
+/*     $OpenBSD: ssl.c,v 1.24 2014/05/20 17:33:36 reyk Exp $   */
 
 /*
  * Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -405,14 +405,14 @@ ssl_update_certificate(X509 *oldcert, EVP_PKEY *pkey, EVP_PKEY *capkey,
 }
 
 int
-ssl_ctx_load_pkey(SSL_CTX *ctx, void *data, char *buf, off_t len,
+ssl_load_pkey(const void *data, size_t datalen, char *buf, off_t len,
     X509 **x509ptr, EVP_PKEY **pkeyptr)
 {
-       int              ret = 0;
        BIO             *in;
        X509            *x509 = NULL;
        EVP_PKEY        *pkey = NULL;
        RSA             *rsa = NULL;
+       void            *exdata = NULL;
 
        if ((in = BIO_new_mem_buf(buf, len)) == NULL) {
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_BUF_LIB);
@@ -430,42 +430,48 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, void *data, char *buf, off_t len,
                goto fail;
        }
 
-       if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) {
-               SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB);
-               goto fail;
-       }
+       BIO_free(in);
 
-       RSA_set_ex_data(rsa, 0, data);
-       RSA_free(rsa); /* dereference, will be cleaned up with pkey */
+       if (data != NULL && datalen) {
+               if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL ||
+                   (exdata = malloc(datalen)) == NULL) {
+                       SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB);
+                       goto fail;
+               }
+
+               memcpy(exdata, data, datalen);
+               RSA_set_ex_data(rsa, 0, exdata);
+               RSA_free(rsa); /* dereference, will be cleaned up with pkey */
+       }
 
        *x509ptr = x509;
        *pkeyptr = pkey;
-       ret = 1;
 
-       goto done;
+       return (1);
 
  fail:
+       if (rsa != NULL)
+               RSA_free(rsa);
+       if (in != NULL)
+               BIO_free(in);
        if (pkey != NULL)
                EVP_PKEY_free(pkey);
        if (x509 != NULL)
                X509_free(x509);
 
- done:
-       if (in != NULL)
-               BIO_free(in);
-
-       return ret;
+       return (0);
 }
 
 int
-ssl_ctx_fake_private_key(SSL_CTX *ctx, void *data, char *buf, off_t len,
-    X509 **x509ptr, EVP_PKEY **pkeyptr)
+ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen,
+    char *buf, off_t len, X509 **x509ptr, EVP_PKEY **pkeyptr)
 {
-       int      ret;
+       int              ret = 0;
+       EVP_PKEY        *pkey = NULL;
+       X509            *x509 = NULL;
 
-       if (!(ret = ssl_ctx_load_pkey(ctx, data, buf, len,
-           x509ptr, pkeyptr)))
-               goto fail;
+       if (!ssl_load_pkey(data, datalen, buf, len, &x509, &pkey))
+               return (0);
 
        /*
         * Use the public key as the "private" key - the secret key
@@ -473,20 +479,20 @@ ssl_ctx_fake_private_key(SSL_CTX *ctx, void *data, char *buf, off_t len,
         * contacted by the RSA engine.  The SSL/TLS library needs at
         * least the public key parameters in the current process.
         */
-       if (!SSL_CTX_use_PrivateKey(ctx, *pkeyptr)) {
+       ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+       if (!ret)
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SSL_LIB);
-               goto fail;
-       }
 
-       return (1);
+       if (pkeyptr != NULL)
+               *pkeyptr = pkey;
+       else if (pkey != NULL)
+               EVP_PKEY_free(pkey);
 
- fail:
-       if (*pkeyptr != NULL)
-               EVP_PKEY_free(*pkeyptr);
-       if (*x509ptr != NULL)
-               X509_free(*x509ptr);
-       *x509ptr = NULL;
-       *pkeyptr = NULL;
+       if (x509ptr != NULL)
+               *x509ptr = x509;
+       else if (x509 != NULL)
+               X509_free(x509);
 
-       return (0);
+       return (ret);
 }
+
index 6ea7c6b..d402992 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssl.c,v 1.66 2014/05/20 14:21:45 reyk Exp $   */
+/*     $OpenBSD: ssl.c,v 1.67 2014/05/20 17:33:36 reyk Exp $   */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -153,7 +153,7 @@ ssl_password_cb(char *buf, int size, int rwflag, void *u)
 #endif
 
 static int
-ssl_getpass_cb(char *buf, int size, int rwflag, void *u)
+ssl_password_cb(char *buf, int size, int rwflag, void *u)
 {
        int     ret = 0;
        size_t  len;
@@ -209,7 +209,7 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char *
        }
 
        (void)snprintf(prompt, sizeof prompt, "passphrase for %s: ", pkiname);
-       key = PEM_read_PrivateKey(fp, NULL, ssl_getpass_cb, prompt);
+       key = PEM_read_PrivateKey(fp, NULL, ssl_password_cb, prompt);
        fclose(fp);
        fp = NULL;
        if (key == NULL)
@@ -276,7 +276,7 @@ ssl_ctx_create(const char *pkiname, char *cert, off_t cert_len)
                        ssl_error("ssl_ctx_create");
                        fatal("ssl_ctx_create: invalid certificate chain");
                } else if (!ssl_ctx_fake_private_key(ctx,
-                   pkiname, pkinamelen, cert, cert_len)) {
+                   pkiname, pkinamelen, cert, cert_len, NULL, NULL)) {
                        ssl_error("ssl_ctx_create");
                        fatal("ssl_ctx_create: could not fake private key");
                } else if (!SSL_CTX_check_private_key(ctx)) {
@@ -462,12 +462,14 @@ ssl_set_ecdh_curve(SSL_CTX *ctx, const char *curve)
 }
 
 int
-ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len,
+ssl_load_pkey(const void *data, size_t datalen, char *buf, off_t len,
     X509 **x509ptr, EVP_PKEY **pkeyptr)
 {
        BIO             *in;
        X509            *x509 = NULL;
        EVP_PKEY        *pkey = NULL;
+       RSA             *rsa = NULL;
+       void            *exdata = NULL;
 
        if ((in = BIO_new_mem_buf(buf, len)) == NULL) {
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_BUF_LIB);
@@ -475,7 +477,7 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len,
        }
 
        if ((x509 = PEM_read_bio_X509(in, NULL,
-           ssl_getpass_cb, NULL)) == NULL) {
+           ssl_password_cb, NULL)) == NULL) {
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PEM_LIB);
                goto fail;
        }
@@ -487,14 +489,26 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len,
 
        BIO_free(in);
 
+       if (data != NULL && datalen) {
+               if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL ||
+                   (exdata = malloc(datalen)) == NULL) {
+                       SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB);
+                       goto fail;
+               }
+
+               memcpy(exdata, data, datalen);
+               RSA_set_ex_data(rsa, 0, exdata);
+               RSA_free(rsa); /* dereference, will be cleaned up with pkey */
+       }
+
        *x509ptr = x509;
        *pkeyptr = pkey;
 
        return (1);
 
  fail:
-       ssl_error("ssl_ctx_load_pkey");
-
+       if (rsa != NULL)
+               RSA_free(rsa);
        if (in != NULL)
                BIO_free(in);
        if (pkey != NULL)
@@ -507,28 +521,15 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len,
 
 int
 ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen,
-    char *buf, off_t len)
+    char *buf, off_t len, X509 **x509ptr, EVP_PKEY **pkeyptr)
 {
        int              ret = 0;
        EVP_PKEY        *pkey = NULL;
        X509            *x509 = NULL;
-       RSA             *rsa = NULL;
-       void            *exdata = NULL;
 
-       if (!ssl_ctx_load_pkey(ctx, buf, len, &x509, &pkey))
+       if (!ssl_load_pkey(data, datalen, buf, len, &x509, &pkey))
                return (0);
 
-       if (data != NULL && datalen) {
-               if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL ||
-                   (exdata = malloc(datalen)) == NULL) {
-                       SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB);
-                       goto done;
-               }
-
-               memcpy(exdata, data, datalen);
-               RSA_set_ex_data(rsa, 0, exdata);
-       }
-
        /*
         * Use the public key as the "private" key - the secret key
         * parameters are hidden in an extra process that will be
@@ -536,17 +537,17 @@ ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen,
         * least the public key parameters in the current process.
         */
        ret = SSL_CTX_use_PrivateKey(ctx, pkey);
-       if (!ret) {
+       if (!ret)
                SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SSL_LIB);
-               ssl_error("ssl_ctx_fake_private_key");
-       }
 
- done:
-       if (rsa != NULL)
-               RSA_free(rsa);
-       if (pkey != NULL)
+       if (pkeyptr != NULL)
+               *pkeyptr = pkey;
+       else if (pkey != NULL)
                EVP_PKEY_free(pkey);
-       if (x509 != NULL)
+
+       if (x509ptr != NULL)
+               *x509ptr = x509;
+       else if (x509 != NULL)
                X509_free(x509);
 
        return (ret);
index 923746e..414e120 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssl.h,v 1.8 2014/05/20 14:21:46 reyk Exp $    */
+/*     $OpenBSD: ssl.h,v 1.9 2014/05/20 17:33:36 reyk Exp $    */
 /*
  * Copyright (c) 2013 Gilles Chehade <gilles@poolp.org>
  *
@@ -61,11 +61,10 @@ int         ssl_load_certificate(struct pki *, const char *);
 int            ssl_load_keyfile(struct pki *, const char *, const char *);
 int            ssl_load_cafile(struct pki *, const char *);
 int            ssl_load_dhparams(struct pki *, const char *);
-
-int            ssl_ctx_load_pkey(SSL_CTX *, char *, off_t,
+int            ssl_load_pkey(const void *, size_t, char *, off_t,
                    X509 **, EVP_PKEY **);
 int            ssl_ctx_fake_private_key(SSL_CTX *, const void *, size_t,
-                   char *, off_t);
+                   char *, off_t, X509 **, EVP_PKEY **);
 
 /* ssl_privsep.c */
 int            ssl_ctx_use_certificate_chain(SSL_CTX *, char *, off_t);