Author: rjung
Date: Sat Aug 19 20:10:13 2017
New Revision: 1805522

URL: http://svn.apache.org/viewvc?rev=1805522&view=rev
Log:
Add support for the OpenSSL SSL_CONF API.

Added:
    tomcat/native/trunk/native/src/sslconf.c   (with props)
Modified:
    tomcat/native/trunk/native/include/ssl_private.h
    tomcat/native/trunk/xdocs/miscellaneous/changelog.xml

Modified: tomcat/native/trunk/native/include/ssl_private.h
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/native/include/ssl_private.h?rev=1805522&r1=1805521&r2=1805522&view=diff
==============================================================================
--- tomcat/native/trunk/native/include/ssl_private.h (original)
+++ tomcat/native/trunk/native/include/ssl_private.h Sat Aug 19 20:10:13 2017
@@ -180,6 +180,11 @@
 #define HAVE_TLSV1_2
 #endif
 
+/* Check for SSL_CONF support */
+#if defined(SSL_CONF_FLAG_FILE)
+#define HAVE_SSL_CONF_CMD
+#endif
+
 /**
  * The following features all depend on TLS extension support.
  * Within this block, check again for features (not version numbers).
@@ -306,6 +311,14 @@ struct tcn_ssl_ctxt_t {
     /* End add from netty-tcnative */
 };
 
