ASF Bugzilla – Attachment 35725 Details for
Bug 62094
Certificate verification using CRL with Tomcat APR connector does not work
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
The source code with the proposed fix.
sslcontext.c (text/plain), 67.12 KB, created by
twsatwork
on 2018-02-09 19:43:29 UTC
(
hide
)
Description:
The source code with the proposed fix.
Filename:
MIME Type:
Creator:
twsatwork
Created:
2018-02-09 19:43:29 UTC
Size:
67.12 KB
patch
obsolete
>/* 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" > >#include "apr_file_io.h" >#include "apr_thread_mutex.h" >#include "apr_poll.h" > >#ifdef HAVE_OPENSSL >#include "ssl_private.h" > >static jclass byteArrayClass; > >static apr_status_t ssl_context_cleanup(void *data) >{ > tcn_ssl_ctxt_t *c = (tcn_ssl_ctxt_t *)data; > if (c) { > int i; > if (c->crl) > X509_STORE_free(c->crl); > c->crl = NULL; > if (c->ctx) > SSL_CTX_free(c->ctx); > c->ctx = NULL; > for (i = 0; i < SSL_AIDX_MAX; i++) { > if (c->certs[i]) { > X509_free(c->certs[i]); > c->certs[i] = NULL; > } > if (c->keys[i]) { > EVP_PKEY_free(c->keys[i]); > c->keys[i] = NULL; > } > } > if (c->bio_is) { > SSL_BIO_close(c->bio_is); > c->bio_is = NULL; > } > if (c->bio_os) { > SSL_BIO_close(c->bio_os); > c->bio_os = NULL; > } > > if (c->verifier) { > JNIEnv *e; > tcn_get_java_env(&e); > (*e)->DeleteGlobalRef(e, c->verifier); > c->verifier = NULL; > } > c->verifier_method = NULL; > > if (c->next_proto_data) { > free(c->next_proto_data); > c->next_proto_data = NULL; > } > c->next_proto_len = 0; > > if (c->alpn_proto_data) { > free(c->alpn_proto_data); > c->alpn_proto_data = NULL; > } > c->alpn_proto_len = 0; > } > return APR_SUCCESS; >} > >static jclass ssl_context_class; >static jmethodID sni_java_callback; > >/* Callback used when OpenSSL receives a client hello with a Server Name > * Indication extension. > */ >int ssl_callback_ServerNameIndication(SSL *ssl, int *al, tcn_ssl_ctxt_t *c) >{ > /* TODO: Is it better to cache the JNIEnv* during the call to handshake? */ > > /* Get the JNI environment for this callback */ > JavaVM *javavm = tcn_get_java_vm(); > JNIEnv *env; > const char *servername; > jstring hostname; > jlong original_ssl_context, new_ssl_context; > tcn_ssl_ctxt_t *new_c; > > // Continue only if the static method exists > if (sni_java_callback == NULL) { > return SSL_TLSEXT_ERR_OK; > } > > (*javavm)->AttachCurrentThread(javavm, (void **)&env, NULL); > > // Get the host name presented by the client > servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); > > // Convert to Java compatible parameters ready for the method call > hostname = (*env)->NewStringUTF(env, servername); > original_ssl_context = P2J(c); > > new_ssl_context = (*env)->CallStaticLongMethod(env, > ssl_context_class, > sni_java_callback, > original_ssl_context, > hostname); > > // Delete the local reference as this method is called via callback. > // Otherwise local references are only freed once jni method returns. > (*env)->DeleteLocalRef(env, hostname); > > if (new_ssl_context != 0 && new_ssl_context != original_ssl_context) { > new_c = J2P(new_ssl_context, tcn_ssl_ctxt_t *); > SSL_set_SSL_CTX(ssl, new_c->ctx); > } > > return SSL_TLSEXT_ERR_OK; >} > >/* Initialize server context */ >TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jlong pool, > jint protocol, jint mode) >{ > apr_pool_t *p = J2P(pool, apr_pool_t *); > tcn_ssl_ctxt_t *c = NULL; > SSL_CTX *ctx = NULL; > jclass clazz; >#if OPENSSL_VERSION_NUMBER >= 0x10100000L > jint prot; >#endif > > UNREFERENCED(o); > if (protocol == SSL_PROTOCOL_NONE) { > tcn_Throw(e, "No SSL protocols requested"); > goto init_failed; > } > >#if OPENSSL_VERSION_NUMBER < 0x10100000L > if (protocol == SSL_PROTOCOL_TLSV1_2) { >#ifdef HAVE_TLSV1_2 > if (mode == SSL_MODE_CLIENT) > ctx = SSL_CTX_new(TLSv1_2_client_method()); > else if (mode == SSL_MODE_SERVER) > ctx = SSL_CTX_new(TLSv1_2_server_method()); > else > ctx = SSL_CTX_new(TLSv1_2_method()); >#endif > } else if (protocol == SSL_PROTOCOL_TLSV1_1) { >#ifdef HAVE_TLSV1_1 > if (mode == SSL_MODE_CLIENT) > ctx = SSL_CTX_new(TLSv1_1_client_method()); > else if (mode == SSL_MODE_SERVER) > ctx = SSL_CTX_new(TLSv1_1_server_method()); > else > ctx = SSL_CTX_new(TLSv1_1_method()); >#endif > } else if (protocol == SSL_PROTOCOL_TLSV1) { > if (mode == SSL_MODE_CLIENT) > ctx = SSL_CTX_new(TLSv1_client_method()); > else if (mode == SSL_MODE_SERVER) > ctx = SSL_CTX_new(TLSv1_server_method()); > else > ctx = SSL_CTX_new(TLSv1_method()); > } else if (protocol == SSL_PROTOCOL_SSLV3) { > if (mode == SSL_MODE_CLIENT) > ctx = SSL_CTX_new(SSLv3_client_method()); > else if (mode == SSL_MODE_SERVER) > ctx = SSL_CTX_new(SSLv3_server_method()); > else > ctx = SSL_CTX_new(SSLv3_method()); > } else if (protocol == SSL_PROTOCOL_SSLV2) { > /* requested but not supported */ >#ifndef HAVE_TLSV1_2 > } else if (protocol & SSL_PROTOCOL_TLSV1_2) { > /* requested but not supported */ >#endif >#ifndef HAVE_TLSV1_1 > } else if (protocol & SSL_PROTOCOL_TLSV1_1) { > /* requested but not supported */ >#endif > } else { >#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */ > if (mode == SSL_MODE_CLIENT) > ctx = SSL_CTX_new(TLS_client_method()); > else if (mode == SSL_MODE_SERVER) > ctx = SSL_CTX_new(TLS_server_method()); > else > ctx = SSL_CTX_new(TLS_method()); >#if OPENSSL_VERSION_NUMBER < 0x10100000L > } >#endif > > if (!ctx) { > char err[256]; > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Invalid Server SSL Protocol (%s)", err); > goto init_failed; > } > if ((c = apr_pcalloc(p, sizeof(tcn_ssl_ctxt_t))) == NULL) { > tcn_ThrowAPRException(e, apr_get_os_error()); > goto init_failed; > } > > c->protocol = protocol; > c->mode = mode; > c->ctx = ctx; > c->pool = p; > c->bio_os = BIO_new(BIO_s_file()); > if (c->bio_os != NULL) > BIO_set_fp(c->bio_os, stderr, BIO_NOCLOSE | BIO_FP_TEXT); > SSL_CTX_set_options(c->ctx, SSL_OP_ALL); > >#if OPENSSL_VERSION_NUMBER < 0x10100000L > /* always disable SSLv2, as per RFC 6176 */ > SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); > if (!(protocol & SSL_PROTOCOL_SSLV3)) > SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv3); > if (!(protocol & SSL_PROTOCOL_TLSV1)) > SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1); >#ifdef HAVE_TLSV1_1 > if (!(protocol & SSL_PROTOCOL_TLSV1_1)) > SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1_1); >#endif >#ifdef HAVE_TLSV1_2 > if (!(protocol & SSL_PROTOCOL_TLSV1_2)) > SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1_2); >#endif > >#else /* if OPENSSL_VERSION_NUMBER < 0x10100000L */ > /* We first determine the maximum protocol version we should provide */ > if (protocol & SSL_PROTOCOL_TLSV1_2) { > prot = TLS1_2_VERSION; > } else if (protocol & SSL_PROTOCOL_TLSV1_1) { > prot = TLS1_1_VERSION; > } else if (protocol & SSL_PROTOCOL_TLSV1) { > prot = TLS1_VERSION; > } else if (protocol & SSL_PROTOCOL_SSLV3) { > prot = SSL3_VERSION; > } else { > SSL_CTX_free(ctx); > tcn_Throw(e, "Invalid Server SSL Protocol (%d)", protocol); > goto init_failed; > } > SSL_CTX_set_max_proto_version(ctx, prot); > > /* Next we scan for the minimal protocol version we should provide, > * but we do not allow holes between max and min */ > if (prot == TLS1_2_VERSION && protocol & SSL_PROTOCOL_TLSV1_1) { > prot = TLS1_1_VERSION; > } > if (prot == TLS1_1_VERSION && protocol & SSL_PROTOCOL_TLSV1) { > prot = TLS1_VERSION; > } > if (prot == TLS1_VERSION && protocol & SSL_PROTOCOL_SSLV3) { > prot = SSL3_VERSION; > } > SSL_CTX_set_min_proto_version(ctx, prot); >#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */ > > /* > * Configure additional context ingredients > */ > SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_DH_USE); >#ifdef HAVE_ECC > SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_ECDH_USE); >#endif >#ifdef SSL_OP_NO_COMPRESSION > /* Disable SSL compression to be safe */ > SSL_CTX_set_options(c->ctx, SSL_OP_NO_COMPRESSION); >#endif > > > /** To get back the tomcat wrapper from CTX */ > SSL_CTX_set_app_data(c->ctx, (char *)c); > >#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION > /* > * Disallow a session from being resumed during a renegotiation, > * so that an acceptable cipher suite can be negotiated. > */ > SSL_CTX_set_options(c->ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); >#endif >#ifdef SSL_MODE_RELEASE_BUFFERS > /* Release idle buffers to the SSL_CTX free list */ > SSL_CTX_set_mode(c->ctx, SSL_MODE_RELEASE_BUFFERS); >#endif > /* Default session context id and cache size */ > SSL_CTX_sess_set_cache_size(c->ctx, SSL_DEFAULT_CACHE_SIZE); > /* Session cache is disabled by default */ > SSL_CTX_set_session_cache_mode(c->ctx, SSL_SESS_CACHE_OFF); > /* Longer session timeout */ > SSL_CTX_set_timeout(c->ctx, 14400); > > EVP_Digest((const unsigned char *)SSL_DEFAULT_VHOST_NAME, > (unsigned long)((sizeof SSL_DEFAULT_VHOST_NAME) - 1), > &(c->context_id[0]), NULL, EVP_sha1(), NULL); > > /* Set default Certificate verification level > * and depth for the Client Authentication > */ > c->verify_depth = 1; > c->verify_mode = SSL_CVERIFY_UNSET; > c->shutdown_type = SSL_SHUTDOWN_TYPE_UNSET; > > /* Set default password callback */ > SSL_CTX_set_default_passwd_cb(c->ctx, (pem_password_cb *)SSL_password_callback); > SSL_CTX_set_default_passwd_cb_userdata(c->ctx, (void *)(&tcn_password_callback)); > SSL_CTX_set_info_callback(c->ctx, SSL_callback_handshake); > > /* Cache Java side SNI callback if not already cached */ > if (ssl_context_class == NULL) { > ssl_context_class = (*e)->NewGlobalRef(e, o); > sni_java_callback = (*e)->GetStaticMethodID(e, ssl_context_class, > "sniCallBack", "(JLjava/lang/String;)J"); > /* Older Tomcat versions may not have this static method */ > if ( (*e)->ExceptionCheck(e) ) { > (*e)->ExceptionClear(e); > } > } > > /* Set up OpenSSL call back if SNI is provided by the client */ > SSL_CTX_set_tlsext_servername_callback(c->ctx, ssl_callback_ServerNameIndication); > SSL_CTX_set_tlsext_servername_arg(c->ctx, c); > > /* > * Let us cleanup the ssl context when the pool is destroyed > */ > apr_pool_cleanup_register(p, (const void *)c, > ssl_context_cleanup, > apr_pool_cleanup_null); > > /* Cache the byte[].class for performance reasons */ > clazz = (*e)->FindClass(e, "[B"); > byteArrayClass = (jclass) (*e)->NewGlobalRef(e, clazz); > > return P2J(c); >init_failed: > return 0; >} > >TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); > /* Run and destroy the cleanup callback */ > return apr_pool_cleanup_run(c->pool, c, ssl_context_cleanup); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx, > jstring id) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > TCN_ALLOC_CSTRING(id); > > TCN_ASSERT(ctx != 0); > UNREFERENCED(o); > if (J2S(id)) { > EVP_Digest((const unsigned char *)J2S(id), > (unsigned long)strlen(J2S(id)), > &(c->context_id[0]), NULL, EVP_sha1(), NULL); > } > TCN_FREE_CSTRING(id); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setBIO)(TCN_STDARGS, jlong ctx, > jlong bio, jint dir) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > BIO *bio_handle = J2P(bio, BIO *); > > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); > if (dir == 0) { > if (c->bio_os && c->bio_os != bio_handle) > SSL_BIO_close(c->bio_os); > c->bio_os = bio_handle; > } > else if (dir == 1) { > if (c->bio_is && c->bio_is != bio_handle) > SSL_BIO_close(c->bio_is); > c->bio_is = bio_handle; > } > else > return; > SSL_BIO_doref(bio_handle); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx, > jint opt) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); >#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION > /* Clear the flag if not supported */ > if (opt & 0x00040000) > opt &= ~0x00040000; >#endif > SSL_CTX_set_options(c->ctx, opt); >} > >TCN_IMPLEMENT_CALL(jint, SSLContext, getOptions)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); > > return SSL_CTX_get_options(c->ctx); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, clearOptions)(TCN_STDARGS, jlong ctx, > jint opt) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); > SSL_CTX_clear_options(c->ctx, opt); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx, > jboolean mode) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); > SSL_CTX_set_quiet_shutdown(c->ctx, mode ? 1 : 0); >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx, > jstring ciphers) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > TCN_ALLOC_CSTRING(ciphers); > jboolean rv = JNI_TRUE; >#ifndef HAVE_EXPORT_CIPHERS > size_t len; > char *buf; >#endif > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > if (!J2S(ciphers)) > return JNI_FALSE; > >#ifndef HAVE_EXPORT_CIPHERS > /* > * Always disable NULL and export ciphers, > * no matter what was given in the config. > */ > len = strlen(J2S(ciphers)) + strlen(SSL_CIPHERS_ALWAYS_DISABLED) + 1; > buf = malloc(len * sizeof(char *)); > if (buf == NULL) > return JNI_FALSE; > memcpy(buf, SSL_CIPHERS_ALWAYS_DISABLED, strlen(SSL_CIPHERS_ALWAYS_DISABLED)); > memcpy(buf + strlen(SSL_CIPHERS_ALWAYS_DISABLED), J2S(ciphers), strlen(J2S(ciphers))); > buf[len - 1] = '\0'; > if (!SSL_CTX_set_cipher_list(c->ctx, buf)) { >#else > if (!SSL_CTX_set_cipher_list(c->ctx, J2S(ciphers))) { >#endif > char err[256]; > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err); > rv = JNI_FALSE; > } >#ifndef HAVE_EXPORT_CIPHERS > free(buf); >#endif > TCN_FREE_CSTRING(ciphers); > return rv; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCARevocation)(TCN_STDARGS, jlong ctx, > jstring file, > jstring path) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > TCN_ALLOC_CSTRING(file); > TCN_ALLOC_CSTRING(path); > jboolean rv = JNI_FALSE; > X509_LOOKUP *lookup; > char err[256]; > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > if (J2S(file) == NULL && J2S(path) == NULL) > return JNI_FALSE; > > if (!c->crl) { >#if 1 // CRL FIX > if ((c->crl = SSL_CTX_get_cert_store(c->ctx)) == NULL) > goto cleanup; >#else > if ((c->crl = X509_STORE_new()) == NULL) > goto cleanup; >#endif > } > if (J2S(file)) { > lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_file()); > if (lookup == NULL) { > ERR_error_string(ERR_get_error(), err); > X509_STORE_free(c->crl); > c->crl = NULL; > tcn_Throw(e, "Lookup failed for file %s (%s)", J2S(file), err); > goto cleanup; > } > X509_LOOKUP_load_file(lookup, J2S(file), X509_FILETYPE_PEM); > } > if (J2S(path)) { > lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_hash_dir()); > if (lookup == NULL) { > ERR_error_string(ERR_get_error(), err); > X509_STORE_free(c->crl); > c->crl = NULL; > tcn_Throw(e, "Lookup failed for path %s (%s)", J2S(file), err); > goto cleanup; > } > X509_LOOKUP_add_dir(lookup, J2S(path), X509_FILETYPE_PEM); > } > rv = JNI_TRUE; >cleanup: > TCN_FREE_CSTRING(file); > TCN_FREE_CSTRING(path); > return rv; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, jlong ctx, > jstring file, > jboolean skipfirst) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jboolean rv = JNI_FALSE; > TCN_ALLOC_CSTRING(file); > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > if (!J2S(file)) > return JNI_FALSE; > if (SSL_CTX_use_certificate_chain(c->ctx, J2S(file), skipfirst) > 0) > rv = JNI_TRUE; > TCN_FREE_CSTRING(file); > return rv; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS, > jlong ctx, > jstring file, > jstring path) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jboolean rv = JNI_TRUE; > TCN_ALLOC_CSTRING(file); > TCN_ALLOC_CSTRING(path); > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > if (file == NULL && path == NULL) > return JNI_FALSE; > > /* > * Configure Client Authentication details > */ > if (!SSL_CTX_load_verify_locations(c->ctx, > J2S(file), J2S(path))) { > char err[256]; > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Unable to configure locations " > "for client authentication (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > c->store = SSL_CTX_get_cert_store(c->ctx); > if (c->mode) { > STACK_OF(X509_NAME) *ca_certs; > c->ca_certs++; > ca_certs = SSL_CTX_get_client_CA_list(c->ctx); > if (ca_certs == NULL) { > SSL_load_client_CA_file(J2S(file)); > if (ca_certs != NULL) > SSL_CTX_set_client_CA_list(c->ctx, ca_certs); > } > else { > if (!SSL_add_file_cert_subjects_to_stack(ca_certs, J2S(file))) > ca_certs = NULL; > } > if (ca_certs == NULL && c->verify_mode == SSL_CVERIFY_REQUIRE) { > /* > * Give a warning when no CAs were configured but client authentication > * should take place. This cannot work. > */ > if (c->bio_os) { > BIO_printf(c->bio_os, > "[WARN] Oops, you want to request client " > "authentication, but no CAs are known for " > "verification!?"); > } > else { > fprintf(stderr, > "[WARN] Oops, you want to request client " > "authentication, but no CAs are known for " > "verification!?"); > } > > } > } >cleanup: > TCN_FREE_CSTRING(file); > TCN_FREE_CSTRING(path); > return rv; >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setTmpDH)(TCN_STDARGS, jlong ctx, > jstring file) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > BIO *bio = NULL; > DH *dh = NULL; > TCN_ALLOC_CSTRING(file); > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > TCN_ASSERT(file); > > if (!J2S(file)) { > tcn_Throw(e, "Error while configuring DH: no dh param file given"); > return; > } > > bio = BIO_new_file(J2S(file), "r"); > if (!bio) { > char err[256]; > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error while configuring DH using %s: %s", J2S(file), err); > TCN_FREE_CSTRING(file); > return; > } > > dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); > BIO_free(bio); > if (!dh) { > char err[256]; > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error while configuring DH: no DH parameter found in %s (%s)", J2S(file), err); > TCN_FREE_CSTRING(file); > return; > } > > if (1 != SSL_CTX_set_tmp_dh(c->ctx, dh)) { > char err[256]; > DH_free(dh); > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error while configuring DH with file %s: %s", J2S(file), err); > TCN_FREE_CSTRING(file); > return; > } > > DH_free(dh); > TCN_FREE_CSTRING(file); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setTmpECDHByCurveName)(TCN_STDARGS, jlong ctx, > jstring curveName) >{ >#ifdef HAVE_ECC > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > int i; > EC_KEY *ecdh; > TCN_ALLOC_CSTRING(curveName); > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > TCN_ASSERT(curveName); > > /* First try to get curve by name */ > i = OBJ_sn2nid(J2S(curveName)); > if (!i) { > tcn_Throw(e, "Can't configure elliptic curve: unknown curve name %s", J2S(curveName)); > TCN_FREE_CSTRING(curveName); > return; > } > > ecdh = EC_KEY_new_by_curve_name(i); > if (!ecdh) { > tcn_Throw(e, "Can't configure elliptic curve: unknown curve name %s", J2S(curveName)); > TCN_FREE_CSTRING(curveName); > return; > } > > /* Setting found curve to context */ > if (1 != SSL_CTX_set_tmp_ecdh(c->ctx, ecdh)) { > char err[256]; > EC_KEY_free(ecdh); > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error while configuring elliptic curve %s: %s", J2S(curveName), err); > TCN_FREE_CSTRING(curveName); > return; > } > EC_KEY_free(ecdh); > TCN_FREE_CSTRING(curveName); >#else > tcn_Throw(e, "Cant't configure elliptic curve: unsupported by this OpenSSL version"); > return; >#endif >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx, > jint type) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > UNREFERENCED_STDARGS; > TCN_ASSERT(ctx != 0); > c->shutdown_type = type; >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx, > jint level, jint depth) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > int verify = SSL_VERIFY_NONE; > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > c->verify_mode = level; > > if (c->verify_mode == SSL_CVERIFY_UNSET) > c->verify_mode = SSL_CVERIFY_NONE; > if (depth > 0) > c->verify_depth = depth; > /* > * Configure callbacks for SSL context > */ > if (c->verify_mode == SSL_CVERIFY_REQUIRE) > verify |= SSL_VERIFY_PEER_STRICT; > if ((c->verify_mode == SSL_CVERIFY_OPTIONAL) || > (c->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) > verify |= SSL_VERIFY_PEER; > if (!c->store) { > if (SSL_CTX_set_default_verify_paths(c->ctx)) { > c->store = SSL_CTX_get_cert_store(c->ctx); > X509_STORE_set_flags(c->store, 0); > } > else { > /* XXX: See if this is fatal */ > } > } > >#if 1 // CRL FIX > X509_STORE_set_flags(c->store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); >#endif > SSL_CTX_set_verify(c->ctx, verify, SSL_callback_SSL_verify); >} > >static EVP_PKEY *load_pem_key(tcn_ssl_ctxt_t *c, const char *file) >{ > BIO *bio = NULL; > EVP_PKEY *key = NULL; > tcn_pass_cb_t *cb_data = c->cb_data; > int i; > > if ((bio = BIO_new(BIO_s_file())) == NULL) { > return NULL; > } > if (BIO_read_filename(bio, file) <= 0) { > BIO_free(bio); > return NULL; > } > if (!cb_data) > cb_data = &tcn_password_callback; > for (i = 0; i < 3; i++) { > key = PEM_read_bio_PrivateKey(bio, NULL, > (pem_password_cb *)SSL_password_callback, > (void *)cb_data); > if (key) > break; > cb_data->password[0] = '\0'; > BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); > } > BIO_free(bio); > return key; >} > >static X509 *load_pem_cert(tcn_ssl_ctxt_t *c, const char *file) >{ > BIO *bio = NULL; > X509 *cert = NULL; > tcn_pass_cb_t *cb_data = c->cb_data; > > if ((bio = BIO_new(BIO_s_file())) == NULL) { > return NULL; > } > if (BIO_read_filename(bio, file) <= 0) { > BIO_free(bio); > return NULL; > } > if (!cb_data) > cb_data = &tcn_password_callback; > cert = PEM_read_bio_X509_AUX(bio, NULL, > (pem_password_cb *)SSL_password_callback, > (void *)cb_data); > if (cert == NULL && > (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE)) { > ERR_clear_error(); > BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); > cert = d2i_X509_bio(bio, NULL); > } > BIO_free(bio); > return cert; >} > >static int ssl_load_pkcs12(tcn_ssl_ctxt_t *c, const char *file, > EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) >{ > const char *pass; > char buff[PEM_BUFSIZE]; > int len, rc = 0; > PKCS12 *p12; > BIO *in; > tcn_pass_cb_t *cb_data = c->cb_data; > > if ((in = BIO_new(BIO_s_file())) == 0) > return 0; > if (BIO_read_filename(in, file) <= 0) { > BIO_free(in); > return 0; > } > p12 = d2i_PKCS12_bio(in, 0); > if (p12 == 0) { > /* Error loading PKCS12 file */ > goto cleanup; > } > /* See if an empty password will do */ > if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, 0, 0)) { > pass = ""; > } > else { > if (!cb_data) > cb_data = &tcn_password_callback; > len = SSL_password_callback(buff, PEM_BUFSIZE, 0, cb_data); > if (len < 0) { > /* Passpharse callback error */ > goto cleanup; > } > if (!PKCS12_verify_mac(p12, buff, len)) { > /* Mac verify error (wrong password?) in PKCS12 file */ > goto cleanup; > } > pass = buff; > } > rc = PKCS12_parse(p12, pass, pkey, cert, ca); >cleanup: > if (p12 != 0) > PKCS12_free(p12); > BIO_free(in); > return rc; >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx, > jstring file) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > TCN_ALLOC_CSTRING(file); > > TCN_ASSERT(ctx != 0); > UNREFERENCED(o); > if (J2S(file)) > c->rand_file = apr_pstrdup(c->pool, J2S(file)); > TCN_FREE_CSTRING(file); >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx, > jstring cert, jstring key, > jstring password, jint idx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jboolean rv = JNI_TRUE; > TCN_ALLOC_CSTRING(cert); > TCN_ALLOC_CSTRING(key); > TCN_ALLOC_CSTRING(password); > const char *key_file, *cert_file; > const char *p; > char err[256]; >#ifdef HAVE_ECC > EC_GROUP *ecparams; > int nid; > EC_KEY *eckey = NULL; >#endif > DH *dhparams; > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > > if (idx < 0 || idx >= SSL_AIDX_MAX) { > /* TODO: Throw something */ > rv = JNI_FALSE; > goto cleanup; > } > if (J2S(password)) { > if (!c->cb_data) > c->cb_data = &tcn_password_callback; > strncpy(c->cb_data->password, J2S(password), SSL_MAX_PASSWORD_LEN); > c->cb_data->password[SSL_MAX_PASSWORD_LEN-1] = '\0'; > } > key_file = J2S(key); > cert_file = J2S(cert); > if (!key_file) > key_file = cert_file; > if (!key_file || !cert_file) { > tcn_Throw(e, "No Certificate file specified or invalid file format"); > rv = JNI_FALSE; > goto cleanup; > } > if ((p = strrchr(cert_file, '.')) != NULL && strcmp(p, ".pkcs12") == 0) { > if (!ssl_load_pkcs12(c, cert_file, &c->keys[idx], &c->certs[idx], 0)) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Unable to load certificate %s (%s)", > cert_file, err); > rv = JNI_FALSE; > goto cleanup; > } > } > else { > if ((c->keys[idx] = load_pem_key(c, key_file)) == NULL) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Unable to load certificate key %s (%s)", > key_file, err); > rv = JNI_FALSE; > goto cleanup; > } > if ((c->certs[idx] = load_pem_cert(c, cert_file)) == NULL) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Unable to load certificate %s (%s)", > cert_file, err); > rv = JNI_FALSE; > goto cleanup; > } > } > if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error setting certificate (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error setting private key (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > if (SSL_CTX_check_private_key(c->ctx) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Private key does not match the certificate public key (%s)", > err); > rv = JNI_FALSE; > goto cleanup; > } > > /* > * Try to read DH parameters from the (first) SSLCertificateFile > */ > /* XXX Does this also work for pkcs12 or only for PEM files? > * If only for PEM files move above to the PEM handling */ > if ((idx == 0) && (dhparams = SSL_dh_GetParamFromFile(cert_file))) { > SSL_CTX_set_tmp_dh(c->ctx, dhparams); > } > >#ifdef HAVE_ECC > /* > * Similarly, try to read the ECDH curve name from SSLCertificateFile... > */ > /* XXX Does this also work for pkcs12 or only for PEM files? > * If only for PEM files move above to the PEM handling */ > if ((ecparams = SSL_ec_GetParamFromFile(cert_file)) && > (nid = EC_GROUP_get_curve_name(ecparams)) && > (eckey = EC_KEY_new_by_curve_name(nid))) { > SSL_CTX_set_tmp_ecdh(c->ctx, eckey); > } > /* > * ...otherwise, configure NIST P-256 (required to enable ECDHE) > */ > else { >#if defined(SSL_CTX_set_ecdh_auto) > SSL_CTX_set_ecdh_auto(c->ctx, 1); >#else > eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); > SSL_CTX_set_tmp_ecdh(c->ctx, eckey); >#endif > } > EC_KEY_free(eckey); >#endif > SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH); > >cleanup: > TCN_FREE_CSTRING(cert); > TCN_FREE_CSTRING(key); > TCN_FREE_CSTRING(password); > return rv; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateRaw)(TCN_STDARGS, jlong ctx, > jbyteArray javaCert, jbyteArray javaKey, jint idx) >{ >#ifdef HAVE_ECC >#ifndef SSL_CTX_set_ecdh_auto > EC_KEY *eckey = NULL; >#endif >#endif > jsize lengthOfCert; > unsigned char* cert; > X509 * certs; > EVP_PKEY * evp; > const unsigned char *tmp; > BIO * bio; > > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jboolean rv = JNI_TRUE; > char err[256]; > > /* we get the key contents into a byte array */ > jbyte* bufferPtr = (*e)->GetByteArrayElements(e, javaKey, NULL); > jsize lengthOfKey = (*e)->GetArrayLength(e, javaKey); > unsigned char* key = malloc(lengthOfKey); > memcpy(key, bufferPtr, lengthOfKey); > (*e)->ReleaseByteArrayElements(e, javaKey, bufferPtr, 0); > > bufferPtr = (*e)->GetByteArrayElements(e, javaCert, NULL); > lengthOfCert = (*e)->GetArrayLength(e, javaCert); > cert = malloc(lengthOfCert); > memcpy(cert, bufferPtr, lengthOfCert); > (*e)->ReleaseByteArrayElements(e, javaCert, bufferPtr, 0); > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > > if (idx < 0 || idx >= SSL_AIDX_MAX) { > tcn_Throw(e, "Invalid key type"); > rv = JNI_FALSE; > goto cleanup; > } > > tmp = (const unsigned char *)cert; > certs = d2i_X509(NULL, &tmp, lengthOfCert); > if (certs == NULL) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error reading certificate (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > if(c->certs[idx] != NULL) { > free(c->certs[idx]); > } > c->certs[idx] = certs; > > bio = BIO_new(BIO_s_mem()); > BIO_write(bio, key, lengthOfKey); > > evp = PEM_read_bio_PrivateKey(bio, NULL, 0, NULL); > if (evp == NULL) { > BIO_free(bio); > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error reading private key (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > BIO_free(bio); > if(c->keys[idx] != NULL) { > free(c->keys[idx]); > } > c->keys[idx] = evp; > > if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error setting certificate (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error setting private key (%s)", err); > rv = JNI_FALSE; > goto cleanup; > } > if (SSL_CTX_check_private_key(c->ctx) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Private key does not match the certificate public key (%s)", > err); > rv = JNI_FALSE; > goto cleanup; > } > > /* > * TODO Try to read DH parameters from somewhere... > */ > >#ifdef HAVE_ECC > /* > * TODO try to read the ECDH curve name from somewhere... > */ >#if defined(SSL_CTX_set_ecdh_auto) > SSL_CTX_set_ecdh_auto(c->ctx, 1); >#else > eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); > SSL_CTX_set_tmp_ecdh(c->ctx, eckey); > EC_KEY_free(eckey); >#endif >#endif > SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH); >cleanup: > free(key); > free(cert); > return rv; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, addChainCertificateRaw)(TCN_STDARGS, jlong ctx, > jbyteArray javaCert) >{ > jsize lengthOfCert; > unsigned char* cert; > X509 * certs; > const unsigned char *tmp; > > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jboolean rv = JNI_TRUE; > char err[256]; > > /* we get the cert contents into a byte array */ > jbyte* bufferPtr = (*e)->GetByteArrayElements(e, javaCert, NULL); > lengthOfCert = (*e)->GetArrayLength(e, javaCert); > cert = malloc(lengthOfCert); > memcpy(cert, bufferPtr, lengthOfCert); > (*e)->ReleaseByteArrayElements(e, javaCert, bufferPtr, 0); > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > > tmp = (const unsigned char *)cert; > certs = d2i_X509(NULL, &tmp, lengthOfCert); > if (certs == NULL) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error reading certificate (%s)", err); > rv = JNI_FALSE; > } else if (SSL_CTX_add0_chain_cert(c->ctx, certs) <= 0) { > ERR_error_string(ERR_get_error(), err); > tcn_Throw(e, "Error adding certificate to chain (%s)", err); > rv = JNI_FALSE; > } > > free(cert); > return rv; >} > >static int ssl_array_index(apr_array_header_t *array, > const char *s) >{ > int i; > for (i = 0; i < array->nelts; i++) { > const char *p = APR_ARRAY_IDX(array, i, const char*); > if (!strcmp(p, s)) { > return i; > } > } > return -1; >} > >static int ssl_cmp_alpn_protos(apr_array_header_t *array, > const char *proto1, > const char *proto2) >{ > int index1 = ssl_array_index(array, proto1); > int index2 = ssl_array_index(array, proto2); > if (index2 > index1) { > return (index1 >= 0)? 1 : -1; > } > else if (index1 > index2) { > return (index2 >= 0)? -1 : 1; > } > > /* Both have the same index (-1 so neither listed by cient) compare > * the names so that spdy3 gets precedence over spdy2. That makes > * the outcome at least deterministic. */ > return strcmp((const char *)proto1, (const char *)proto2); >} > >/* > * This callback function is executed when the TLS Application Layer > * Protocol Negotiate Extension (ALPN, RFC 7301) is triggered by the client > * hello, giving a list of desired protocol names (in descending preference) > * to the server. > * The callback has to select a protocol name or return an error if none of > * the clients preferences is supported. > * The selected protocol does not have to be on the client list, according > * to RFC 7301, so no checks are performed. > * The client protocol list is serialized as length byte followed by ascii > * characters (not null-terminated), followed by the next protocol name. > */ >int cb_server_alpn(SSL *ssl, > const unsigned char **out, unsigned char *outlen, > const unsigned char *in, unsigned int inlen, void *arg) >{ > tcn_ssl_ctxt_t *tcsslctx = (tcn_ssl_ctxt_t *)arg; > tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl); > apr_array_header_t *client_protos; > apr_array_header_t *proposed_protos; > int i; > size_t len; > > if (inlen == 0) { > // Client specified an empty protocol list. Nothing to negotiate. > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > > client_protos = apr_array_make(con->pool , 0, sizeof(char *)); > for (i = 0; i < inlen; /**/) { > /* Grab length of next item from leading length byte */ > unsigned int plen = in[i++]; > if (plen + i > inlen) { > // The protocol name extends beyond the declared length > // of the protocol list. > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > APR_ARRAY_PUSH(client_protos, char*) = apr_pstrndup(con->pool, (const char *)in+i, plen); > i += plen; > } > > if (tcsslctx->alpn == NULL) { > // Server supported protocol names not set. > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > > if (tcsslctx->alpnlen == 0) { > // Server supported protocols is an empty list > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > > proposed_protos = apr_array_make(con->pool, 0, sizeof(char *)); > for (i = 0; i < tcsslctx->alpnlen; /**/) { > /* Grab length of next item from leading length byte */ > unsigned int plen = tcsslctx->alpn[i++]; > if (plen + i > tcsslctx->alpnlen) { > // The protocol name extends beyond the declared length > // of the protocol list. > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > APR_ARRAY_PUSH(proposed_protos, char*) = apr_pstrndup(con->pool, (const char *)tcsslctx->alpn+i, plen); > i += plen; > } > > if (proposed_protos->nelts <= 0) { > // Should never happen. The server did not specify any protocols. > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > > /* Now select the most preferred protocol from the proposals. */ > *out = APR_ARRAY_IDX(proposed_protos, 0, const unsigned char *); > for (i = 1; i < proposed_protos->nelts; ++i) { > const char *proto = APR_ARRAY_IDX(proposed_protos, i, const char*); > /* Do we prefer it over existing candidate? */ > if (ssl_cmp_alpn_protos(client_protos, (const char *)*out, proto) < 0) { > *out = (const unsigned char*)proto; > } > } > > len = strlen((const char*)*out); > if (len > 255) { > // Agreed protocol name too long > return SSL_TLSEXT_ERR_ALERT_FATAL; > } > > *outlen = (unsigned char)len; > > return SSL_TLSEXT_ERR_OK; >} > >TCN_IMPLEMENT_CALL(jint, SSLContext, setALPN)(TCN_STDARGS, jlong ctx, > jbyteArray buf, jint len) >{ > tcn_ssl_ctxt_t *sslctx = J2P(ctx, tcn_ssl_ctxt_t *); > > sslctx->alpn = apr_pcalloc(sslctx->pool, len); > (*e)->GetByteArrayRegion(e, buf, 0, len, (jbyte *)sslctx->alpn); > sslctx->alpnlen = len; > > if (sslctx->mode == SSL_MODE_SERVER) { > SSL_CTX_set_alpn_select_cb(sslctx->ctx, cb_server_alpn, sslctx); > } else { > /* > * TODO: Implement client side call-back > * SSL_CTX_set_next_proto_select_cb(sslctx->ctx, cb_request_alpn, sslctx); > */ > return APR_ENOTIMPL; > } > return 0; >} > >/* Start of netty-tc-native add */ > >/* Convert protos to wire format */ >static int initProtocols(JNIEnv *e, const tcn_ssl_ctxt_t *c, unsigned char **proto_data, > unsigned int *proto_len, jobjectArray protos) { > int i; > unsigned char *p_data; > /* > * We start with allocate 128 bytes which should be good enough for most use-cases while still be pretty low. > * We will call realloc to increate this if needed. > */ > size_t p_data_size = 128; > size_t p_data_len = 0; > jstring proto_string; > const char *proto_chars; > size_t proto_chars_len; > int cnt; > > if (protos == NULL) { > // Guard against NULL protos. > return -1; > } > > cnt = (*e)->GetArrayLength(e, protos); > > if (cnt == 0) { > // if cnt is 0 we not need to continue and can just fail fast. > return -1; > } > > p_data = (unsigned char *) malloc(p_data_size); > if (p_data == NULL) { > // Not enough memory? > return -1; > } > > for (i = 0; i < cnt; ++i) { > proto_string = (jstring) (*e)->GetObjectArrayElement(e, protos, i); > proto_chars = (*e)->GetStringUTFChars(e, proto_string, 0); > > proto_chars_len = strlen(proto_chars); > if (proto_chars_len > 0 && proto_chars_len <= MAX_ALPN_NPN_PROTO_SIZE) { > // We need to add +1 as each protocol is prefixed by it's length (unsigned char). > // For all except of the last one we already have the extra space as everything is > // delimited by ','. > p_data_len += 1 + proto_chars_len; > if (p_data_len > p_data_size) { > // double size > p_data_size <<= 1; > p_data = realloc(p_data, p_data_size); > if (p_data == NULL) { > // Not enough memory? > (*e)->ReleaseStringUTFChars(e, proto_string, proto_chars); > break; > } > } > // Write the length of the protocol and then increment before memcpy the protocol itself. > *p_data = proto_chars_len; > ++p_data; > memcpy(p_data, proto_chars, proto_chars_len); > p_data += proto_chars_len; > } > > // Release the string to prevent memory leaks > (*e)->ReleaseStringUTFChars(e, proto_string, proto_chars); > } > > if (p_data == NULL) { > // Something went wrong so update the proto_len and return -1 > *proto_len = 0; > return -1; > } else { > if (*proto_data != NULL) { > // Free old data > free(*proto_data); > } > // Decrement pointer again as we incremented it while creating the protocols in wire format. > p_data -= p_data_len; > *proto_data = p_data; > *proto_len = p_data_len; > return 0; > } >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setNpnProtos)(TCN_STDARGS, jlong ctx, jobjectArray next_protos, > jint selectorFailureBehavior) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > TCN_ASSERT(ctx != 0); > UNREFERENCED(o); > > if (initProtocols(e, c, &c->next_proto_data, &c->next_proto_len, next_protos) == 0) { > c->next_selector_failure_behavior = selectorFailureBehavior; > > // depending on if it's client mode or not we need to call different functions. > if (c->mode == SSL_MODE_CLIENT) { > SSL_CTX_set_next_proto_select_cb(c->ctx, SSL_callback_select_next_proto, (void *)c); > } else { > SSL_CTX_set_next_protos_advertised_cb(c->ctx, SSL_callback_next_protos, (void *)c); > } > } >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setAlpnProtos)(TCN_STDARGS, jlong ctx, jobjectArray alpn_protos, > jint selectorFailureBehavior) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > TCN_ASSERT(ctx != 0); > UNREFERENCED(o); > > if (initProtocols(e, c, &c->alpn_proto_data, &c->alpn_proto_len, alpn_protos) == 0) { > c->alpn_selector_failure_behavior = selectorFailureBehavior; > > // depending on if it's client mode or not we need to call different functions. > if (c->mode == SSL_MODE_CLIENT) { > SSL_CTX_set_alpn_protos(c->ctx, c->alpn_proto_data, c->alpn_proto_len); > } else { > SSL_CTX_set_alpn_select_cb(c->ctx, SSL_callback_alpn_select_proto, (void *) c); > > } > } >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheMode)(TCN_STDARGS, jlong ctx, jlong mode) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > return SSL_CTX_set_session_cache_mode(c->ctx, mode); >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheMode)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > return SSL_CTX_get_session_cache_mode(c->ctx); >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheTimeout)(TCN_STDARGS, jlong ctx, jlong timeout) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_set_timeout(c->ctx, timeout); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheTimeout)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > return SSL_CTX_get_timeout(c->ctx); >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheSize)(TCN_STDARGS, jlong ctx, jlong size) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = 0; > > // Also allow size of 0 which is unlimited > if (size >= 0) { > SSL_CTX_set_session_cache_mode(c->ctx, SSL_SESS_CACHE_SERVER); > rv = SSL_CTX_sess_set_cache_size(c->ctx, size); > } > > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheSize)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > return SSL_CTX_sess_get_cache_size(c->ctx); >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionNumber)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_number(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnect)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_connect(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnectGood)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_connect_good(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnectRenegotiate)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_connect_renegotiate(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAccept)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_accept(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAcceptGood)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_accept_good(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAcceptRenegotiate)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_accept_renegotiate(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionHits)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_hits(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCbHits)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_cb_hits(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionMisses)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_misses(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTimeouts)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_timeouts(c->ctx); > return rv; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCacheFull)(TCN_STDARGS, jlong ctx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jlong rv = SSL_CTX_sess_cache_full(c->ctx); > return rv; >} > >#define TICKET_KEYS_SIZE 48 >TCN_IMPLEMENT_CALL(void, SSLContext, setSessionTicketKeys)(TCN_STDARGS, jlong ctx, jbyteArray keys) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > jbyte* b; > > if ((*e)->GetArrayLength(e, keys) != TICKET_KEYS_SIZE) { > if (c->bio_os) { > BIO_printf(c->bio_os, "[ERROR] Session ticket keys provided were wrong size."); > } > else { > fprintf(stderr, "[ERROR] Session ticket keys provided were wrong size."); > } > exit(1); > } > > b = (*e)->GetByteArrayElements(e, keys, NULL); > SSL_CTX_set_tlsext_ticket_keys(c->ctx, b, TICKET_KEYS_SIZE); > (*e)->ReleaseByteArrayElements(e, keys, b, 0); >} > > >#if OPENSSL_VERSION_NUMBER < 0x10100000L > >/* > * Adapted from OpenSSL: > * https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/ssl/ssl_locl.h#L318 > */ >/* Bits for algorithm_mkey (key exchange algorithm) */ >/* RSA key exchange */ ># define SSL_kRSA 0x00000001L >/* DH cert, RSA CA cert */ ># define SSL_kDHr 0x00000002L >/* DH cert, DSA CA cert */ ># define SSL_kDHd 0x00000004L >/* tmp DH key no DH cert */ ># define SSL_kEDH 0x00000008L >/* forward-compatible synonym */ ># define SSL_kDHE SSL_kEDH >/* Kerberos5 key exchange */ ># define SSL_kKRB5 0x00000010L >/* ECDH cert, RSA CA cert */ ># define SSL_kECDHr 0x00000020L >/* ECDH cert, ECDSA CA cert */ ># define SSL_kECDHe 0x00000040L >/* ephemeral ECDH */ ># define SSL_kEECDH 0x00000080L >/* forward-compatible synonym */ ># define SSL_kECDHE SSL_kEECDH >/* PSK */ ># define SSL_kPSK 0x00000100L >/* GOST key exchange */ ># define SSL_kGOST 0x00000200L >/* SRP */ ># define SSL_kSRP 0x00000400L > >/* Bits for algorithm_auth (server authentication) */ >/* RSA auth */ ># define SSL_aRSA 0x00000001L >/* DSS auth */ ># define SSL_aDSS 0x00000002L >/* no auth (i.e. use ADH or AECDH) */ ># define SSL_aNULL 0x00000004L >/* Fixed DH auth (kDHd or kDHr) */ ># define SSL_aDH 0x00000008L >/* Fixed ECDH auth (kECDHe or kECDHr) */ ># define SSL_aECDH 0x00000010L >/* KRB5 auth */ ># define SSL_aKRB5 0x00000020L >/* ECDSA auth*/ ># define SSL_aECDSA 0x00000040L >/* PSK auth */ ># define SSL_aPSK 0x00000080L >/* GOST R 34.10-94 signature auth */ ># define SSL_aGOST94 0x00000100L >/* GOST R 34.10-2001 signature auth */ ># define SSL_aGOST01 0x00000200L >/* SRP auth */ ># define SSL_aSRP 0x00000400L > >/* OpenSSL end */ > >#define TCN_SSL_kRSA SSL_kRSA >#define TCN_SSL_kDHr SSL_kDHr >#define TCN_SSL_kDHd SSL_kDHd >#define TCN_SSL_kDHE SSL_kDHE >#define TCN_SSL_kKRB5 SSL_kKRB5 >#define TCN_SSL_kECDHr SSL_kECDHr >#define TCN_SSL_kECDHe SSL_kECDHe >#define TCN_SSL_kECDHE SSL_kECDHE > >#define TCN_SSL_aRSA SSL_aRSA >#define TCN_SSL_aDSS SSL_aDSS >#define TCN_SSL_aNULL SSL_aNULL >#define TCN_SSL_aDH SSL_aDH >#define TCN_SSL_aECDH SSL_aECDH >#define TCN_SSL_aKRB5 SSL_aKRB5 >#define TCN_SSL_aECDSA SSL_aECDSA > >#else > >#define TCN_SSL_kRSA NID_kx_rsa >#define TCN_SSL_kDHE NID_kx_dhe >#define TCN_SSL_kECDHE NID_kx_ecdhe > >#define TCN_SSL_aRSA NID_auth_rsa >#define TCN_SSL_aDSS NID_auth_dss >#define TCN_SSL_aNULL NID_auth_null >#define TCN_SSL_aECDSA NID_auth_ecdsa > >#endif > >/* > * Adapted from Android: > * https://android.googlesource.com/platform/external/openssl/+/master/patches/0003-jsse.patch > */ >static const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher){ > int auth; > int kx; > if (cipher == NULL) { > return "UNKNOWN"; > } >#if OPENSSL_VERSION_NUMBER < 0x10100000L > kx = cipher->algorithm_mkey; > auth = cipher->algorithm_auth; >#else > kx = SSL_CIPHER_get_kx_nid(cipher); > auth = SSL_CIPHER_get_auth_nid(cipher); >#endif > > switch (kx) > { > case TCN_SSL_kRSA: > return SSL_TXT_RSA; >#if OPENSSL_VERSION_NUMBER < 0x10100000L > case TCN_SSL_kDHr: > return SSL_TXT_DH "_" SSL_TXT_RSA; > case TCN_SSL_kDHd: > return SSL_TXT_DH "_" SSL_TXT_DSS; >#endif > case TCN_SSL_kDHE: > switch (auth) > { > case TCN_SSL_aDSS: > return "DHE_" SSL_TXT_DSS; > case TCN_SSL_aRSA: > return "DHE_" SSL_TXT_RSA; > case TCN_SSL_aNULL: > return SSL_TXT_DH "_anon"; > default: > return "UNKNOWN"; > } >#if OPENSSL_VERSION_NUMBER < 0x10100000L > case TCN_SSL_kKRB5: > return SSL_TXT_KRB5; > case TCN_SSL_kECDHr: > return SSL_TXT_ECDH "_" SSL_TXT_RSA; > case TCN_SSL_kECDHe: > return SSL_TXT_ECDH "_" SSL_TXT_ECDSA; >#endif > case TCN_SSL_kECDHE: > switch (auth) > { > case TCN_SSL_aECDSA: > return "ECDHE_" SSL_TXT_ECDSA; > case TCN_SSL_aRSA: > return "ECDHE_" SSL_TXT_RSA; > case TCN_SSL_aNULL: > return SSL_TXT_ECDH "_anon"; > default: > return "UNKNOWN"; > } > default: > return "UNKNOWN"; > } >} > >static const char* SSL_authentication_method(const SSL* ssl) { >#if OPENSSL_VERSION_NUMBER < 0x10100000L > return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher); >#else > /* XXX ssl->s3->tmp.new_cipher is no longer available in OpenSSL 1.1.0 */ > /* https://github.com/netty/netty-tcnative/blob/1.1.33/openssl-dynamic/src/main/c/sslcontext.c > * contains a different method, but I think this is not correct. > * Instead of choosing the cipher used for the current handshake it simply > * uses the first cipher available during the handshake. */ > /* Not sure whether SSL_get_current_cipher(ssl) returns something useful > * at the point in time we call it. */ > return SSL_CIPHER_authentication_method(SSL_get_current_cipher(ssl)); >#endif >} >/* Android end */ > >static int SSL_cert_verify(X509_STORE_CTX *ctx, void *arg) { > /* Get Apache context back through OpenSSL context */ > SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); > tcn_ssl_ctxt_t *c = SSL_get_app_data2(ssl); > > > // Get a stack of all certs in the chain > STACK_OF(X509) *sk = X509_STORE_CTX_get0_untrusted(ctx); > > int len = sk_X509_num(sk); > unsigned i; > X509 *cert; > int length; > unsigned char *buf; > JNIEnv *e; > jbyteArray array; > jbyteArray bArray; > const char *authMethod; > jstring authMethodString; > jboolean result; > int r; > tcn_get_java_env(&e); > > // Create the byte[][]Â array that holds all the certs > array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL); > > for(i = 0; i < len; i++) { > cert = (X509*) sk_X509_value(sk, i); > > buf = NULL; > length = i2d_X509(cert, &buf); > if (length < 0) { > // In case of error just return an empty byte[][] > array = (*e)->NewObjectArray(e, 0, byteArrayClass, NULL); > // We need to delete the local references so we not leak memory as this method is called via callback. > OPENSSL_free(buf); > break; > } > bArray = (*e)->NewByteArray(e, length); > (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf); > (*e)->SetObjectArrayElement(e, array, i, bArray); > > // Delete the local reference as we not know how long the chain is and local references are otherwise > // only freed once jni method returns. > (*e)->DeleteLocalRef(e, bArray); > OPENSSL_free(buf); > } > > authMethod = SSL_authentication_method(ssl); > authMethodString = (*e)->NewStringUTF(e, authMethod); > > result = (*e)->CallBooleanMethod(e, c->verifier, c->verifier_method, P2J(ssl), array, > authMethodString); > > r = result == JNI_TRUE ? 1 : 0; > > // We need to delete the local references so we not leak memory as this method is called via callback. > (*e)->DeleteLocalRef(e, authMethodString); > (*e)->DeleteLocalRef(e, array); > return r; >} > > >TCN_IMPLEMENT_CALL(void, SSLContext, setCertVerifyCallback)(TCN_STDARGS, jlong ctx, jobject verifier) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > > if (verifier == NULL) { > SSL_CTX_set_cert_verify_callback(c->ctx, NULL, NULL); > } else { > jclass verifier_class = (*e)->GetObjectClass(e, verifier); > jmethodID method = (*e)->GetMethodID(e, verifier_class, "verify", "(J[[BLjava/lang/String;)Z"); > > if (method == NULL) { > return; > } > // Delete the reference to the previous specified verifier if needed. > if (c->verifier != NULL) { > (*e)->DeleteLocalRef(e, c->verifier); > } > c->verifier = (*e)->NewGlobalRef(e, verifier); > c->verifier_method = method; > > SSL_CTX_set_cert_verify_callback(c->ctx, SSL_cert_verify, NULL); > } >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setSessionIdContext)(TCN_STDARGS, jlong ctx, jbyteArray sidCtx) >{ > tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); > int len = (*e)->GetArrayLength(e, sidCtx); > unsigned char *buf; > int res; > > UNREFERENCED(o); > TCN_ASSERT(ctx != 0); > > buf = malloc(len); > > (*e)->GetByteArrayRegion(e, sidCtx, 0, len, (jbyte*) buf); > > res = SSL_CTX_set_session_id_context(c->ctx, buf, len); > free(buf); > > if (res == 1) { > return JNI_TRUE; > } > return JNI_FALSE; >} > >/* End of netty-tc-native add */ >#else >/* OpenSSL is not supported. > * Create empty stubs. > */ > >TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jlong pool, > jint protocol, jint mode) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(pool); > UNREFERENCED(protocol); > UNREFERENCED(mode); > return 0; >} > >TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return APR_ENOTIMPL; >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx, > jstring id) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(id); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setBIO)(TCN_STDARGS, jlong ctx, > jlong bio, jint dir) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(bio); > UNREFERENCED(dir); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx, > jint opt) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(opt); >} > >TCN_IMPLEMENT_CALL(jint, SSLContext, getOptions)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, clearOptions)(TCN_STDARGS, jlong ctx, > jint opt) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(opt); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx, > jboolean mode) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(mode); >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx, > jstring ciphers) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(ciphers); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCARevocation)(TCN_STDARGS, jlong ctx, > jstring file, > jstring path) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(file); > UNREFERENCED(path); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, jlong ctx, > jstring file, > jboolean skipfirst) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(file); > UNREFERENCED(skipfirst); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS, > jlong ctx, > jstring file, > jstring path) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(file); > UNREFERENCED(path); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx, > jint type) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(type); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx, > jint level, jint depth) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(level); > UNREFERENCED(depth); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx, > jstring file) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(file); >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx, > jstring cert, jstring key, > jstring password, jint idx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(cert); > UNREFERENCED(key); > UNREFERENCED(password); > UNREFERENCED(idx); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateRaw)(TCN_STDARGS, jlong ctx, > jbyteArray javaCert, jbyteArray javaKey, > jint idx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(javaCert); > UNREFERENCED(javaKey); > UNREFERENCED(idx); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(jboolean, SSLContext, addChainCertificateRaw)(TCN_STDARGS, jlong ctx, > jbyteArray javaCert) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(javaCert); > return JNI_FALSE; >} > >TCN_IMPLEMENT_CALL(jint, SSLContext, setALPN)(TCN_STDARGS, jlong ctx, > jbyteArray buf, jint len) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(buf); > UNREFERENCED(len); > return APR_ENOTIMPL; >} > >/* Start of netty-tc-native add */ > >TCN_IMPLEMENT_CALL(void, SSLContext, setNpnProtos)(TCN_STDARGS, jlong ctx, jobjectArray next_protos, > jint selectorFailureBehavior) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(next_protos); >} > > >TCN_IMPLEMENT_CALL(void, SSLContext, setAlpnProtos)(TCN_STDARGS, jlong ctx, jobjectArray alpn_protos, > jint selectorFailureBehavior) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(alpn_protos); >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheMode)(TCN_STDARGS, jlong ctx, jlong mode) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(mode); > return -1; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheMode)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return -1; >} > > >TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheTimeout)(TCN_STDARGS, jlong ctx, jlong timeout) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(timeout); > return -1; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheTimeout)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return -1; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheSize)(TCN_STDARGS, jlong ctx, jlong size) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(size); > return -1; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheSize)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return -1; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionNumber)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnect)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnectGood)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnectRenegotiate)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAccept)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAcceptGood)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAcceptRenegotiate)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionHits)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCbHits)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTimeouts)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCacheFull)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionMisses)(TCN_STDARGS, jlong ctx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > return 0; >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setSessionTicketKeys)(TCN_STDARGS, jlong ctx, jbyteArray keys) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(keys); >} > >TCN_IMPLEMENT_CALL(void, SSLContext, setCertVerifyCallback)(TCN_STDARGS, jlong ctx, jobject verifier) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(verifier); >} >TCN_IMPLEMENT_CALL(jboolean, SSLContext, setSessionIdContext)(TCN_STDARGS, jlong ctx, jbyteArray sidCtx) >{ > UNREFERENCED_STDARGS; > UNREFERENCED(ctx); > UNREFERENCED(sidCtx); > return JNI_FALSE; >} >/* End of netty-tc-native add */ > >#endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 62094
: 35725