+#ifdef HAVE_SSL_CONF_CMD
+typedef struct tcn_ssl_conf_ctxt_t tcn_ssl_conf_ctxt_t;
+
+struct tcn_ssl_conf_ctxt_t {
+    apr_pool_t      *pool;
+    SSL_CONF_CTX    *cctx;
+};
+#endif
   
 typedef struct {
     apr_pool_t     *pool;

Added: tomcat/native/trunk/native/src/sslconf.c
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslconf.c?rev=1805522&view=auto
==============================================================================
--- tomcat/native/trunk/native/src/sslconf.c (added)
+++ tomcat/native/trunk/native/src/sslconf.c Sat Aug 19 20:10:13 2017
@@ -0,0 +1,413 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** SSL Context wrapper
+ */
+
+#include "tcn.h"
+
+#ifdef HAVE_OPENSSL
+
+#include "ssl_private.h"
+
+#ifdef HAVE_SSL_CONF_CMD
+
+#define SSL_THROW_RETURN -9
+
+#include "apr_file_io.h"
+
+/**
+ * Define the Path Checking modes
+ */
+#define PCM_EXISTS     0x1
+#define PCM_ISREG      0x2
+#define PCM_ISDIR      0x4
+#define PCM_ISNONZERO  0x8
+
+#define FLAGS_CHECK_FILE (PCM_EXISTS|PCM_ISREG|PCM_ISNONZERO)
+#define FLAGS_CHECK_DIR  (PCM_EXISTS|PCM_ISDIR)
+
+static int path_check(apr_pool_t *p, const char *path, int pcm)
+{
+    apr_finfo_t finfo;
+
+    if (path == NULL)
+        return 1;
+    if (pcm & PCM_EXISTS &&
+        apr_stat(&finfo, path, APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
+        return 1;
+    if (pcm & PCM_ISREG && finfo.filetype != APR_REG)
+        return 1;
+    if (pcm & PCM_ISDIR && finfo.filetype != APR_DIR)
+        return 1;
+    if (pcm & PCM_ISNONZERO && finfo.size <= 0)
+        return 1;
+    return 0;
+}
+
+
+static int check_dir(apr_pool_t *p, const char *dir)
+{
+    return path_check(p, dir, FLAGS_CHECK_DIR);
+}
+
+static int check_file(apr_pool_t *p, const char *file)
+{
+    return path_check(p, file, FLAGS_CHECK_FILE);
+}
+
+static apr_status_t ssl_ctx_config_cleanup(void *data)
+{
+    tcn_ssl_conf_ctxt_t *c = (tcn_ssl_conf_ctxt_t *)data;
+    if (c != NULL && c->cctx != NULL) {
+        SSL_CONF_CTX_free(c->cctx);
+        c->cctx = NULL;
+        c->pool = NULL;
+    }
+    return APR_SUCCESS;
+}
+
+/* Initialize an SSL_CONF context */
+TCN_IMPLEMENT_CALL(jlong, SSLConf, make)(TCN_STDARGS, jlong pool,
+                                         jint flags)
+{
+    apr_pool_t *p = J2P(pool, apr_pool_t *);
+    tcn_ssl_conf_ctxt_t *c = NULL;
+    SSL_CONF_CTX *cctx;
+    unsigned long ec;
+
+    UNREFERENCED(o);
+
+    SSL_ERR_clear();
+    cctx = SSL_CONF_CTX_new();
+    ec = SSL_ERR_get();
+    if (!cctx || ec != 0) {
+        if (ec != 0) {
+            char err[256];
+            ERR_error_string(ec, err);
+            tcn_Throw(e, "Could not create SSL_CONF context (%s)", err);
+        } else {
+            tcn_Throw(e, "Could not create SSL_CONF context");
+        }
+        return 0;
+    }
+
+    SSL_CONF_CTX_set_flags(cctx, flags);
+
+    if ((c = apr_pcalloc(p, sizeof(tcn_ssl_conf_ctxt_t))) == NULL) {
+        tcn_ThrowAPRException(e, apr_get_os_error());
+        return 0;
+    }
+
+    c->cctx = cctx;
+    c->pool = p;
+
+    /*
+     * Let us cleanup the SSL_CONF context when the pool is destroyed
+     */
+    apr_pool_cleanup_register(p, (const void *)c,
+                              ssl_ctx_config_cleanup,
+                              apr_pool_cleanup_null);
+
+    return P2J(c);
+}
+
+/* Destroy an SSL_CONF context */
+TCN_IMPLEMENT_CALL(void, SSLConf, free)(TCN_STDARGS, jlong cctx)
+{
+    tcn_ssl_conf_ctxt_t *c = J2P(cctx, tcn_ssl_conf_ctxt_t *);
+    UNREFERENCED_STDARGS;
+    TCN_ASSERT(c != 0);
+    if (c->cctx != NULL) {
+        SSL_CONF_CTX_free(c->cctx);
+        c->cctx = NULL;
+        c->pool = NULL;
+    }
+}
+
+/* Check a command for an SSL_CONF context */
+TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx,
+                                         jstring cmd, jstring value)
+{
+    tcn_ssl_conf_ctxt_t *c = J2P(cctx, tcn_ssl_conf_ctxt_t *);
+    int rc = 1;
+    unsigned long ec;
+    TCN_ALLOC_CSTRING(cmd);
+    TCN_ALLOC_CSTRING(value);
+    UNREFERENCED(o);
+    TCN_ASSERT(c != 0);
+    TCN_ASSERT(c->cctx != 0);
+    if (!J2S(cmd)) {
+        tcn_Throw(e, "Can not check null SSL_CONF command");
+        return SSL_THROW_RETURN;
+    }
+
+    SSL_ERR_clear();
+    int value_type = SSL_CONF_cmd_value_type(c->cctx, J2S(cmd));
+    ec = SSL_ERR_get();
+    if (ec != 0) {
+        char err[256];
+        ERR_error_string(ec, err);
+        tcn_Throw(e, "Could not determine SSL_CONF command type for '%s' 
(%s)", J2S(cmd), err);
+        return 0;
+    }
+
+    if (value_type == SSL_CONF_TYPE_UNKNOWN) {
+        tcn_Throw(e, "Invalid SSL_CONF command '%s', type unknown", J2S(cmd));
+        return SSL_THROW_RETURN;
+    }
+
+    if (value_type == SSL_CONF_TYPE_FILE) {
+        if (!J2S(value)) {
+            tcn_Throw(e, "SSL_CONF command '%s' needs a non-empty file 
argument", J2S(cmd));
+            return SSL_THROW_RETURN;
+        }
+        if (check_file(c->pool, J2S(value))) {
+            tcn_Throw(e, "SSL_CONF command '%s' file '%s' does not exist or is 
empty", J2S(cmd), J2S(value));
+            return SSL_THROW_RETURN;
+        }
+    }
+    else if (value_type == SSL_CONF_TYPE_DIR) {
+        if (!J2S(value)) {
+            tcn_Throw(e, "SSL_CONF command '%s' needs a non-empty directory 
argument", J2S(cmd));
+            return SSL_THROW_RETURN;
+        }
+        if (check_dir(c->pool, J2S(value))) {
+            tcn_Throw(e, "SSL_CONF command '%s' directory '%s' does not 
exist", J2S(cmd), J2S(value));
+            return SSL_THROW_RETURN;
+        }
+    }
+
+    TCN_FREE_CSTRING(cmd);
+    TCN_FREE_CSTRING(value);
+    return rc;
+}
+
+/* Assign an SSL_CTX to an SSL_CONF context */
+TCN_IMPLEMENT_CALL(void, SSLConf, assign)(TCN_STDARGS, jlong cctx,
+                                          jlong ctx)
+{
+    tcn_ssl_conf_ctxt_t *c = J2P(cctx, tcn_ssl_conf_ctxt_t *);
+    tcn_ssl_ctxt_t *sc = J2P(ctx, tcn_ssl_ctxt_t *);
+    UNREFERENCED_STDARGS;
+    TCN_ASSERT(c != 0);
+    TCN_ASSERT(c->cctx != 0);
+    TCN_ASSERT(sc != 0);
+    // sc->ctx == 0 is allowed!
+    SSL_CONF_CTX_set_ssl_ctx(c->cctx, sc->ctx);
+}
+
+/* Apply a command to an SSL_CONF context */
+TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx,
+                                         jstring cmd, jstring value)
+{
+    tcn_ssl_conf_ctxt_t *c = J2P(cctx, tcn_ssl_conf_ctxt_t *);
+    int rc;
+    unsigned long ec;
+#ifndef HAVE_EXPORT_CIPHERS
+    size_t len;
+    char *buf = NULL;
+#endif
+    TCN_ALLOC_CSTRING(cmd);
+    TCN_ALLOC_CSTRING(value);
+    UNREFERENCED(o);
+    TCN_ASSERT(c != 0);
+    TCN_ASSERT(c->cctx != 0);
+    if (!J2S(cmd)) {
+        tcn_Throw(e, "Can not apply null SSL_CONF command");
+        return SSL_THROW_RETURN;
+    }
+#ifndef HAVE_EXPORT_CIPHERS
+    if (!strcmp(J2S(cmd), "CipherString")) {
+        /*
+         *  Always disable NULL and export ciphers,
+         *  no matter what was given in the config.
+         */
+        len = strlen(J2S(value)) + strlen(SSL_CIPHERS_ALWAYS_DISABLED) + 1;
+        buf = malloc(len * sizeof(char *));
+        if (buf == NULL) {
+            tcn_Throw(e, "Could not allocate memory to adjust cipher string");
+            return SSL_THROW_RETURN;
+        }
+        memcpy(buf, SSL_CIPHERS_ALWAYS_DISABLED, 
strlen(SSL_CIPHERS_ALWAYS_DISABLED));
+        memcpy(buf + strlen(SSL_CIPHERS_ALWAYS_DISABLED), J2S(value), 
strlen(J2S(value)));
+        buf[len - 1] = '\0';
+    }
+#endif
+    SSL_ERR_clear();
+    rc = SSL_CONF_cmd(c->cctx, J2S(cmd), buf != NULL ? buf : J2S(value));
+    ec = SSL_ERR_get();
+    if (rc <= 0 || ec != 0) {
+        if (ec != 0) {
+            char err[256];
+            ERR_error_string(ec, err);
+            tcn_Throw(e, "Could not apply SSL_CONF command '%s' with value 
'%s' (%s)", J2S(cmd), buf != NULL ? buf : J2S(value), err);
+        } else {
+            tcn_Throw(e, "Could not apply SSL_CONF command '%s' with value 
'%s'", J2S(cmd), buf != NULL ? buf : J2S(value));
+        }
+        return SSL_THROW_RETURN;
+    }
+#ifndef HAVE_EXPORT_CIPHERS
+    if (buf != NULL) {
+        free(buf);
+    }
+#endif
+    TCN_FREE_CSTRING(cmd);
+    TCN_FREE_CSTRING(value);
+    return rc;
+}
+
+/* Finish an SSL_CONF context */
+TCN_IMPLEMENT_CALL(jint, SSLConf, finish)(TCN_STDARGS, jlong cctx)
+{
+    tcn_ssl_conf_ctxt_t *c = J2P(cctx, tcn_ssl_conf_ctxt_t *);
+    int rc;
+    unsigned long ec;
+
+    UNREFERENCED_STDARGS;
+    TCN_ASSERT(c != 0);
+    TCN_ASSERT(c->cctx != 0);
+    rc = SSL_CONF_CTX_finish(c->cctx);
+    ec = SSL_ERR_get();
+    if (rc <= 0 || ec != 0) {
+        if (ec != 0) {
+            char err[256];
+            ERR_error_string(ec, err);
+            tcn_Throw(e, "Could not finish SSL_CONF commands (%s)", err);
+        } else {
+            tcn_Throw(e, "Could not finish SSL_CONF commands");
+        }
+        return SSL_THROW_RETURN;
+    }
+    return rc;
+}
+
+
+#else /* HAVE_SSL_CONF_CMD */
+/* SSL_CONF is not supported.
+ * Create empty stubs.
+ */
+
+TCN_IMPLEMENT_CALL(jlong, SSLConf, make)(TCN_STDARGS, jlong pool,
+                                         jint flags)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(pool);
+    UNREFERENCED(flags);
+    return 0;
+}
+
+TCN_IMPLEMENT_CALL(void, SSLConf, free)(TCN_STDARGS, jlong cctx)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+}
+
+TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx,
+                                         jstring cmd, jstring value)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    UNREFERENCED(cmd);
+    UNREFERENCED(value);
+    return APR_ENOTIMPL;
+}
+
+TCN_IMPLEMENT_CALL(void, SSLConf, assign)(TCN_STDARGS, jlong cctx,
+                                          jlong ctx)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    UNREFERENCED(ctx);
+}
+
+TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx,
+                                         jstring cmd, jstring value)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    UNREFERENCED(cmd);
+    UNREFERENCED(value);
+    return APR_ENOTIMPL;
+}
+
+TCN_IMPLEMENT_CALL(jint, SSLConf, finish)(TCN_STDARGS, jlong cctx)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    return APR_ENOTIMPL;
+}
+
+
+#endif /* HAVE_SSL_CONF_CMD */
+
+#else /* HAVE_OPENSSL */
+/* OpenSSL is not supported.
+ * Create empty stubs.
+ */
+
+TCN_IMPLEMENT_CALL(jlong, SSLConf, make)(TCN_STDARGS, jlong pool,
+                                         jint flags)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(pool);
+    UNREFERENCED(flags);
+    return 0;
+}
+
+TCN_IMPLEMENT_CALL(void, SSLConf, free)(TCN_STDARGS, jlong cctx)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+}
+
+TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, jlong cctx,
+                                         jstring cmd, jstring value)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    UNREFERENCED(cmd);
+    UNREFERENCED(value);
+    return APR_ENOTIMPL;
+}
+
+TCN_IMPLEMENT_CALL(void, SSLConf, assign)(TCN_STDARGS, jlong cctx,
+                                          jlong ctx)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    UNREFERENCED(ctx);
+}
+
+TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, jlong cctx,
+                                         jstring cmd, jstring value)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    UNREFERENCED(cmd);
+    UNREFERENCED(value);
+    return APR_ENOTIMPL;
+}
+
+TCN_IMPLEMENT_CALL(jint, SSLConf, finish)(TCN_STDARGS, jlong cctx)
+{
+    UNREFERENCED_STDARGS;
+    UNREFERENCED(cctx);
+    return APR_ENOTIMPL;
+}
+
+
+#endif /* HAVE_OPENSSL */

Propchange: tomcat/native/trunk/native/src/sslconf.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/native/trunk/native/src/sslconf.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: tomcat/native/trunk/xdocs/miscellaneous/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/xdocs/miscellaneous/changelog.xml?rev=1805522&r1=1805521&r2=1805522&view=diff
==============================================================================
--- tomcat/native/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/native/trunk/xdocs/miscellaneous/changelog.xml Sat Aug 19 20:10:13 
2017
@@ -37,6 +37,9 @@
 <section name="Changes in 1.2.13">
   <changelog>
     <add>
+      Add support for the OpenSSL SSL_CONF API. (rjung)
+    </add>
+    <add>
       Add SSLContext.getCiphers(). (rjung)
     </add>
     <add>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to