OLD | NEW |
| 1 /* |
| 2 * Copyright 2016 The Netty Project |
| 3 * |
| 4 * The Netty Project licenses this file to you under the Apache License, |
| 5 * version 2.0 (the "License"); you may not use this file except in compliance |
| 6 * with the License. You may obtain a copy of the License at: |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 * License for the specific language governing permissions and limitations |
| 14 * under the License. |
| 15 */ |
1 /* Licensed to the Apache Software Foundation (ASF) under one or more | 16 /* Licensed to the Apache Software Foundation (ASF) under one or more |
2 * contributor license agreements. See the NOTICE file distributed with | 17 * contributor license agreements. See the NOTICE file distributed with |
3 * this work for additional information regarding copyright ownership. | 18 * this work for additional information regarding copyright ownership. |
4 * The ASF licenses this file to You under the Apache License, Version 2.0 | 19 * The ASF licenses this file to You under the Apache License, Version 2.0 |
5 * (the "License"); you may not use this file except in compliance with | 20 * (the "License"); you may not use this file except in compliance with |
6 * the License. You may obtain a copy of the License at | 21 * the License. You may obtain a copy of the License at |
7 * | 22 * |
8 * http://www.apache.org/licenses/LICENSE-2.0 | 23 * http://www.apache.org/licenses/LICENSE-2.0 |
9 * | 24 * |
10 * Unless required by applicable law or agreed to in writing, software | 25 * Unless required by applicable law or agreed to in writing, software |
11 * distributed under the License is distributed on an "AS IS" BASIS, | 26 * distributed under the License is distributed on an "AS IS" BASIS, |
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 * See the License for the specific language governing permissions and | 28 * See the License for the specific language governing permissions and |
14 * limitations under the License. | 29 * limitations under the License. |
15 */ | 30 */ |
16 | 31 |
17 /** SSL Context wrapper | |
18 * | |
19 * @author Mladen Turk | |
20 * @version $Id: sslcontext.c 1649733 2015-01-06 04:42:24Z billbarker $ | |
21 */ | |
22 | |
23 #include "tcn.h" | 32 #include "tcn.h" |
24 | 33 |
25 #include "apr_file_io.h" | |
26 #include "apr_thread_mutex.h" | |
27 #include "apr_thread_rwlock.h" | 34 #include "apr_thread_rwlock.h" |
28 #include "apr_poll.h" | 35 #include "apr_atomic.h" |
29 | 36 |
30 #ifdef HAVE_OPENSSL | |
31 #include "ssl_private.h" | 37 #include "ssl_private.h" |
| 38 #include <stdint.h> |
32 | 39 |
33 static jclass byteArrayClass; | 40 extern apr_pool_t *tcn_global_pool; |
34 | 41 |
35 static apr_status_t ssl_context_cleanup(void *data) | 42 static apr_status_t ssl_context_cleanup(void *data) |
36 { | 43 { |
37 tcn_ssl_ctxt_t *c = (tcn_ssl_ctxt_t *)data; | 44 tcn_ssl_ctxt_t *c = (tcn_ssl_ctxt_t *)data; |
38 JNIEnv *e; | 45 JNIEnv *e; |
39 | 46 |
40 if (c) { | 47 if (c) { |
41 int i; | 48 SSL_CTX_free(c->ctx); // this function is safe to call with NULL |
42 if (c->crl) | |
43 X509_STORE_free(c->crl); | |
44 c->crl = NULL; | |
45 if (c->ctx) | |
46 SSL_CTX_free(c->ctx); | |
47 c->ctx = NULL; | 49 c->ctx = NULL; |
48 for (i = 0; i < SSL_AIDX_MAX; i++) { | |
49 if (c->certs[i]) { | |
50 X509_free(c->certs[i]); | |
51 c->certs[i] = NULL; | |
52 } | |
53 if (c->keys[i]) { | |
54 EVP_PKEY_free(c->keys[i]); | |
55 c->keys[i] = NULL; | |
56 } | |
57 } | |
58 if (c->bio_is) { | |
59 SSL_BIO_close(c->bio_is); | |
60 c->bio_is = NULL; | |
61 } | |
62 if (c->bio_os) { | |
63 SSL_BIO_close(c->bio_os); | |
64 c->bio_os = NULL; | |
65 } | |
66 | 50 |
67 if (c->verifier) { | 51 if (c->verifier != NULL) { |
68 tcn_get_java_env(&e); | 52 tcn_get_java_env(&e); |
69 (*e)->DeleteGlobalRef(e, c->verifier); | 53 (*e)->DeleteGlobalRef(e, c->verifier); |
70 c->verifier = NULL; | 54 c->verifier = NULL; |
71 } | 55 } |
72 c->verifier_method = NULL; | 56 c->verifier_method = NULL; |
73 | 57 |
74 if (c->next_proto_data) { | 58 if (c->cert_requested_callback != NULL) { |
| 59 tcn_get_java_env(&e); |
| 60 (*e)->DeleteGlobalRef(e, c->cert_requested_callback); |
| 61 c->cert_requested_callback = NULL; |
| 62 } |
| 63 c->cert_requested_callback_method = NULL; |
| 64 |
| 65 if (c->next_proto_data != NULL) { |
75 free(c->next_proto_data); | 66 free(c->next_proto_data); |
76 c->next_proto_data = NULL; | 67 c->next_proto_data = NULL; |
77 } | 68 } |
78 c->next_proto_len = 0; | 69 c->next_proto_len = 0; |
79 | 70 |
80 if (c->alpn_proto_data) { | 71 if (c->alpn_proto_data != NULL) { |
81 free(c->alpn_proto_data); | 72 free(c->alpn_proto_data); |
82 c->alpn_proto_data = NULL; | 73 c->alpn_proto_data = NULL; |
83 } | 74 } |
84 c->alpn_proto_len = 0; | 75 c->alpn_proto_len = 0; |
85 | 76 |
86 apr_thread_rwlock_destroy(c->mutex); | 77 apr_thread_rwlock_destroy(c->mutex); |
87 | 78 |
88 if (c->ticket_keys) { | 79 if (c->ticket_keys != NULL) { |
89 free(c->ticket_keys); | 80 free(c->ticket_keys); |
90 c->ticket_keys = NULL; | 81 c->ticket_keys = NULL; |
91 } | 82 } |
92 c->ticket_keys_len = 0; | 83 c->ticket_keys_len = 0; |
| 84 |
| 85 if (c->password != NULL) { |
| 86 free(c->password); |
| 87 c->password = NULL; |
| 88 } |
93 } | 89 } |
94 return APR_SUCCESS; | 90 return APR_SUCCESS; |
95 } | 91 } |
96 | 92 |
97 /* Initialize server context */ | 93 /* Initialize server context */ |
98 TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jlong pool, | 94 TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jint protocol, jint mod
e) |
99 jint protocol, jint mode) | |
100 { | 95 { |
101 apr_pool_t *p = J2P(pool, apr_pool_t *); | 96 apr_pool_t *p = NULL; |
102 tcn_ssl_ctxt_t *c = NULL; | 97 tcn_ssl_ctxt_t *c = NULL; |
103 SSL_CTX *ctx = NULL; | 98 SSL_CTX *ctx = NULL; |
104 jclass clazz; | |
105 | 99 |
106 UNREFERENCED(o); | 100 UNREFERENCED(o); |
107 | 101 |
108 if (protocol == SSL_PROTOCOL_TLSV1_2) { | 102 switch (protocol) { |
109 #ifdef SSL_OP_NO_TLSv1_2 | 103 case SSL_PROTOCOL_TLS: |
| 104 case SSL_PROTOCOL_ALL: |
| 105 if (mode == SSL_MODE_CLIENT) |
| 106 ctx = SSL_CTX_new(SSLv23_client_method()); |
| 107 else if (mode == SSL_MODE_SERVER) |
| 108 ctx = SSL_CTX_new(SSLv23_server_method()); |
| 109 else |
| 110 ctx = SSL_CTX_new(SSLv23_method()); |
| 111 break; |
| 112 case SSL_PROTOCOL_TLSV1_2: |
| 113 #ifndef OPENSSL_NO_TLS1 |
110 if (mode == SSL_MODE_CLIENT) | 114 if (mode == SSL_MODE_CLIENT) |
111 ctx = SSL_CTX_new(TLSv1_2_client_method()); | 115 ctx = SSL_CTX_new(TLSv1_2_client_method()); |
112 else if (mode == SSL_MODE_SERVER) | 116 else if (mode == SSL_MODE_SERVER) |
113 ctx = SSL_CTX_new(TLSv1_2_server_method()); | 117 ctx = SSL_CTX_new(TLSv1_2_server_method()); |
114 else | 118 else |
115 ctx = SSL_CTX_new(TLSv1_2_method()); | 119 ctx = SSL_CTX_new(TLSv1_2_method()); |
116 #endif | 120 #endif |
117 } else if (protocol == SSL_PROTOCOL_TLSV1_1) { | 121 break; |
118 #ifdef SSL_OP_NO_TLSv1_1 | 122 case SSL_PROTOCOL_TLSV1_1: |
| 123 #ifndef OPENSSL_NO_TLS1 |
119 if (mode == SSL_MODE_CLIENT) | 124 if (mode == SSL_MODE_CLIENT) |
120 ctx = SSL_CTX_new(TLSv1_1_client_method()); | 125 ctx = SSL_CTX_new(TLSv1_1_client_method()); |
121 else if (mode == SSL_MODE_SERVER) | 126 else if (mode == SSL_MODE_SERVER) |
122 ctx = SSL_CTX_new(TLSv1_1_server_method()); | 127 ctx = SSL_CTX_new(TLSv1_1_server_method()); |
123 else | 128 else |
124 ctx = SSL_CTX_new(TLSv1_1_method()); | 129 ctx = SSL_CTX_new(TLSv1_1_method()); |
125 #endif | 130 #endif |
126 } else if (protocol == SSL_PROTOCOL_TLSV1) { | 131 break; |
| 132 case SSL_PROTOCOL_TLSV1: |
| 133 #ifndef OPENSSL_NO_TLS1 |
127 if (mode == SSL_MODE_CLIENT) | 134 if (mode == SSL_MODE_CLIENT) |
128 ctx = SSL_CTX_new(TLSv1_client_method()); | 135 ctx = SSL_CTX_new(TLSv1_client_method()); |
129 else if (mode == SSL_MODE_SERVER) | 136 else if (mode == SSL_MODE_SERVER) |
130 ctx = SSL_CTX_new(TLSv1_server_method()); | 137 ctx = SSL_CTX_new(TLSv1_server_method()); |
131 else | 138 else |
132 ctx = SSL_CTX_new(TLSv1_method()); | 139 ctx = SSL_CTX_new(TLSv1_method()); |
| 140 #endif |
| 141 break; |
| 142 case SSL_PROTOCOL_SSLV3: |
133 #ifndef OPENSSL_NO_SSL3 | 143 #ifndef OPENSSL_NO_SSL3 |
134 } else if (protocol == SSL_PROTOCOL_SSLV3) { | |
135 if (mode == SSL_MODE_CLIENT) | 144 if (mode == SSL_MODE_CLIENT) |
136 ctx = SSL_CTX_new(SSLv3_client_method()); | 145 ctx = SSL_CTX_new(SSLv3_client_method()); |
137 else if (mode == SSL_MODE_SERVER) | 146 else if (mode == SSL_MODE_SERVER) |
138 ctx = SSL_CTX_new(SSLv3_server_method()); | 147 ctx = SSL_CTX_new(SSLv3_server_method()); |
139 else | 148 else |
140 ctx = SSL_CTX_new(SSLv3_method()); | 149 ctx = SSL_CTX_new(SSLv3_method()); |
141 #endif | 150 #endif |
| 151 break; |
| 152 case SSL_PROTOCOL_SSLV2: |
142 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_NO_SSL2) | 153 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_NO_SSL2) |
143 } else if (protocol == SSL_PROTOCOL_SSLV2) { | |
144 if (mode == SSL_MODE_CLIENT) | 154 if (mode == SSL_MODE_CLIENT) |
145 ctx = SSL_CTX_new(SSLv2_client_method()); | 155 ctx = SSL_CTX_new(SSLv2_client_method()); |
146 else if (mode == SSL_MODE_SERVER) | 156 else if (mode == SSL_MODE_SERVER) |
147 ctx = SSL_CTX_new(SSLv2_server_method()); | 157 ctx = SSL_CTX_new(SSLv2_server_method()); |
148 else | 158 else |
149 ctx = SSL_CTX_new(SSLv2_method()); | 159 ctx = SSL_CTX_new(SSLv2_method()); |
150 #endif | 160 #endif |
151 #ifndef SSL_OP_NO_TLSv1_2 | 161 break; |
152 } else if (protocol & SSL_PROTOCOL_TLSV1_2) { | 162 default: |
153 /* requested but not supported */ | 163 // Try to give the user the highest supported protocol. |
| 164 #ifndef OPENSSL_NO_TLS1 |
| 165 if (protocol & SSL_PROTOCOL_TLSV1_2) { |
| 166 if (mode == SSL_MODE_CLIENT) |
| 167 ctx = SSL_CTX_new(TLSv1_2_client_method()); |
| 168 else if (mode == SSL_MODE_SERVER) |
| 169 ctx = SSL_CTX_new(TLSv1_2_server_method()); |
| 170 else |
| 171 ctx = SSL_CTX_new(TLSv1_2_method()); |
| 172 break; |
| 173 } else if (protocol & SSL_PROTOCOL_TLSV1_1) { |
| 174 if (mode == SSL_MODE_CLIENT) |
| 175 ctx = SSL_CTX_new(TLSv1_1_client_method()); |
| 176 else if (mode == SSL_MODE_SERVER) |
| 177 ctx = SSL_CTX_new(TLSv1_1_server_method()); |
| 178 else |
| 179 ctx = SSL_CTX_new(TLSv1_1_method()); |
| 180 break; |
| 181 } else if (protocol & SSL_PROTOCOL_TLSV1) { |
| 182 if (mode == SSL_MODE_CLIENT) |
| 183 ctx = SSL_CTX_new(TLSv1_client_method()); |
| 184 else if (mode == SSL_MODE_SERVER) |
| 185 ctx = SSL_CTX_new(TLSv1_server_method()); |
| 186 else |
| 187 ctx = SSL_CTX_new(TLSv1_method()); |
| 188 break; |
| 189 } |
154 #endif | 190 #endif |
155 #ifndef SSL_OP_NO_TLSv1_1 | 191 #ifndef OPENSSL_NO_SSL3 |
156 } else if (protocol & SSL_PROTOCOL_TLSV1_1) { | 192 if (protocol & SSL_PROTOCOL_SSLV3) { |
157 /* requested but not supported */ | 193 if (mode == SSL_MODE_CLIENT) |
| 194 ctx = SSL_CTX_new(SSLv3_client_method()); |
| 195 else if (mode == SSL_MODE_SERVER) |
| 196 ctx = SSL_CTX_new(SSLv3_server_method()); |
| 197 else |
| 198 ctx = SSL_CTX_new(SSLv3_method()); |
| 199 break; |
| 200 } |
158 #endif | 201 #endif |
159 } else { | 202 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_NO_SSL2) |
160 if (mode == SSL_MODE_CLIENT) | 203 if (protocol & SSL_PROTOCOL_SSLV2) { |
161 ctx = SSL_CTX_new(SSLv23_client_method()); | 204 if (mode == SSL_MODE_CLIENT) |
162 else if (mode == SSL_MODE_SERVER) | 205 ctx = SSL_CTX_new(SSLv2_client_method()); |
163 ctx = SSL_CTX_new(SSLv23_server_method()); | 206 else if (mode == SSL_MODE_SERVER) |
164 else | 207 ctx = SSL_CTX_new(SSLv2_server_method()); |
165 ctx = SSL_CTX_new(SSLv23_method()); | 208 else |
| 209 ctx = SSL_CTX_new(SSLv2_method()); |
| 210 break; |
| 211 } |
| 212 #endif |
| 213 tcn_Throw(e, "Unsupported SSL protocol (%d)", protocol); |
| 214 goto cleanup; |
166 } | 215 } |
167 | 216 |
168 if (!ctx) { | 217 if (ctx == NULL) { |
169 char err[256]; | 218 char err[256]; |
170 ERR_error_string(ERR_get_error(), err); | 219 ERR_error_string(ERR_get_error(), err); |
171 tcn_Throw(e, "Invalid Server SSL Protocol (%s)", err); | 220 tcn_Throw(e, "Failed to initialize SSL_CTX (%s)", err); |
172 goto init_failed; | 221 goto cleanup; |
173 } | 222 } |
| 223 |
| 224 TCN_THROW_IF_ERR(apr_pool_create(&p, tcn_global_pool), p); |
| 225 |
174 if ((c = apr_pcalloc(p, sizeof(tcn_ssl_ctxt_t))) == NULL) { | 226 if ((c = apr_pcalloc(p, sizeof(tcn_ssl_ctxt_t))) == NULL) { |
175 tcn_ThrowAPRException(e, apr_get_os_error()); | 227 tcn_ThrowAPRException(e, apr_get_os_error()); |
176 goto init_failed; | 228 goto cleanup; |
177 } | 229 } |
178 | 230 |
179 c->protocol = protocol; | 231 c->protocol = protocol; |
180 c->mode = mode; | 232 c->mode = mode; |
181 c->ctx = ctx; | 233 c->ctx = ctx; |
182 c->pool = p; | 234 c->pool = p; |
183 c->bio_os = NULL; | |
184 SSL_CTX_set_options(c->ctx, SSL_OP_ALL); | |
185 if (!(protocol & SSL_PROTOCOL_SSLV2)) | 235 if (!(protocol & SSL_PROTOCOL_SSLV2)) |
186 SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv2); | 236 SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv2); |
187 if (!(protocol & SSL_PROTOCOL_SSLV3)) | 237 if (!(protocol & SSL_PROTOCOL_SSLV3)) |
188 SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv3); | 238 SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv3); |
189 if (!(protocol & SSL_PROTOCOL_TLSV1)) | 239 if (!(protocol & SSL_PROTOCOL_TLSV1)) |
190 SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1); | 240 SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1); |
191 #ifdef SSL_OP_NO_TLSv1_1 | 241 #ifdef SSL_OP_NO_TLSv1_1 |
192 if (!(protocol & SSL_PROTOCOL_TLSV1_1)) | 242 if (!(protocol & SSL_PROTOCOL_TLSV1_1)) |
193 SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1_1); | 243 SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1_1); |
194 #endif | 244 #endif |
195 #ifdef SSL_OP_NO_TLSv1_2 | 245 #ifdef SSL_OP_NO_TLSv1_2 |
196 if (!(protocol & SSL_PROTOCOL_TLSV1_2)) | 246 if (!(protocol & SSL_PROTOCOL_TLSV1_2)) |
197 SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1_2); | 247 SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1_2); |
198 #endif | 248 #endif |
199 /* | 249 /* |
200 * Configure additional context ingredients | 250 * Configure additional context ingredients |
201 */ | 251 */ |
202 SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_DH_USE); | 252 SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_DH_USE); |
203 #ifdef HAVE_ECC | 253 #ifdef HAVE_ECC |
204 SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_ECDH_USE); | 254 SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_ECDH_USE); |
205 #endif | 255 #endif |
206 | 256 |
207 #ifdef SSL_OP_NO_COMPRESSION | |
208 SSL_CTX_set_options(c->ctx, SSL_OP_NO_COMPRESSION); | 257 SSL_CTX_set_options(c->ctx, SSL_OP_NO_COMPRESSION); |
209 #else | |
210 #error "SSL_OP_NO_COMPRESSION not supported in your version of OpenSSL" | |
211 #endif | |
212 | 258 |
213 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | |
214 /* | 259 /* |
215 * Disallow a session from being resumed during a renegotiation, | 260 * Disallow a session from being resumed during a renegotiation, |
216 * so that an acceptable cipher suite can be negotiated. | 261 * so that an acceptable cipher suite can be negotiated. |
217 */ | 262 */ |
218 SSL_CTX_set_options(c->ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); | 263 SSL_CTX_set_options(c->ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); |
219 #else | 264 /** |
220 #error "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION not supported in your vers
ion of OpenSSL" | 265 * These options may be set by default but can be dangerous in practice [1]. |
221 #endif | 266 * [1] https://www.openssl.org/docs/man1.0.1/ssl/SSL_CTX_set_options.html |
| 267 */ |
| 268 SSL_CTX_clear_options(c->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | SSL
_OP_LEGACY_SERVER_CONNECT); |
222 | 269 |
223 #ifdef SSL_MODE_RELEASE_BUFFERS | |
224 /* Release idle buffers to the SSL_CTX free list */ | 270 /* Release idle buffers to the SSL_CTX free list */ |
225 SSL_CTX_set_mode(c->ctx, SSL_MODE_RELEASE_BUFFERS); | 271 SSL_CTX_set_mode(c->ctx, SSL_MODE_RELEASE_BUFFERS); |
226 #else | 272 |
227 #error "SSL_MODE_RELEASE_BUFFERS not supported in your version of OpenSSL" | |
228 #endif | |
229 /* Default session context id and cache size */ | 273 /* Default session context id and cache size */ |
230 SSL_CTX_sess_set_cache_size(c->ctx, SSL_DEFAULT_CACHE_SIZE); | 274 SSL_CTX_sess_set_cache_size(c->ctx, SSL_DEFAULT_CACHE_SIZE); |
231 | 275 |
232 /* Session cache is disabled by default */ | 276 /* Session cache is disabled by default */ |
233 SSL_CTX_set_session_cache_mode(c->ctx, SSL_SESS_CACHE_OFF); | 277 SSL_CTX_set_session_cache_mode(c->ctx, SSL_SESS_CACHE_OFF); |
234 /* Longer session timeout */ | 278 /* Longer session timeout */ |
235 SSL_CTX_set_timeout(c->ctx, 14400); | 279 SSL_CTX_set_timeout(c->ctx, 14400); |
236 EVP_Digest((const unsigned char *)SSL_DEFAULT_VHOST_NAME, | 280 EVP_Digest((const unsigned char *)SSL_DEFAULT_VHOST_NAME, |
237 (unsigned long)((sizeof SSL_DEFAULT_VHOST_NAME) - 1), | 281 (unsigned long)((sizeof SSL_DEFAULT_VHOST_NAME) - 1), |
238 &(c->context_id[0]), NULL, EVP_sha1(), NULL); | 282 &(c->context_id[0]), NULL, EVP_sha1(), NULL); |
239 if (mode) { | 283 if (mode) { |
240 #ifdef HAVE_ECC | 284 #ifdef HAVE_ECC |
241 /* Set default (nistp256) elliptic curve for ephemeral ECDH keys */ | 285 /* Set default (nistp256) elliptic curve for ephemeral ECDH keys */ |
242 EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); | 286 EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); |
243 SSL_CTX_set_tmp_ecdh(c->ctx, ecdh); | 287 SSL_CTX_set_tmp_ecdh(c->ctx, ecdh); |
244 EC_KEY_free(ecdh); | 288 EC_KEY_free(ecdh); |
245 #endif | 289 #endif |
246 | 290 |
247 // This method should not be used when using libressl as it will result in | |
248 // error:14085042:SSL routines:SSL3_CTX_CTRL:called a function you should not ca
ll | |
249 // | |
250 // See also http://forum.nginx.org/read.php?2,256381,257336#msg-257336 | |
251 #ifndef LIBRESSL_VERSION_NUMBER | |
252 SSL_CTX_set_tmp_rsa_callback(c->ctx, SSL_callback_tmp_RSA); | |
253 #endif | |
254 SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH); | 291 SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH); |
255 } | 292 } |
256 /* Set default Certificate verification level | 293 |
257 * and depth for the Client Authentication | 294 // Default depth is 100 and disabled according to https://www.openssl.org/do
cs/man1.0.2/ssl/SSL_set_verify.html. |
258 */ | 295 c->verify_config.verify_depth = 100; |
259 c->verify_depth = 1; | 296 c->verify_config.verify_mode = SSL_CVERIFY_NONE; |
260 c->verify_mode = SSL_CVERIFY_UNSET; | |
261 c->shutdown_type = SSL_SHUTDOWN_TYPE_UNSET; | |
262 | 297 |
263 /* Set default password callback */ | 298 /* Set default password callback */ |
264 SSL_CTX_set_default_passwd_cb(c->ctx, (pem_password_cb *)SSL_password_callba
ck); | 299 SSL_CTX_set_default_passwd_cb(c->ctx, (pem_password_cb *)SSL_password_callba
ck); |
265 SSL_CTX_set_default_passwd_cb_userdata(c->ctx, (void *)(&tcn_password_callba
ck)); | 300 SSL_CTX_set_default_passwd_cb_userdata(c->ctx, (void *) c->password); |
266 SSL_CTX_set_info_callback(c->ctx, SSL_callback_handshake); | |
267 | 301 |
268 apr_thread_rwlock_create(&c->mutex, p); | 302 apr_thread_rwlock_create(&c->mutex, p); |
269 /* | 303 /* |
270 * Let us cleanup the ssl context when the pool is destroyed | 304 * Let us cleanup the ssl context when the pool is destroyed |
271 */ | 305 */ |
272 apr_pool_cleanup_register(p, (const void *)c, | 306 apr_pool_cleanup_register(p, (const void *)c, |
273 ssl_context_cleanup, | 307 ssl_context_cleanup, |
274 apr_pool_cleanup_null); | 308 apr_pool_cleanup_null); |
275 | 309 |
276 | |
277 // Cache the byte[].class for performance reasons | |
278 clazz = (*e)->FindClass(e, "[B"); | |
279 byteArrayClass = (jclass) (*e)->NewGlobalRef(e, clazz); | |
280 | |
281 return P2J(c); | 310 return P2J(c); |
282 init_failed: | 311 cleanup: |
| 312 if (p != NULL) { |
| 313 apr_pool_destroy(p); |
| 314 } |
| 315 SSL_CTX_free(ctx); // this function is safe to call with NULL. |
283 return 0; | 316 return 0; |
284 } | 317 } |
285 | 318 |
286 TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx) | 319 TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx) |
287 { | 320 { |
288 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 321 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
289 UNREFERENCED_STDARGS; | 322 UNREFERENCED_STDARGS; |
290 TCN_ASSERT(ctx != 0); | 323 TCN_ASSERT(ctx != 0); |
291 /* Run and destroy the cleanup callback */ | 324 /* Run and destroy the cleanup callback */ |
292 return apr_pool_cleanup_run(c->pool, c, ssl_context_cleanup); | 325 int result = apr_pool_cleanup_run(c->pool, c, ssl_context_cleanup); |
| 326 apr_pool_destroy(c->pool); |
| 327 return result; |
293 } | 328 } |
294 | 329 |
295 TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx, | 330 TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx, |
296 jstring id) | 331 jstring id) |
297 { | 332 { |
298 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 333 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
299 TCN_ALLOC_CSTRING(id); | 334 TCN_ALLOC_CSTRING(id); |
300 | 335 |
301 TCN_ASSERT(ctx != 0); | 336 TCN_ASSERT(ctx != 0); |
302 UNREFERENCED(o); | 337 UNREFERENCED(o); |
303 if (J2S(id)) { | 338 if (J2S(id)) { |
304 EVP_Digest((const unsigned char *)J2S(id), | 339 EVP_Digest((const unsigned char *)J2S(id), |
305 (unsigned long)strlen(J2S(id)), | 340 (unsigned long)strlen(J2S(id)), |
306 &(c->context_id[0]), NULL, EVP_sha1(), NULL); | 341 &(c->context_id[0]), NULL, EVP_sha1(), NULL); |
307 } | 342 } |
308 TCN_FREE_CSTRING(id); | 343 TCN_FREE_CSTRING(id); |
309 } | 344 } |
310 | 345 |
311 TCN_IMPLEMENT_CALL(void, SSLContext, setBIO)(TCN_STDARGS, jlong ctx, | |
312 jlong bio, jint dir) | |
313 { | |
314 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | |
315 BIO *bio_handle = J2P(bio, BIO *); | |
316 | |
317 UNREFERENCED_STDARGS; | |
318 TCN_ASSERT(ctx != 0); | |
319 if (dir == 0) { | |
320 if (c->bio_os && c->bio_os != bio_handle) | |
321 SSL_BIO_close(c->bio_os); | |
322 c->bio_os = bio_handle; | |
323 } | |
324 else if (dir == 1) { | |
325 if (c->bio_is && c->bio_is != bio_handle) | |
326 SSL_BIO_close(c->bio_is); | |
327 c->bio_is = bio_handle; | |
328 } | |
329 else | |
330 return; | |
331 SSL_BIO_doref(bio_handle); | |
332 } | |
333 | |
334 TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx, | 346 TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx, |
335 jint opt) | 347 jint opt) |
336 { | 348 { |
337 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 349 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
338 | 350 |
339 UNREFERENCED_STDARGS; | 351 UNREFERENCED_STDARGS; |
340 TCN_ASSERT(ctx != 0); | 352 TCN_ASSERT(ctx != 0); |
341 #ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | 353 |
342 /* Clear the flag if not supported */ | |
343 if (opt & 0x00040000) | |
344 opt &= ~0x00040000; | |
345 #endif | |
346 SSL_CTX_set_options(c->ctx, opt); | 354 SSL_CTX_set_options(c->ctx, opt); |
347 } | 355 } |
348 | 356 |
349 TCN_IMPLEMENT_CALL(jint, SSLContext, getOptions)(TCN_STDARGS, jlong ctx) | 357 TCN_IMPLEMENT_CALL(jint, SSLContext, getOptions)(TCN_STDARGS, jlong ctx) |
350 { | 358 { |
351 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 359 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
352 | 360 |
353 UNREFERENCED_STDARGS; | 361 UNREFERENCED_STDARGS; |
354 TCN_ASSERT(ctx != 0); | 362 TCN_ASSERT(ctx != 0); |
355 | 363 |
356 return SSL_CTX_get_options(c->ctx); | 364 return SSL_CTX_get_options(c->ctx); |
357 } | 365 } |
358 | 366 |
359 TCN_IMPLEMENT_CALL(void, SSLContext, clearOptions)(TCN_STDARGS, jlong ctx, | 367 TCN_IMPLEMENT_CALL(void, SSLContext, clearOptions)(TCN_STDARGS, jlong ctx, |
360 jint opt) | 368 jint opt) |
361 { | 369 { |
362 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 370 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
363 | 371 |
364 UNREFERENCED_STDARGS; | 372 UNREFERENCED_STDARGS; |
365 TCN_ASSERT(ctx != 0); | 373 TCN_ASSERT(ctx != 0); |
366 SSL_CTX_clear_options(c->ctx, opt); | 374 SSL_CTX_clear_options(c->ctx, opt); |
367 } | 375 } |
368 | 376 |
369 TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx, | |
370 jboolean mode) | |
371 { | |
372 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | |
373 | |
374 UNREFERENCED_STDARGS; | |
375 TCN_ASSERT(ctx != 0); | |
376 SSL_CTX_set_quiet_shutdown(c->ctx, mode ? 1 : 0); | |
377 } | |
378 | |
379 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx, | 377 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx, |
380 jstring ciphers) | 378 jstring ciphers) |
381 { | 379 { |
382 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 380 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
383 TCN_ALLOC_CSTRING(ciphers); | 381 TCN_ALLOC_CSTRING(ciphers); |
384 jboolean rv = JNI_TRUE; | 382 jboolean rv = JNI_TRUE; |
385 | 383 |
386 UNREFERENCED(o); | 384 UNREFERENCED(o); |
387 TCN_ASSERT(ctx != 0); | 385 TCN_ASSERT(ctx != 0); |
388 if (!J2S(ciphers)) | 386 if (!J2S(ciphers)) |
389 return JNI_FALSE; | 387 return JNI_FALSE; |
390 | 388 |
391 if (!SSL_CTX_set_cipher_list(c->ctx, J2S(ciphers))) { | 389 if (!SSL_CTX_set_cipher_list(c->ctx, J2S(ciphers))) { |
392 char err[256]; | 390 char err[256]; |
393 ERR_error_string(ERR_get_error(), err); | 391 ERR_error_string(ERR_get_error(), err); |
394 tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err); | 392 tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err); |
395 rv = JNI_FALSE; | 393 rv = JNI_FALSE; |
396 } | 394 } |
397 TCN_FREE_CSTRING(ciphers); | 395 TCN_FREE_CSTRING(ciphers); |
398 return rv; | 396 return rv; |
399 } | 397 } |
400 | 398 |
401 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCARevocation)(TCN_STDARGS, jlong ctx
, | |
402 jstring file, | |
403 jstring path) | |
404 { | |
405 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | |
406 TCN_ALLOC_CSTRING(file); | |
407 TCN_ALLOC_CSTRING(path); | |
408 jboolean rv = JNI_FALSE; | |
409 X509_LOOKUP *lookup; | |
410 char err[256]; | |
411 | |
412 UNREFERENCED(o); | |
413 TCN_ASSERT(ctx != 0); | |
414 if (J2S(file) == NULL && J2S(path) == NULL) | |
415 return JNI_FALSE; | |
416 | |
417 if (!c->crl) { | |
418 if ((c->crl = X509_STORE_new()) == NULL) | |
419 goto cleanup; | |
420 } | |
421 if (J2S(file)) { | |
422 lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_file()); | |
423 if (lookup == NULL) { | |
424 ERR_error_string(ERR_get_error(), err); | |
425 X509_STORE_free(c->crl); | |
426 c->crl = NULL; | |
427 tcn_Throw(e, "Lookup failed for file %s (%s)", J2S(file), err); | |
428 goto cleanup; | |
429 } | |
430 X509_LOOKUP_load_file(lookup, J2S(file), X509_FILETYPE_PEM); | |
431 } | |
432 if (J2S(path)) { | |
433 lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_hash_dir()); | |
434 if (lookup == NULL) { | |
435 ERR_error_string(ERR_get_error(), err); | |
436 X509_STORE_free(c->crl); | |
437 c->crl = NULL; | |
438 tcn_Throw(e, "Lookup failed for path %s (%s)", J2S(file), err); | |
439 goto cleanup; | |
440 } | |
441 X509_LOOKUP_add_dir(lookup, J2S(path), X509_FILETYPE_PEM); | |
442 } | |
443 rv = JNI_TRUE; | |
444 cleanup: | |
445 TCN_FREE_CSTRING(file); | |
446 TCN_FREE_CSTRING(path); | |
447 return rv; | |
448 } | |
449 | |
450 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, j
long ctx, | 399 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, j
long ctx, |
451 jstring file, | 400 jstring file, |
452 jboolean skipf
irst) | 401 jboolean skipf
irst) |
453 { | 402 { |
454 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 403 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
455 jboolean rv = JNI_FALSE; | 404 jboolean rv = JNI_FALSE; |
456 TCN_ALLOC_CSTRING(file); | 405 TCN_ALLOC_CSTRING(file); |
457 | 406 |
458 UNREFERENCED(o); | 407 UNREFERENCED(o); |
459 TCN_ASSERT(ctx != 0); | 408 TCN_ASSERT(ctx != 0); |
(...skipping 15 matching lines...) Expand all Loading... |
475 UNREFERENCED(o); | 424 UNREFERENCED(o); |
476 TCN_ASSERT(ctx != 0); | 425 TCN_ASSERT(ctx != 0); |
477 if (b == NULL) | 426 if (b == NULL) |
478 return JNI_FALSE; | 427 return JNI_FALSE; |
479 if (SSL_CTX_use_certificate_chain_bio(c->ctx, b, skipfirst) > 0) { | 428 if (SSL_CTX_use_certificate_chain_bio(c->ctx, b, skipfirst) > 0) { |
480 return JNI_TRUE; | 429 return JNI_TRUE; |
481 } | 430 } |
482 return JNI_FALSE; | 431 return JNI_FALSE; |
483 } | 432 } |
484 | 433 |
485 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS, | 434 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificateBio)(TCN_STDARGS, jlong
ctx, jlong certs) |
486 jlong ctx, | |
487 jstring file, | |
488 jstring path) | |
489 { | 435 { |
490 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 436 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
491 jboolean rv = JNI_TRUE; | 437 BIO *b = J2P(certs, BIO *); |
492 TCN_ALLOC_CSTRING(file); | |
493 TCN_ALLOC_CSTRING(path); | |
494 | 438 |
495 UNREFERENCED(o); | 439 UNREFERENCED(o); |
496 TCN_ASSERT(ctx != 0); | 440 TCN_ASSERT(c != NULL); |
497 if (file == NULL && path == NULL) | |
498 return JNI_FALSE; | |
499 | 441 |
500 /* | 442 return b != NULL && c->mode != SSL_MODE_CLIENT && SSL_CTX_use_client_CA_bio(
c->ctx, b) > 0 ? JNI_TRUE : JNI_FALSE; |
501 * Configure Client Authentication details | |
502 */ | |
503 if (!SSL_CTX_load_verify_locations(c->ctx, | |
504 J2S(file), J2S(path))) { | |
505 char err[256]; | |
506 ERR_error_string(ERR_get_error(), err); | |
507 tcn_Throw(e, "Unable to configure locations " | |
508 "for client authentication (%s)", err); | |
509 rv = JNI_FALSE; | |
510 goto cleanup; | |
511 } | |
512 c->store = SSL_CTX_get_cert_store(c->ctx); | |
513 if (c->mode) { | |
514 STACK_OF(X509_NAME) *ca_certs; | |
515 c->ca_certs++; | |
516 ca_certs = SSL_CTX_get_client_CA_list(c->ctx); | |
517 if (ca_certs == NULL) { | |
518 SSL_load_client_CA_file(J2S(file)); | |
519 if (ca_certs != NULL) | |
520 SSL_CTX_set_client_CA_list(c->ctx, ca_certs); | |
521 } | |
522 else { | |
523 if (!SSL_add_file_cert_subjects_to_stack(ca_certs, J2S(file))) | |
524 ca_certs = NULL; | |
525 } | |
526 if (ca_certs == NULL && c->verify_mode == SSL_CVERIFY_REQUIRE) { | |
527 /* | |
528 * Give a warning when no CAs were configured but client authenticat
ion | |
529 * should take place. This cannot work. | |
530 */ | |
531 if (c->bio_os) { | |
532 BIO_printf(c->bio_os, | |
533 "[WARN] Oops, you want to request client " | |
534 "authentication, but no CAs are known for " | |
535 "verification!?"); | |
536 } | |
537 else { | |
538 fprintf(stderr, | |
539 "[WARN] Oops, you want to request client " | |
540 "authentication, but no CAs are known for " | |
541 "verification!?"); | |
542 } | |
543 } | |
544 } | |
545 cleanup: | |
546 TCN_FREE_CSTRING(file); | |
547 TCN_FREE_CSTRING(path); | |
548 return rv; | |
549 } | 443 } |
550 | 444 |
551 TCN_IMPLEMENT_CALL(void, SSLContext, setTmpDH)(TCN_STDARGS, jlong ctx, | 445 TCN_IMPLEMENT_CALL(void, SSLContext, setTmpDHLength)(TCN_STDARGS, jlong ctx, jin
t length) |
552 jstring file) | |
553 { | 446 { |
554 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 447 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
555 BIO *bio = NULL; | |
556 DH *dh = NULL; | |
557 TCN_ALLOC_CSTRING(file); | |
558 UNREFERENCED(o); | 448 UNREFERENCED(o); |
559 TCN_ASSERT(ctx != 0); | 449 TCN_ASSERT(ctx != 0); |
560 TCN_ASSERT(file); | 450 switch (length) { |
561 | 451 case 512: |
562 if (!J2S(file)) { | 452 SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH_512); |
563 tcn_Throw(e, "Error while configuring DH: no dh param file given"); | 453 return; |
564 return; | 454 case 1024: |
| 455 SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH_1024); |
| 456 return; |
| 457 case 2048: |
| 458 SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH_2048); |
| 459 return; |
| 460 case 4096: |
| 461 SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH_4096); |
| 462 return; |
| 463 default: |
| 464 tcn_Throw(e, "Unsupported length %s", length); |
| 465 return; |
565 } | 466 } |
566 | |
567 bio = BIO_new_file(J2S(file), "r"); | |
568 if (!bio) { | |
569 char err[256]; | |
570 ERR_error_string(ERR_get_error(), err); | |
571 tcn_Throw(e, "Error while configuring DH using %s: %s", J2S(file), err); | |
572 TCN_FREE_CSTRING(file); | |
573 return; | |
574 } | |
575 | |
576 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); | |
577 BIO_free(bio); | |
578 if (!dh) { | |
579 char err[256]; | |
580 ERR_error_string(ERR_get_error(), err); | |
581 tcn_Throw(e, "Error while configuring DH: no DH parameter found in %s (%
s)", J2S(file), err); | |
582 TCN_FREE_CSTRING(file); | |
583 return; | |
584 } | |
585 | |
586 if (1 != SSL_CTX_set_tmp_dh(c->ctx, dh)) { | |
587 char err[256]; | |
588 DH_free(dh); | |
589 ERR_error_string(ERR_get_error(), err); | |
590 tcn_Throw(e, "Error while configuring DH with file %s: %s", J2S(file), e
rr); | |
591 TCN_FREE_CSTRING(file); | |
592 return; | |
593 } | |
594 | |
595 DH_free(dh); | |
596 TCN_FREE_CSTRING(file); | |
597 } | 467 } |
598 | 468 |
599 TCN_IMPLEMENT_CALL(void, SSLContext, setTmpECDHByCurveName)(TCN_STDARGS, jlong c
tx, | 469 TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx, jint lev
el, jint depth) |
600 jstring curveN
ame) | |
601 { | |
602 #ifdef HAVE_ECC | |
603 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | |
604 int i; | |
605 EC_KEY *ecdh; | |
606 TCN_ALLOC_CSTRING(curveName); | |
607 UNREFERENCED(o); | |
608 TCN_ASSERT(ctx != 0); | |
609 TCN_ASSERT(curveName); | |
610 | |
611 // First try to get curve by name | |
612 i = OBJ_sn2nid(J2S(curveName)); | |
613 if (!i) { | |
614 tcn_Throw(e, "Can't configure elliptic curve: unknown curve name %s", J2
S(curveName)); | |
615 TCN_FREE_CSTRING(curveName); | |
616 return; | |
617 } | |
618 | |
619 ecdh = EC_KEY_new_by_curve_name(i); | |
620 if (!ecdh) { | |
621 tcn_Throw(e, "Can't configure elliptic curve: unknown curve name %s", J2
S(curveName)); | |
622 TCN_FREE_CSTRING(curveName); | |
623 return; | |
624 } | |
625 | |
626 // Setting found curve to context | |
627 if (1 != SSL_CTX_set_tmp_ecdh(c->ctx, ecdh)) { | |
628 char err[256]; | |
629 EC_KEY_free(ecdh); | |
630 ERR_error_string(ERR_get_error(), err); | |
631 tcn_Throw(e, "Error while configuring elliptic curve %s: %s", J2S(curveN
ame), err); | |
632 TCN_FREE_CSTRING(curveName); | |
633 return; | |
634 } | |
635 EC_KEY_free(ecdh); | |
636 TCN_FREE_CSTRING(curveName); | |
637 #else | |
638 » tcn_Throw(e, "Cant't configure elliptic curve: unsupported by this OpenS
SL version"); | |
639 » return; | |
640 #endif | |
641 } | |
642 | |
643 TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx, | |
644 jint type) | |
645 { | 470 { |
646 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 471 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
647 | 472 |
648 UNREFERENCED_STDARGS; | 473 UNREFERENCED(o); |
649 TCN_ASSERT(ctx != 0); | 474 TCN_ASSERT(c != NULL); |
650 c->shutdown_type = type; | |
651 } | |
652 | 475 |
653 TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx, | 476 // No need to set the callback for SSL_CTX_set_verify because we override th
e default certificate verification via SSL_CTX_set_cert_verify_callback. |
654 jint level, jint depth) | 477 SSL_CTX_set_verify(c->ctx, tcn_set_verify_config(&c->verify_config, level, d
epth), NULL); |
655 { | 478 SSL_CTX_set_verify_depth(c->ctx, c->verify_config.verify_depth); |
656 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | |
657 int verify = SSL_VERIFY_NONE; | |
658 | |
659 UNREFERENCED(o); | |
660 TCN_ASSERT(ctx != 0); | |
661 c->verify_mode = level; | |
662 | |
663 if (c->verify_mode == SSL_CVERIFY_UNSET) | |
664 c->verify_mode = SSL_CVERIFY_NONE; | |
665 if (depth > 0) | |
666 c->verify_depth = depth; | |
667 /* | |
668 * Configure callbacks for SSL context | |
669 */ | |
670 if (c->verify_mode == SSL_CVERIFY_REQUIRE) | |
671 verify |= SSL_VERIFY_PEER_STRICT; | |
672 if ((c->verify_mode == SSL_CVERIFY_OPTIONAL) || | |
673 (c->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) | |
674 verify |= SSL_VERIFY_PEER; | |
675 if (!c->store) { | |
676 if (SSL_CTX_set_default_verify_paths(c->ctx)) { | |
677 c->store = SSL_CTX_get_cert_store(c->ctx); | |
678 X509_STORE_set_flags(c->store, 0); | |
679 } | |
680 else { | |
681 /* XXX: See if this is fatal */ | |
682 } | |
683 } | |
684 | |
685 SSL_CTX_set_verify(c->ctx, verify, SSL_callback_SSL_verify); | |
686 } | 479 } |
687 | 480 |
688 static EVP_PKEY *load_pem_key(tcn_ssl_ctxt_t *c, const char *file) | 481 static EVP_PKEY *load_pem_key(tcn_ssl_ctxt_t *c, const char *file) |
689 { | 482 { |
690 BIO *bio = NULL; | 483 BIO *bio = NULL; |
691 EVP_PKEY *key = NULL; | 484 EVP_PKEY *key = NULL; |
692 tcn_pass_cb_t *cb_data = c->cb_data; | |
693 int i; | |
694 | 485 |
695 if ((bio = BIO_new(BIO_s_file())) == NULL) { | 486 if ((bio = BIO_new(BIO_s_file())) == NULL) { |
696 return NULL; | 487 return NULL; |
697 } | 488 } |
698 if (BIO_read_filename(bio, file) <= 0) { | 489 if (BIO_read_filename(bio, file) <= 0) { |
699 BIO_free(bio); | 490 BIO_free(bio); |
700 return NULL; | 491 return NULL; |
701 } | 492 } |
702 if (!cb_data) | 493 |
703 cb_data = &tcn_password_callback; | 494 key = PEM_read_bio_PrivateKey(bio, NULL, (pem_password_cb *)SSL_password_cal
lback, (void *)c->password); |
704 for (i = 0; i < 3; i++) { | 495 |
705 key = PEM_read_bio_PrivateKey(bio, NULL, | |
706 (pem_password_cb *)SSL_password_callback, | |
707 (void *)cb_data); | |
708 if (key != NULL) | |
709 break; | |
710 cb_data->password[0] = '\0'; | |
711 BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); | |
712 } | |
713 BIO_free(bio); | 496 BIO_free(bio); |
714 return key; | 497 return key; |
715 } | 498 } |
716 | 499 |
717 static EVP_PKEY *load_pem_key_bio(tcn_ssl_ctxt_t *c, const BIO *bio) | |
718 { | |
719 EVP_PKEY *key = NULL; | |
720 tcn_pass_cb_t *cb_data = c->cb_data; | |
721 int i; | |
722 | |
723 if (cb_data == NULL) | |
724 cb_data = &tcn_password_callback; | |
725 for (i = 0; i < 3; i++) { | |
726 key = PEM_read_bio_PrivateKey((BIO*) bio, NULL, | |
727 (pem_password_cb *)SSL_password_callback, | |
728 (void *)cb_data); | |
729 if (key) | |
730 break; | |
731 cb_data->password[0] = '\0'; | |
732 BIO_ctrl((BIO*) bio, BIO_CTRL_RESET, 0, NULL); | |
733 } | |
734 return key; | |
735 } | |
736 | |
737 static X509 *load_pem_cert(tcn_ssl_ctxt_t *c, const char *file) | 500 static X509 *load_pem_cert(tcn_ssl_ctxt_t *c, const char *file) |
738 { | 501 { |
739 BIO *bio = NULL; | 502 BIO *bio = NULL; |
740 X509 *cert = NULL; | 503 X509 *cert = NULL; |
741 tcn_pass_cb_t *cb_data = c->cb_data; | |
742 | 504 |
743 if ((bio = BIO_new(BIO_s_file())) == NULL) { | 505 if ((bio = BIO_new(BIO_s_file())) == NULL) { |
744 return NULL; | 506 return NULL; |
745 } | 507 } |
746 if (BIO_read_filename(bio, file) <= 0) { | 508 if (BIO_read_filename(bio, file) <= 0) { |
747 BIO_free(bio); | 509 BIO_free(bio); |
748 return NULL; | 510 return NULL; |
749 } | 511 } |
750 if (!cb_data) | |
751 cb_data = &tcn_password_callback; | |
752 cert = PEM_read_bio_X509_AUX(bio, NULL, | 512 cert = PEM_read_bio_X509_AUX(bio, NULL, |
753 (pem_password_cb *)SSL_password_callback, | 513 (pem_password_cb *)SSL_password_callback, |
754 (void *)cb_data); | 514 (void *)c->password); |
755 if (cert == NULL && | 515 if (cert == NULL && |
756 (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE)) { | 516 (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE)) { |
757 ERR_clear_error(); | 517 ERR_clear_error(); |
758 BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); | 518 BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); |
759 cert = d2i_X509_bio(bio, NULL); | 519 cert = d2i_X509_bio(bio, NULL); |
760 } | 520 } |
761 BIO_free(bio); | 521 BIO_free(bio); |
762 return cert; | 522 return cert; |
763 } | 523 } |
764 | 524 |
765 static X509 *load_pem_cert_bio(tcn_ssl_ctxt_t *c, const BIO *bio) | |
766 { | |
767 X509 *cert = NULL; | |
768 tcn_pass_cb_t *cb_data = c->cb_data; | |
769 | |
770 if (cb_data == NULL) | |
771 cb_data = &tcn_password_callback; | |
772 cert = PEM_read_bio_X509_AUX((BIO*) bio, NULL, | |
773 (pem_password_cb *)SSL_password_callback, | |
774 (void *)cb_data); | |
775 if (cert == NULL && | |
776 (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE)) { | |
777 ERR_clear_error(); | |
778 BIO_ctrl((BIO*) bio, BIO_CTRL_RESET, 0, NULL); | |
779 cert = d2i_X509_bio((BIO*) bio, NULL); | |
780 } | |
781 return cert; | |
782 } | |
783 | |
784 static int ssl_load_pkcs12(tcn_ssl_ctxt_t *c, const char *file, | 525 static int ssl_load_pkcs12(tcn_ssl_ctxt_t *c, const char *file, |
785 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) | 526 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) |
786 { | 527 { |
787 const char *pass; | 528 const char *pass; |
788 char buff[PEM_BUFSIZE]; | 529 char buff[PEM_BUFSIZE]; |
789 int len, rc = 0; | 530 int len, rc = 0; |
790 PKCS12 *p12; | 531 PKCS12 *p12; |
791 BIO *in; | 532 BIO *in; |
792 tcn_pass_cb_t *cb_data = c->cb_data; | |
793 | 533 |
794 if ((in = BIO_new(BIO_s_file())) == 0) | 534 if ((in = BIO_new(BIO_s_file())) == 0) |
795 return 0; | 535 return 0; |
796 if (BIO_read_filename(in, file) <= 0) { | 536 if (BIO_read_filename(in, file) <= 0) { |
797 BIO_free(in); | 537 BIO_free(in); |
798 return 0; | 538 return 0; |
799 } | 539 } |
800 p12 = d2i_PKCS12_bio(in, 0); | 540 p12 = d2i_PKCS12_bio(in, 0); |
801 if (p12 == 0) { | 541 if (p12 == 0) { |
802 /* Error loading PKCS12 file */ | 542 /* Error loading PKCS12 file */ |
803 goto cleanup; | 543 goto cleanup; |
804 } | 544 } |
805 /* See if an empty password will do */ | 545 /* See if an empty password will do */ |
806 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, 0, 0)) { | 546 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, 0, 0)) { |
807 pass = ""; | 547 pass = ""; |
808 } | 548 } |
809 else { | 549 else { |
810 if (!cb_data) | 550 len = SSL_password_callback(buff, PEM_BUFSIZE, 0, (void *) c->password); |
811 cb_data = &tcn_password_callback; | |
812 len = SSL_password_callback(buff, PEM_BUFSIZE, 0, cb_data); | |
813 if (len < 0) { | 551 if (len < 0) { |
814 /* Passpharse callback error */ | 552 /* Passpharse callback error */ |
815 goto cleanup; | 553 goto cleanup; |
816 } | 554 } |
817 if (!PKCS12_verify_mac(p12, buff, len)) { | 555 if (!PKCS12_verify_mac(p12, buff, len)) { |
818 /* Mac verify error (wrong password?) in PKCS12 file */ | 556 /* Mac verify error (wrong password?) in PKCS12 file */ |
819 goto cleanup; | 557 goto cleanup; |
820 } | 558 } |
821 pass = buff; | 559 pass = buff; |
822 } | 560 } |
823 rc = PKCS12_parse(p12, pass, pkey, cert, ca); | 561 rc = PKCS12_parse(p12, pass, pkey, cert, ca); |
824 cleanup: | 562 cleanup: |
825 if (p12 != 0) | 563 if (p12 != 0) |
826 PKCS12_free(p12); | 564 PKCS12_free(p12); |
827 BIO_free(in); | 565 BIO_free(in); |
828 return rc; | 566 return rc; |
829 } | 567 } |
830 | 568 |
831 TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx, | 569 static void free_and_reset_pass(tcn_ssl_ctxt_t *c, char* old_password, const jbo
olean rv) { |
832 jstring file) | 570 if (!rv) { |
833 { | 571 if (c->password != NULL) { |
834 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 572 free(c->password); |
835 TCN_ALLOC_CSTRING(file); | 573 c->password = NULL; |
| 574 } |
| 575 // Restore old password |
| 576 c->password = old_password; |
| 577 } else if (old_password != NULL) { |
| 578 free(old_password); |
| 579 } |
| 580 } |
836 | 581 |
837 TCN_ASSERT(ctx != 0); | |
838 UNREFERENCED(o); | |
839 if (J2S(file)) | |
840 c->rand_file = apr_pstrdup(c->pool, J2S(file)); | |
841 TCN_FREE_CSTRING(file); | |
842 } | |
843 | 582 |
844 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx, | 583 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx, |
845 jstring cert, jstring k
ey, | 584 jstring cert, jstring k
ey, |
846 jstring password, jint
idx) | 585 jstring password) |
847 { | 586 { |
848 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 587 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
849 jboolean rv = JNI_TRUE; | 588 jboolean rv = JNI_TRUE; |
850 TCN_ALLOC_CSTRING(cert); | 589 TCN_ALLOC_CSTRING(cert); |
851 TCN_ALLOC_CSTRING(key); | 590 TCN_ALLOC_CSTRING(key); |
852 TCN_ALLOC_CSTRING(password); | 591 TCN_ALLOC_CSTRING(password); |
| 592 EVP_PKEY *pkey = NULL; |
| 593 X509 *xcert = NULL; |
853 const char *key_file, *cert_file; | 594 const char *key_file, *cert_file; |
854 const char *p; | 595 const char *p; |
| 596 char *old_password = NULL; |
855 char err[256]; | 597 char err[256]; |
856 | 598 |
857 UNREFERENCED(o); | 599 UNREFERENCED(o); |
858 TCN_ASSERT(ctx != 0); | 600 TCN_ASSERT(ctx != 0); |
859 | 601 |
860 if (idx < 0 || idx >= SSL_AIDX_MAX) { | |
861 /* TODO: Throw something */ | |
862 rv = JNI_FALSE; | |
863 goto cleanup; | |
864 } | |
865 if (J2S(password)) { | 602 if (J2S(password)) { |
866 if (!c->cb_data) | 603 old_password = c->password; |
867 c->cb_data = &tcn_password_callback; | 604 |
868 strncpy(c->cb_data->password, J2S(password), SSL_MAX_PASSWORD_LEN); | 605 c->password = strdup(cpassword); |
869 c->cb_data->password[SSL_MAX_PASSWORD_LEN-1] = '\0'; | 606 if (c->password == NULL) { |
| 607 rv = JNI_FALSE; |
| 608 goto cleanup; |
| 609 } |
870 } | 610 } |
871 key_file = J2S(key); | 611 key_file = J2S(key); |
872 cert_file = J2S(cert); | 612 cert_file = J2S(cert); |
873 if (!key_file) | 613 if (!key_file) |
874 key_file = cert_file; | 614 key_file = cert_file; |
875 if (!key_file || !cert_file) { | 615 if (!key_file || !cert_file) { |
876 tcn_Throw(e, "No Certificate file specified or invalid file format"); | 616 tcn_Throw(e, "No Certificate file specified or invalid file format"); |
877 rv = JNI_FALSE; | 617 rv = JNI_FALSE; |
878 goto cleanup; | 618 goto cleanup; |
879 } | 619 } |
880 if ((p = strrchr(cert_file, '.')) != NULL && strcmp(p, ".pkcs12") == 0) { | 620 if ((p = strrchr(cert_file, '.')) != NULL && strcmp(p, ".pkcs12") == 0) { |
881 if (!ssl_load_pkcs12(c, cert_file, &c->keys[idx], &c->certs[idx], 0)) { | 621 if (!ssl_load_pkcs12(c, cert_file, &pkey, &xcert, 0)) { |
882 ERR_error_string(ERR_get_error(), err); | 622 ERR_error_string(ERR_get_error(), err); |
883 tcn_Throw(e, "Unable to load certificate %s (%s)", | 623 tcn_Throw(e, "Unable to load certificate %s (%s)", |
884 cert_file, err); | 624 cert_file, err); |
885 rv = JNI_FALSE; | 625 rv = JNI_FALSE; |
886 goto cleanup; | 626 goto cleanup; |
887 } | 627 } |
888 } | 628 } |
889 else { | 629 else { |
890 if ((c->keys[idx] = load_pem_key(c, key_file)) == NULL) { | 630 if ((pkey = load_pem_key(c, key_file)) == NULL) { |
891 ERR_error_string(ERR_get_error(), err); | 631 ERR_error_string(ERR_get_error(), err); |
892 tcn_Throw(e, "Unable to load certificate key %s (%s)", | 632 tcn_Throw(e, "Unable to load certificate key %s (%s)", |
893 key_file, err); | 633 key_file, err); |
894 rv = JNI_FALSE; | 634 rv = JNI_FALSE; |
895 goto cleanup; | 635 goto cleanup; |
896 } | 636 } |
897 if ((c->certs[idx] = load_pem_cert(c, cert_file)) == NULL) { | 637 if ((xcert = load_pem_cert(c, cert_file)) == NULL) { |
898 ERR_error_string(ERR_get_error(), err); | 638 ERR_error_string(ERR_get_error(), err); |
899 tcn_Throw(e, "Unable to load certificate %s (%s)", | 639 tcn_Throw(e, "Unable to load certificate %s (%s)", |
900 cert_file, err); | 640 cert_file, err); |
901 rv = JNI_FALSE; | 641 rv = JNI_FALSE; |
902 goto cleanup; | 642 goto cleanup; |
903 } | 643 } |
904 } | 644 } |
905 if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) { | 645 if (SSL_CTX_use_certificate(c->ctx, xcert) <= 0) { |
906 ERR_error_string(ERR_get_error(), err); | 646 ERR_error_string(ERR_get_error(), err); |
907 tcn_Throw(e, "Error setting certificate (%s)", err); | 647 tcn_Throw(e, "Error setting certificate (%s)", err); |
908 rv = JNI_FALSE; | 648 rv = JNI_FALSE; |
909 goto cleanup; | 649 goto cleanup; |
910 } | 650 } |
911 if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) { | 651 if (SSL_CTX_use_PrivateKey(c->ctx, pkey) <= 0) { |
912 ERR_error_string(ERR_get_error(), err); | 652 ERR_error_string(ERR_get_error(), err); |
913 tcn_Throw(e, "Error setting private key (%s)", err); | 653 tcn_Throw(e, "Error setting private key (%s)", err); |
914 rv = JNI_FALSE; | 654 rv = JNI_FALSE; |
915 goto cleanup; | 655 goto cleanup; |
916 } | 656 } |
917 if (SSL_CTX_check_private_key(c->ctx) <= 0) { | 657 if (SSL_CTX_check_private_key(c->ctx) <= 0) { |
918 ERR_error_string(ERR_get_error(), err); | 658 ERR_error_string(ERR_get_error(), err); |
919 tcn_Throw(e, "Private key does not match the certificate public key (%s)
", | 659 tcn_Throw(e, "Private key does not match the certificate public key (%s)
", |
920 err); | 660 err); |
921 rv = JNI_FALSE; | 661 rv = JNI_FALSE; |
922 goto cleanup; | 662 goto cleanup; |
923 } | 663 } |
924 cleanup: | 664 cleanup: |
925 TCN_FREE_CSTRING(cert); | 665 TCN_FREE_CSTRING(cert); |
926 TCN_FREE_CSTRING(key); | 666 TCN_FREE_CSTRING(key); |
927 TCN_FREE_CSTRING(password); | 667 TCN_FREE_CSTRING(password); |
| 668 EVP_PKEY_free(pkey); // this function is safe to call with NULL |
| 669 X509_free(xcert); // this function is safe to call with NULL |
| 670 free_and_reset_pass(c, old_password, rv); |
928 return rv; | 671 return rv; |
929 } | 672 } |
930 | 673 |
931 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateBio)(TCN_STDARGS, jlong c
tx, | 674 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateBio)(TCN_STDARGS, jlong c
tx, |
932 jlong cert, jlong key, | 675 jlong cert, jlong key, |
933 jstring password, jint
idx) | 676 jstring password) |
934 { | 677 { |
935 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 678 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
936 BIO *cert_bio = J2P(cert, BIO *); | 679 BIO *cert_bio = J2P(cert, BIO *); |
937 BIO *key_bio = J2P(key, BIO *); | 680 BIO *key_bio = J2P(key, BIO *); |
| 681 EVP_PKEY *pkey = NULL; |
| 682 X509 *xcert = NULL; |
938 | 683 |
939 jboolean rv = JNI_TRUE; | 684 jboolean rv = JNI_TRUE; |
940 TCN_ALLOC_CSTRING(password); | 685 TCN_ALLOC_CSTRING(password); |
| 686 char *old_password = NULL; |
941 char err[256]; | 687 char err[256]; |
942 | 688 |
943 UNREFERENCED(o); | 689 UNREFERENCED(o); |
944 TCN_ASSERT(ctx != 0); | 690 TCN_ASSERT(ctx != 0); |
945 | 691 |
946 if (idx < 0 || idx >= SSL_AIDX_MAX) { | 692 if (J2S(password)) { |
947 /* TODO: Throw something */ | 693 old_password = c->password; |
948 rv = JNI_FALSE; | 694 |
949 goto cleanup; | 695 c->password = strdup(cpassword); |
| 696 if (c->password == NULL) { |
| 697 rv = JNI_FALSE; |
| 698 goto cleanup; |
| 699 } |
950 } | 700 } |
951 if (J2S(password)) { | 701 |
952 if (!c->cb_data) | |
953 c->cb_data = &tcn_password_callback; | |
954 strncpy(c->cb_data->password, J2S(password), SSL_MAX_PASSWORD_LEN); | |
955 c->cb_data->password[SSL_MAX_PASSWORD_LEN-1] = '\0'; | |
956 } | |
957 if (!key) | 702 if (!key) |
958 key = cert; | 703 key = cert; |
959 if (!cert || !key) { | 704 if (!cert || !key) { |
960 tcn_Throw(e, "No Certificate file specified or invalid file format"); | 705 tcn_Throw(e, "No Certificate file specified or invalid file format"); |
961 rv = JNI_FALSE; | 706 rv = JNI_FALSE; |
962 goto cleanup; | 707 goto cleanup; |
963 } | 708 } |
964 | 709 |
965 if ((c->keys[idx] = load_pem_key_bio(c, key_bio)) == NULL) { | 710 if ((pkey = load_pem_key_bio(c->password, key_bio)) == NULL) { |
966 ERR_error_string(ERR_get_error(), err); | 711 ERR_error_string(ERR_get_error(), err); |
967 ERR_clear_error(); | 712 ERR_clear_error(); |
968 tcn_Throw(e, "Unable to load certificate key (%s)",err); | 713 tcn_Throw(e, "Unable to load certificate key (%s)",err); |
969 rv = JNI_FALSE; | 714 rv = JNI_FALSE; |
970 goto cleanup; | 715 goto cleanup; |
971 } | 716 } |
972 if ((c->certs[idx] = load_pem_cert_bio(c, cert_bio)) == NULL) { | 717 if ((xcert = load_pem_cert_bio(c->password, cert_bio)) == NULL) { |
973 ERR_error_string(ERR_get_error(), err); | 718 ERR_error_string(ERR_get_error(), err); |
974 ERR_clear_error(); | 719 ERR_clear_error(); |
975 tcn_Throw(e, "Unable to load certificate (%s) ", err); | 720 tcn_Throw(e, "Unable to load certificate (%s) ", err); |
976 rv = JNI_FALSE; | 721 rv = JNI_FALSE; |
977 goto cleanup; | 722 goto cleanup; |
978 } | 723 } |
979 | 724 |
980 if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) { | 725 if (SSL_CTX_use_certificate(c->ctx, xcert) <= 0) { |
981 ERR_error_string(ERR_get_error(), err); | 726 ERR_error_string(ERR_get_error(), err); |
982 ERR_clear_error(); | 727 ERR_clear_error(); |
983 tcn_Throw(e, "Error setting certificate (%s)", err); | 728 tcn_Throw(e, "Error setting certificate (%s)", err); |
984 rv = JNI_FALSE; | 729 rv = JNI_FALSE; |
985 goto cleanup; | 730 goto cleanup; |
986 } | 731 } |
987 if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) { | 732 if (SSL_CTX_use_PrivateKey(c->ctx, pkey) <= 0) { |
988 ERR_error_string(ERR_get_error(), err); | 733 ERR_error_string(ERR_get_error(), err); |
989 ERR_clear_error(); | 734 ERR_clear_error(); |
990 tcn_Throw(e, "Error setting private key (%s)", err); | 735 tcn_Throw(e, "Error setting private key (%s)", err); |
991 rv = JNI_FALSE; | 736 rv = JNI_FALSE; |
992 goto cleanup; | 737 goto cleanup; |
993 } | 738 } |
994 if (SSL_CTX_check_private_key(c->ctx) <= 0) { | 739 if (SSL_CTX_check_private_key(c->ctx) <= 0) { |
995 ERR_error_string(ERR_get_error(), err); | 740 ERR_error_string(ERR_get_error(), err); |
996 ERR_clear_error(); | 741 ERR_clear_error(); |
997 | 742 |
998 tcn_Throw(e, "Private key does not match the certificate public key (%s)
", | 743 tcn_Throw(e, "Private key does not match the certificate public key (%s)
", |
999 err); | 744 err); |
1000 rv = JNI_FALSE; | 745 rv = JNI_FALSE; |
1001 goto cleanup; | 746 goto cleanup; |
1002 } | 747 } |
1003 cleanup: | 748 cleanup: |
1004 TCN_FREE_CSTRING(password); | 749 TCN_FREE_CSTRING(password); |
| 750 EVP_PKEY_free(pkey); // this function is safe to call with NULL |
| 751 X509_free(xcert); // this function is safe to call with NULL |
| 752 free_and_reset_pass(c, old_password, rv); |
1005 return rv; | 753 return rv; |
1006 } | 754 } |
1007 | 755 |
1008 | |
1009 // Convert protos to wire format | 756 // Convert protos to wire format |
1010 static int initProtocols(JNIEnv *e, unsigned char **proto_data, | 757 static int initProtocols(JNIEnv *e, unsigned char **proto_data, |
1011 unsigned int *proto_len, jobjectArray protos) { | 758 unsigned int *proto_len, jobjectArray protos) { |
1012 int i; | 759 int i; |
1013 unsigned char *p_data; | 760 unsigned char *p_data; |
1014 // We start with allocate 128 bytes which should be good enough for most use
-cases while still be pretty low. | 761 // We start with allocate 128 bytes which should be good enough for most use
-cases while still be pretty low. |
1015 // We will call realloc to increate this if needed. | 762 // We will call realloc to increase this if needed. |
1016 size_t p_data_size = 128; | 763 size_t p_data_size = 128; |
1017 size_t p_data_len = 0; | 764 size_t p_data_len = 0; |
1018 jstring proto_string; | 765 jstring proto_string; |
1019 const char *proto_chars; | 766 const char *proto_chars; |
1020 size_t proto_chars_len; | 767 size_t proto_chars_len; |
1021 int cnt; | 768 int cnt; |
1022 | 769 |
1023 if (protos == NULL) { | 770 if (protos == NULL) { |
1024 // Guard against NULL protos. | 771 // Guard against NULL protos. |
1025 return -1; | 772 return -1; |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 return rv; | 1013 return rv; |
1267 } | 1014 } |
1268 | 1015 |
1269 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCacheFull)(TCN_STDARGS, jlong ctx) | 1016 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCacheFull)(TCN_STDARGS, jlong ctx) |
1270 { | 1017 { |
1271 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 1018 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
1272 jlong rv = SSL_CTX_sess_cache_full(c->ctx); | 1019 jlong rv = SSL_CTX_sess_cache_full(c->ctx); |
1273 return rv; | 1020 return rv; |
1274 } | 1021 } |
1275 | 1022 |
| 1023 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyNew)(TCN_STDARGS, jlong ct
x) |
| 1024 { |
| 1025 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
| 1026 jlong rv = apr_atomic_read32(&c->ticket_keys_new); |
| 1027 return rv; |
| 1028 } |
| 1029 |
| 1030 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyResume)(TCN_STDARGS, jlong
ctx) |
| 1031 { |
| 1032 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
| 1033 jlong rv = apr_atomic_read32(&c->ticket_keys_resume); |
| 1034 return rv; |
| 1035 } |
| 1036 |
| 1037 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyRenew)(TCN_STDARGS, jlong
ctx) |
| 1038 { |
| 1039 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
| 1040 jlong rv = apr_atomic_read32(&c->ticket_keys_renew); |
| 1041 return rv; |
| 1042 } |
| 1043 |
| 1044 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyFail)(TCN_STDARGS, jlong c
tx) |
| 1045 { |
| 1046 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
| 1047 jlong rv = apr_atomic_read32(&c->ticket_keys_fail); |
| 1048 return rv; |
| 1049 } |
| 1050 |
1276 static int current_session_key(tcn_ssl_ctxt_t *c, tcn_ssl_ticket_key_t *key) { | 1051 static int current_session_key(tcn_ssl_ctxt_t *c, tcn_ssl_ticket_key_t *key) { |
1277 int result = JNI_FALSE; | 1052 int result = JNI_FALSE; |
1278 apr_thread_rwlock_rdlock(c->mutex); | 1053 apr_thread_rwlock_rdlock(c->mutex); |
1279 if (c->ticket_keys_len > 0) { | 1054 if (c->ticket_keys_len > 0) { |
1280 *key = c->ticket_keys[0]; | 1055 *key = c->ticket_keys[0]; |
1281 result = JNI_TRUE; | 1056 result = JNI_TRUE; |
1282 } | 1057 } |
1283 apr_thread_rwlock_unlock(c->mutex); | 1058 apr_thread_rwlock_unlock(c->mutex); |
1284 return result; | 1059 return result; |
1285 } | 1060 } |
(...skipping 10 matching lines...) Expand all Loading... |
1296 result = JNI_TRUE; | 1071 result = JNI_TRUE; |
1297 *is_current_key = (i == 0); | 1072 *is_current_key = (i == 0); |
1298 break; | 1073 break; |
1299 } | 1074 } |
1300 } | 1075 } |
1301 apr_thread_rwlock_unlock(c->mutex); | 1076 apr_thread_rwlock_unlock(c->mutex); |
1302 return result; | 1077 return result; |
1303 } | 1078 } |
1304 | 1079 |
1305 static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned
char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) { | 1080 static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned
char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) { |
1306 tcn_ssl_ctxt_t *c = SSL_get_app_data2(s); | 1081 tcn_ssl_ctxt_t *c = SSL_get_app_data2(s); |
1307 tcn_ssl_ticket_key_t key; | 1082 tcn_ssl_ticket_key_t key; |
1308 int is_current_key; | 1083 int is_current_key; |
1309 | 1084 |
1310 if (enc) { /* create new session */ | 1085 if (enc) { /* create new session */ |
1311 if (current_session_key(c, &key)) { | 1086 if (current_session_key(c, &key)) { |
1312 if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0) { | 1087 if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0) { |
1313 return -1; /* insufficient random */ | 1088 return -1; /* insufficient random */ |
1314 } | 1089 } |
1315 | 1090 |
1316 memcpy(key_name, key.key_name, 16); | 1091 memcpy(key_name, key.key_name, 16); |
1317 | 1092 |
1318 EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key.aes_key, iv); | 1093 EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key.aes_key, iv); |
1319 HMAC_Init_ex(hctx, key.hmac_key, 16, EVP_sha256(), NULL); | 1094 HMAC_Init_ex(hctx, key.hmac_key, 16, EVP_sha256(), NULL); |
1320 return 1; | 1095 apr_atomic_inc32(&c->ticket_keys_new); |
1321 } | 1096 return 1; |
1322 // No ticket configured | 1097 } |
1323 return 0; | 1098 // No ticket configured |
1324 } else { /* retrieve session */ | 1099 return 0; |
1325 if (find_session_key(c, key_name, &key, &is_current_key)) { | 1100 } else { /* retrieve session */ |
1326 HMAC_Init_ex(hctx, key.hmac_key, 16, EVP_sha256(), NULL); | 1101 if (find_session_key(c, key_name, &key, &is_current_key)) { |
1327 EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key.aes_key, iv ); | 1102 HMAC_Init_ex(hctx, key.hmac_key, 16, EVP_sha256(), NULL); |
1328 if (!is_current_key) { | 1103 EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key.aes_key, iv ); |
1329 return 2; | 1104 if (!is_current_key) { |
1330 } | 1105 // The ticket matched a key in the list, and we want to upgrade
it to the current |
1331 return 1; | 1106 // key. |
1332 } | 1107 apr_atomic_inc32(&c->ticket_keys_renew); |
1333 // No ticket | 1108 return 2; |
1334 return 0; | 1109 } |
1335 } | 1110 // The ticket matched the current key. |
| 1111 apr_atomic_inc32(&c->ticket_keys_resume); |
| 1112 return 1; |
| 1113 } |
| 1114 // No matching ticket. |
| 1115 apr_atomic_inc32(&c->ticket_keys_fail); |
| 1116 return 0; |
| 1117 } |
1336 } | 1118 } |
1337 | 1119 |
1338 TCN_IMPLEMENT_CALL(void, SSLContext, setSessionTicketKeys0)(TCN_STDARGS, jlong c
tx, jbyteArray keys) | 1120 TCN_IMPLEMENT_CALL(void, SSLContext, setSessionTicketKeys0)(TCN_STDARGS, jlong c
tx, jbyteArray keys) |
1339 { | 1121 { |
1340 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 1122 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
1341 jbyte* b; | 1123 jbyte* b; |
1342 jbyte* key; | 1124 jbyte* key; |
1343 tcn_ssl_ticket_key_t* ticket_keys; | 1125 tcn_ssl_ticket_key_t* ticket_keys; |
1344 int i; | 1126 int i; |
1345 int cnt; | 1127 int cnt; |
(...skipping 16 matching lines...) Expand all Loading... |
1362 if (c->ticket_keys) { | 1144 if (c->ticket_keys) { |
1363 free(c->ticket_keys); | 1145 free(c->ticket_keys); |
1364 } | 1146 } |
1365 c->ticket_keys_len = cnt; | 1147 c->ticket_keys_len = cnt; |
1366 c->ticket_keys = ticket_keys; | 1148 c->ticket_keys = ticket_keys; |
1367 apr_thread_rwlock_unlock(c->mutex); | 1149 apr_thread_rwlock_unlock(c->mutex); |
1368 | 1150 |
1369 SSL_CTX_set_tlsext_ticket_key_cb(c->ctx, ssl_tlsext_ticket_key_cb); | 1151 SSL_CTX_set_tlsext_ticket_key_cb(c->ctx, ssl_tlsext_ticket_key_cb); |
1370 } | 1152 } |
1371 | 1153 |
1372 | |
1373 /* | |
1374 * Adapted from OpenSSL: | |
1375 * http://osxr.org/openssl/source/ssl/ssl_locl.h#0291 | |
1376 */ | |
1377 /* Bits for algorithm_mkey (key exchange algorithm) */ | |
1378 #define SSL_kRSA 0x00000001L /* RSA key exchange */ | |
1379 #define SSL_kDHr 0x00000002L /* DH cert, RSA CA cert */ /* no such cipher
suites supported! */ | |
1380 #define SSL_kDHd 0x00000004L /* DH cert, DSA CA cert */ /* no such cipher
suite supported! */ | |
1381 #define SSL_kEDH 0x00000008L /* tmp DH key no DH cert */ | |
1382 #define SSL_kKRB5 0x00000010L /* Kerberos5 key exchange */ | |
1383 #define SSL_kECDHr 0x00000020L /* ECDH cert, RSA CA cert */ | |
1384 #define SSL_kECDHe 0x00000040L /* ECDH cert, ECDSA CA cert */ | |
1385 #define SSL_kEECDH 0x00000080L /* ephemeral ECDH */ | |
1386 #define SSL_kPSK 0x00000100L /* PSK */ | |
1387 #define SSL_kGOST 0x00000200L /* GOST key exchange */ | |
1388 #define SSL_kSRP 0x00000400L /* SRP */ | |
1389 | |
1390 /* Bits for algorithm_auth (server authentication) */ | |
1391 #define SSL_aRSA 0x00000001L /* RSA auth */ | |
1392 #define SSL_aDSS 0x00000002L /* DSS auth */ | |
1393 #define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */ | |
1394 #define SSL_aDH 0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no suc
h ciphersuites supported! */ | |
1395 #define SSL_aECDH 0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */ | |
1396 #define SSL_aKRB5 0x00000020L /* KRB5 auth */ | |
1397 #define SSL_aECDSA 0x00000040L /* ECDSA auth*/ | |
1398 #define SSL_aPSK 0x00000080L /* PSK auth */ | |
1399 #define SSL_aGOST94 0x00000100L /* GOST R 34.10-94 signature auth */ | |
1400 #define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */ | |
1401 | |
1402 /* OpenSSL end */ | |
1403 | |
1404 /* | |
1405 * Adapted from Android: | |
1406 * https://android.googlesource.com/platform/external/openssl/+/master/patches/0
003-jsse.patch | |
1407 */ | |
1408 const char* cipher_authentication_method(const SSL_CIPHER* cipher){ | |
1409 #ifndef OPENSSL_IS_BORINGSSL | |
1410 switch (cipher->algorithm_mkey) | |
1411 { | |
1412 case SSL_kRSA: | |
1413 return SSL_TXT_RSA; | |
1414 case SSL_kDHr: | |
1415 return SSL_TXT_DH "_" SSL_TXT_RSA; | |
1416 | |
1417 case SSL_kDHd: | |
1418 return SSL_TXT_DH "_" SSL_TXT_DSS; | |
1419 case SSL_kEDH: | |
1420 switch (cipher->algorithm_auth) | |
1421 { | |
1422 case SSL_aDSS: | |
1423 return "DHE_" SSL_TXT_DSS; | |
1424 case SSL_aRSA: | |
1425 return "DHE_" SSL_TXT_RSA; | |
1426 case SSL_aNULL: | |
1427 return SSL_TXT_DH "_anon"; | |
1428 default: | |
1429 return "UNKNOWN"; | |
1430 } | |
1431 case SSL_kKRB5: | |
1432 return SSL_TXT_KRB5; | |
1433 case SSL_kECDHr: | |
1434 return SSL_TXT_ECDH "_" SSL_TXT_RSA; | |
1435 case SSL_kECDHe: | |
1436 return SSL_TXT_ECDH "_" SSL_TXT_ECDSA; | |
1437 case SSL_kEECDH: | |
1438 switch (cipher->algorithm_auth) | |
1439 { | |
1440 case SSL_aECDSA: | |
1441 return "ECDHE_" SSL_TXT_ECDSA; | |
1442 case SSL_aRSA: | |
1443 return "ECDHE_" SSL_TXT_RSA; | |
1444 case SSL_aNULL: | |
1445 return SSL_TXT_ECDH "_anon"; | |
1446 default: | |
1447 return "UNKNOWN"; | |
1448 } | |
1449 default: | |
1450 return "UNKNOWN"; | |
1451 } | |
1452 #else | |
1453 return SSL_CIPHER_get_kx_name(cipher); | |
1454 #endif | |
1455 | |
1456 } | |
1457 | |
1458 static const char* authentication_method(const SSL* ssl) { | 1154 static const char* authentication_method(const SSL* ssl) { |
1459 { | 1155 { |
| 1156 const STACK_OF(SSL_CIPHER) *ciphers = NULL; |
| 1157 |
1460 switch (SSL_version(ssl)) | 1158 switch (SSL_version(ssl)) |
1461 { | 1159 { |
1462 case SSL2_VERSION: | 1160 case SSL2_VERSION: |
1463 return SSL_TXT_RSA; | 1161 return SSL_TXT_RSA; |
1464 default: | 1162 default: |
1465 #if defined(OPENSSL_IS_BORINGSSL) | 1163 ciphers = SSL_get_ciphers(ssl); |
1466 return cipher_authentication_method(SSL_get_pending_cipher(ssl)); | 1164 if (ciphers == NULL || sk_SSL_CIPHER_num(ciphers) <= 0) { |
1467 #else | 1165 // No cipher available so return UNKNOWN. |
1468 return cipher_authentication_method(ssl->s3->tmp.new_cipher); | 1166 return TCN_UNKNOWN_AUTH_METHOD; |
1469 #endif | 1167 } |
| 1168 return SSL_cipher_authentication_method(sk_SSL_CIPHER_value(ciphers,
0)); |
1470 } | 1169 } |
1471 } | 1170 } |
1472 } | 1171 } |
1473 /* Android end */ | 1172 /* Android end */ |
1474 | 1173 |
1475 static int SSL_cert_verify(X509_STORE_CTX *ctx, void *arg) { | 1174 static int SSL_cert_verify(X509_STORE_CTX *ctx, void *arg) { |
1476 /* Get Apache context back through OpenSSL context */ | 1175 /* Get Apache context back through OpenSSL context */ |
1477 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_id
x()); | 1176 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_id
x()); |
| 1177 TCN_ASSERT(ssl != NULL); |
1478 tcn_ssl_ctxt_t *c = SSL_get_app_data2(ssl); | 1178 tcn_ssl_ctxt_t *c = SSL_get_app_data2(ssl); |
1479 | 1179 TCN_ASSERT(c != NULL); |
| 1180 tcn_ssl_verify_config_t* verify_config = SSL_get_app_data4(ssl); |
| 1181 TCN_ASSERT(verify_config != NULL); |
1480 | 1182 |
1481 // Get a stack of all certs in the chain | 1183 // Get a stack of all certs in the chain |
1482 STACK_OF(X509) *sk = ctx->untrusted; | 1184 STACK_OF(X509) *sk = ctx->untrusted; |
1483 | 1185 |
1484 int len = sk_num((_STACK*) sk); | 1186 // SSL_CTX_set_verify_depth() and SSL_set_verify_depth() set the limit up to
which depth certificates in a chain are |
| 1187 // used during the verification procedure. If the certificate chain is longe
r than allowed, the certificates above |
| 1188 // the limit are ignored. Error messages are generated as if these certifica
tes would not be present, |
| 1189 // most likely a X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY will be issued
. |
| 1190 // https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_verify.html |
| 1191 const int totalQueuedLength = sk_X509_num(sk); |
| 1192 int len = TCN_MIN(verify_config->verify_depth, totalQueuedLength); |
1485 unsigned i; | 1193 unsigned i; |
1486 X509 *cert; | 1194 X509 *cert; |
1487 int length; | 1195 int length; |
1488 unsigned char *buf; | 1196 unsigned char *buf; |
1489 JNIEnv *e; | 1197 JNIEnv *e; |
1490 jbyteArray array; | 1198 jbyteArray array; |
1491 jbyteArray bArray; | 1199 jbyteArray bArray; |
1492 const char *authMethod; | 1200 const char *authMethod; |
1493 jstring authMethodString; | 1201 jstring authMethodString; |
1494 jboolean result; | 1202 jint result; |
1495 int r; | 1203 jclass byteArrayClass = tcn_get_byte_array_class(); |
1496 tcn_get_java_env(&e); | 1204 tcn_get_java_env(&e); |
1497 | 1205 |
1498 // Create the byte[][]Â array that holds all the certs | 1206 // Create the byte[][]Â array that holds all the certs |
1499 array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL); | 1207 array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL); |
1500 | 1208 |
1501 for(i = 0; i < len; i++) { | 1209 for(i = 0; i < len; i++) { |
1502 cert = (X509*) sk_value((_STACK*) sk, i); | 1210 cert = sk_X509_value(sk, i); |
1503 | 1211 |
1504 buf = NULL; | 1212 buf = NULL; |
1505 length = i2d_X509(cert, &buf); | 1213 length = i2d_X509(cert, &buf); |
1506 if (length < 0) { | 1214 if (length < 0) { |
1507 // In case of error just return an empty byte[][] | 1215 // In case of error just return an empty byte[][] |
1508 array = (*e)->NewObjectArray(e, 0, byteArrayClass, NULL); | 1216 array = (*e)->NewObjectArray(e, 0, byteArrayClass, NULL); |
1509 // We need to delete the local references so we not leak memory as t
his method is called via callback. | 1217 if (buf != NULL) { |
1510 OPENSSL_free(buf); | 1218 // We need to delete the local references so we not leak memory
as this method is called via callback. |
| 1219 OPENSSL_free(buf); |
| 1220 } |
1511 break; | 1221 break; |
1512 } | 1222 } |
1513 bArray = (*e)->NewByteArray(e, length); | 1223 bArray = (*e)->NewByteArray(e, length); |
1514 (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf); | 1224 (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf); |
1515 (*e)->SetObjectArrayElement(e, array, i, bArray); | 1225 (*e)->SetObjectArrayElement(e, array, i, bArray); |
1516 | 1226 |
1517 // Delete the local reference as we not know how long the chain is and l
ocal references are otherwise | 1227 // Delete the local reference as we not know how long the chain is and l
ocal references are otherwise |
1518 // only freed once jni method returns. | 1228 // only freed once jni method returns. |
1519 (*e)->DeleteLocalRef(e, bArray); | 1229 (*e)->DeleteLocalRef(e, bArray); |
1520 OPENSSL_free(buf); | 1230 OPENSSL_free(buf); |
1521 } | 1231 } |
1522 | 1232 |
1523 authMethod = authentication_method(ssl); | 1233 authMethod = authentication_method(ssl); |
1524 authMethodString = (*e)->NewStringUTF(e, authMethod); | 1234 authMethodString = (*e)->NewStringUTF(e, authMethod); |
1525 | 1235 |
1526 result = (*e)->CallBooleanMethod(e, c->verifier, c->verifier_method, P2J(ssl
), array, | 1236 result = (*e)->CallIntMethod(e, c->verifier, c->verifier_method, P2J(ssl), a
rray, authMethodString); |
1527 authMethodString); | |
1528 | 1237 |
1529 r = result == JNI_TRUE ? 1 : 0; | 1238 #ifdef X509_V_ERR_UNSPECIFIED |
| 1239 // If we failed to verify for an unknown reason (currently this happens if w
e can't find a common root) then we should |
| 1240 // fail with the same status as recommended in the OpenSSL docs https://www.
openssl.org/docs/man1.0.2/ssl/SSL_set_verify.html |
| 1241 if (result == X509_V_ERR_UNSPECIFIED && len < totalQueuedLength) { |
| 1242 result = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; |
| 1243 } |
| 1244 #else |
| 1245 // HACK! |
| 1246 // LibreSSL 2.4.x doesn't support the X509_V_ERR_UNSPECIFIED so we introduce
a work around to make sure a supported alert is used. |
| 1247 // This should be reverted when we support LibreSSL 2.5.x (which does suppor
t X509_V_ERR_UNSPECIFIED). |
| 1248 if (result == TCN_X509_V_ERR_UNSPECIFIED) { |
| 1249 result = len < totalQueuedLength ? X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_
LOCALLY : X509_V_ERR_CERT_REJECTED; |
| 1250 } |
| 1251 #endif |
| 1252 |
| 1253 // TODO(scott): if verify_config->verify_depth == SSL_CVERIFY_OPTIONAL we ha
ve the option to let the handshake |
| 1254 // succeed for some of the "informational" error messages (e.g. X509_V_ERR_E
MAIL_MISMATCH ?) |
| 1255 |
| 1256 // Set the correct error so it will be included in the alert. |
| 1257 X509_STORE_CTX_set_error(ctx, result); |
1530 | 1258 |
1531 // We need to delete the local references so we not leak memory as this meth
od is called via callback. | 1259 // We need to delete the local references so we not leak memory as this meth
od is called via callback. |
1532 (*e)->DeleteLocalRef(e, authMethodString); | 1260 (*e)->DeleteLocalRef(e, authMethodString); |
1533 (*e)->DeleteLocalRef(e, array); | 1261 (*e)->DeleteLocalRef(e, array); |
1534 return r; | 1262 |
| 1263 return result == X509_V_OK ? 1 : 0; |
1535 } | 1264 } |
1536 | 1265 |
1537 | |
1538 TCN_IMPLEMENT_CALL(void, SSLContext, setCertVerifyCallback)(TCN_STDARGS, jlong c
tx, jobject verifier) | 1266 TCN_IMPLEMENT_CALL(void, SSLContext, setCertVerifyCallback)(TCN_STDARGS, jlong c
tx, jobject verifier) |
1539 { | 1267 { |
1540 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 1268 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
1541 | 1269 |
1542 UNREFERENCED(o); | 1270 UNREFERENCED(o); |
1543 TCN_ASSERT(ctx != 0); | 1271 TCN_ASSERT(ctx != 0); |
1544 | 1272 |
1545 if (verifier == NULL) { | 1273 if (verifier == NULL) { |
1546 SSL_CTX_set_cert_verify_callback(c->ctx, NULL, NULL); | 1274 SSL_CTX_set_cert_verify_callback(c->ctx, NULL, NULL); |
1547 } else { | 1275 } else { |
1548 jclass verifier_class = (*e)->GetObjectClass(e, verifier); | 1276 jclass verifier_class = (*e)->GetObjectClass(e, verifier); |
1549 jmethodID method = (*e)->GetMethodID(e, verifier_class, "verify", "(J[[B
Ljava/lang/String;)Z"); | 1277 jmethodID method = (*e)->GetMethodID(e, verifier_class, "verify", "(J[[B
Ljava/lang/String;)I"); |
1550 | 1278 |
1551 if (method == NULL) { | 1279 if (method == NULL) { |
1552 return; | 1280 return; |
1553 } | 1281 } |
1554 // Delete the reference to the previous specified verifier if needed. | 1282 // Delete the reference to the previous specified verifier if needed. |
1555 if (c->verifier != NULL) { | 1283 if (c->verifier != NULL) { |
1556 (*e)->DeleteLocalRef(e, c->verifier); | 1284 (*e)->DeleteLocalRef(e, c->verifier); |
1557 } | 1285 } |
1558 c->verifier = (*e)->NewGlobalRef(e, verifier); | 1286 c->verifier = (*e)->NewGlobalRef(e, verifier); |
1559 c->verifier_method = method; | 1287 c->verifier_method = method; |
1560 | 1288 |
1561 SSL_CTX_set_cert_verify_callback(c->ctx, SSL_cert_verify, NULL); | 1289 SSL_CTX_set_cert_verify_callback(c->ctx, SSL_cert_verify, NULL); |
1562 } | 1290 } |
1563 } | 1291 } |
1564 | 1292 |
| 1293 /** |
| 1294 * Returns an array containing all the X500 principal's bytes. |
| 1295 * |
| 1296 * Partly based on code from conscrypt: |
| 1297 * https://android.googlesource.com/platform/external/conscrypt/+/master/src/mai
n/native/org_conscrypt_NativeCrypto.cpp |
| 1298 */ |
| 1299 static jobjectArray principalBytes(JNIEnv* e, const STACK_OF(X509_NAME)* names)
{ |
| 1300 jobjectArray array; |
| 1301 jbyteArray bArray; |
| 1302 int i; |
| 1303 int count; |
| 1304 int length; |
| 1305 unsigned char *buf; |
| 1306 X509_NAME* principal; |
| 1307 jclass byteArrayClass = tcn_get_byte_array_class(); |
| 1308 |
| 1309 if (names == NULL) { |
| 1310 return NULL; |
| 1311 } |
| 1312 |
| 1313 count = sk_X509_NAME_num(names); |
| 1314 if (count <= 0) { |
| 1315 return NULL; |
| 1316 } |
| 1317 |
| 1318 array = (*e)->NewObjectArray(e, count, byteArrayClass, NULL); |
| 1319 if (array == NULL) { |
| 1320 return NULL; |
| 1321 } |
| 1322 |
| 1323 for (i = 0; i < count; i++) { |
| 1324 principal = sk_X509_NAME_value(names, i); |
| 1325 buf = NULL; |
| 1326 length = i2d_X509_NAME(principal, &buf); |
| 1327 if (length < 0) { |
| 1328 if (buf != NULL) { |
| 1329 // We need to delete the local references so we not leak memory
as this method is called via callback. |
| 1330 OPENSSL_free(buf); |
| 1331 } |
| 1332 // In case of error just return an empty byte[][] |
| 1333 return (*e)->NewObjectArray(e, 0, byteArrayClass, NULL); |
| 1334 } |
| 1335 bArray = (*e)->NewByteArray(e, length); |
| 1336 (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf); |
| 1337 (*e)->SetObjectArrayElement(e, array, i, bArray); |
| 1338 |
| 1339 // Delete the local reference as we not know how long the chain is and l
ocal references are otherwise |
| 1340 // only freed once jni method returns. |
| 1341 (*e)->DeleteLocalRef(e, bArray); |
| 1342 OPENSSL_free(buf); |
| 1343 } |
| 1344 |
| 1345 return array; |
| 1346 } |
| 1347 |
| 1348 static int cert_requested(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) { |
| 1349 #if defined(LIBRESSL_VERSION_NUMBER) |
| 1350 return -1; |
| 1351 #else |
| 1352 tcn_ssl_ctxt_t *c = SSL_get_app_data2(ssl); |
| 1353 int ctype_num; |
| 1354 jbyte* ctype_bytes; |
| 1355 jobjectArray issuers; |
| 1356 JNIEnv *e; |
| 1357 jbyteArray keyTypes; |
| 1358 jobject keyMaterial; |
| 1359 STACK_OF(X509) *chain = NULL; |
| 1360 X509 *cert = NULL; |
| 1361 EVP_PKEY* pkey = NULL; |
| 1362 jlong certChain; |
| 1363 jlong privateKey; |
| 1364 int certChainLen; |
| 1365 int i; |
| 1366 |
| 1367 tcn_get_java_env(&e); |
| 1368 |
| 1369 #if OPENSSL_VERSION_NUMBER < 0x10002000L |
| 1370 char ssl2_ctype = SSL3_CT_RSA_SIGN; |
| 1371 switch (ssl->version) { |
| 1372 case SSL2_VERSION: |
| 1373 ctype_bytes = (jbyte*) &ssl2_ctype; |
| 1374 ctype_num = 1; |
| 1375 break; |
| 1376 case SSL3_VERSION: |
| 1377 case TLS1_VERSION: |
| 1378 case TLS1_1_VERSION: |
| 1379 case TLS1_2_VERSION: |
| 1380 case DTLS1_VERSION: |
| 1381 ctype_bytes = (jbyte*) ssl->s3->tmp.ctype; |
| 1382 ctype_num = ssl->s3->tmp.ctype_num; |
| 1383 break; |
| 1384 } |
| 1385 #else |
| 1386 ctype_num = SSL_get0_certificate_types(ssl, (const uint8_t **) &ctype_bytes)
; |
| 1387 #endif |
| 1388 if (ctype_num <= 0) { |
| 1389 // Use no certificate |
| 1390 return 0; |
| 1391 } |
| 1392 keyTypes = (*e)->NewByteArray(e, ctype_num); |
| 1393 if (keyTypes == NULL) { |
| 1394 // Something went seriously wrong, bail out! |
| 1395 return -1; |
| 1396 } |
| 1397 (*e)->SetByteArrayRegion(e, keyTypes, 0, ctype_num, ctype_bytes); |
| 1398 |
| 1399 issuers = principalBytes(e, SSL_get_client_CA_list(ssl)); |
| 1400 |
| 1401 // Execute the java callback |
| 1402 keyMaterial = (*e)->CallObjectMethod(e, c->cert_requested_callback, c->cert_
requested_callback_method, P2J(ssl), keyTypes, issuers); |
| 1403 if (keyMaterial == NULL) { |
| 1404 return 0; |
| 1405 } |
| 1406 |
| 1407 // Any failure after this line must cause a goto fail to cleanup things. |
| 1408 certChain = (*e)->GetLongField(e, keyMaterial, tcn_get_key_material_certific
ate_chain_field()); |
| 1409 privateKey = (*e)->GetLongField(e, keyMaterial, tcn_get_key_material_private
_key_field()); |
| 1410 |
| 1411 chain = J2P(certChain, STACK_OF(X509) *); |
| 1412 pkey = J2P(privateKey, EVP_PKEY *); |
| 1413 |
| 1414 if (chain == NULL || pkey == NULL) { |
| 1415 goto fail; |
| 1416 } |
| 1417 |
| 1418 certChainLen = sk_X509_num(chain); |
| 1419 |
| 1420 if (certChainLen <= 0) { |
| 1421 goto fail; |
| 1422 } |
| 1423 |
| 1424 // Skip the first cert in the chain as we will write this to x509Out. |
| 1425 // See https://github.com/netty/netty-tcnative/issues/184 |
| 1426 for (i = 1; i < certChainLen; ++i) { |
| 1427 // We need to explicit add extra certs to the chain as stated in: |
| 1428 // https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_client_cert_cb
.html |
| 1429 // |
| 1430 // Using SSL_add0_chain_cert(...) here as we not want to increment the r
eference count. |
| 1431 if (SSL_add0_chain_cert(ssl, sk_X509_value(chain, i)) <= 0) { |
| 1432 goto fail; |
| 1433 } |
| 1434 } |
| 1435 |
| 1436 cert = sk_X509_value(chain, 0); |
| 1437 // Increment the reference count as we already set the chain via SSL_set0_ch
ain(...) and using a cert out of it. |
| 1438 if (tcn_X509_up_ref(cert) <= 0) { |
| 1439 goto fail; |
| 1440 } |
| 1441 *x509Out = cert; |
| 1442 *pkeyOut = pkey; |
| 1443 |
| 1444 // Free the stack it self but not the certs. |
| 1445 sk_X509_free(chain); |
| 1446 return 1; |
| 1447 fail: |
| 1448 ERR_clear_error(); |
| 1449 sk_X509_pop_free(chain, X509_free); |
| 1450 EVP_PKEY_free(pkey); |
| 1451 |
| 1452 // TODO: Would it be more correct to return 0 in this case we may not want t
o use any cert / private key ? |
| 1453 return -1; |
| 1454 #endif /* defined(LIBRESSL_VERSION_NUMBER) */ |
| 1455 } |
| 1456 |
| 1457 TCN_IMPLEMENT_CALL(void, SSLContext, setCertRequestedCallback)(TCN_STDARGS, jlon
g ctx, jobject callback) |
| 1458 { |
| 1459 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
| 1460 |
| 1461 UNREFERENCED(o); |
| 1462 TCN_ASSERT(ctx != 0); |
| 1463 |
| 1464 if (callback == NULL) { |
| 1465 SSL_CTX_set_client_cert_cb(c->ctx, NULL); |
| 1466 } else { |
| 1467 jclass callback_class = (*e)->GetObjectClass(e, callback); |
| 1468 jmethodID method = (*e)->GetMethodID(e, callback_class, "requested", "(J
[B[[B)Lio/netty/internal/tcnative/CertificateRequestedCallback$KeyMaterial;"); |
| 1469 if (method == NULL) { |
| 1470 return; |
| 1471 } |
| 1472 // Delete the reference to the previous specified verifier if needed. |
| 1473 if (c->cert_requested_callback != NULL) { |
| 1474 (*e)->DeleteLocalRef(e, c->cert_requested_callback); |
| 1475 } |
| 1476 c->cert_requested_callback = (*e)->NewGlobalRef(e, callback); |
| 1477 c->cert_requested_callback_method = method; |
| 1478 |
| 1479 SSL_CTX_set_client_cert_cb(c->ctx, cert_requested); |
| 1480 } |
| 1481 } |
| 1482 |
1565 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setSessionIdContext)(TCN_STDARGS, jlong
ctx, jbyteArray sidCtx) | 1483 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setSessionIdContext)(TCN_STDARGS, jlong
ctx, jbyteArray sidCtx) |
1566 { | 1484 { |
1567 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); | 1485 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
1568 int len = (*e)->GetArrayLength(e, sidCtx); | 1486 int len = (*e)->GetArrayLength(e, sidCtx); |
1569 unsigned char *buf; | 1487 unsigned char *buf; |
1570 int res; | 1488 int res; |
1571 | 1489 |
1572 UNREFERENCED(o); | 1490 UNREFERENCED(o); |
1573 TCN_ASSERT(ctx != 0); | 1491 TCN_ASSERT(ctx != 0); |
1574 | 1492 |
1575 buf = malloc(len); | 1493 buf = malloc(len); |
1576 | 1494 |
1577 (*e)->GetByteArrayRegion(e, sidCtx, 0, len, (jbyte*) buf); | 1495 (*e)->GetByteArrayRegion(e, sidCtx, 0, len, (jbyte*) buf); |
1578 | 1496 |
1579 res = SSL_CTX_set_session_id_context(c->ctx, buf, len); | 1497 res = SSL_CTX_set_session_id_context(c->ctx, buf, len); |
1580 free(buf); | 1498 free(buf); |
1581 | 1499 |
1582 if (res == 1) { | 1500 if (res == 1) { |
1583 return JNI_TRUE; | 1501 return JNI_TRUE; |
1584 } | 1502 } |
1585 return JNI_FALSE; | 1503 return JNI_FALSE; |
1586 } | 1504 } |
1587 #else | 1505 |
1588 /* OpenSSL is not supported. | 1506 TCN_IMPLEMENT_CALL(jint, SSLContext, setMode)(TCN_STDARGS, jlong ctx, jint mode) |
1589 * Create empty stubs. | 1507 { |
1590 */ | 1508 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
1591 | 1509 |
1592 TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jlong pool, | 1510 UNREFERENCED(o); |
1593 jint protocol, jint mode) | 1511 TCN_ASSERT(ctx != 0); |
1594 { | 1512 |
1595 UNREFERENCED_STDARGS; | 1513 return (jint) SSL_CTX_set_mode(c->ctx, mode); |
1596 UNREFERENCED(pool); | 1514 } |
1597 UNREFERENCED(protocol); | 1515 |
1598 UNREFERENCED(mode); | 1516 |
1599 return 0; | 1517 TCN_IMPLEMENT_CALL(jint, SSLContext, getMode)(TCN_STDARGS, jlong ctx) |
1600 } | 1518 { |
1601 | 1519 tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); |
1602 TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx) | 1520 |
1603 { | 1521 UNREFERENCED(o); |
1604 UNREFERENCED_STDARGS; | 1522 TCN_ASSERT(ctx != 0); |
1605 UNREFERENCED(ctx); | 1523 |
1606 return APR_ENOTIMPL; | 1524 return (jint) SSL_CTX_get_mode(c->ctx); |
1607 } | 1525 } |
1608 | |
1609 TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx, | |
1610 jstring id) | |
1611 { | |
1612 UNREFERENCED_STDARGS; | |
1613 UNREFERENCED(ctx); | |
1614 UNREFERENCED(id); | |
1615 } | |
1616 | |
1617 TCN_IMPLEMENT_CALL(void, SSLContext, setBIO)(TCN_STDARGS, jlong ctx, | |
1618 jlong bio, jint dir) | |
1619 { | |
1620 UNREFERENCED_STDARGS; | |
1621 UNREFERENCED(ctx); | |
1622 UNREFERENCED(bio); | |
1623 UNREFERENCED(dir); | |
1624 } | |
1625 | |
1626 TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx, | |
1627 jint opt) | |
1628 { | |
1629 UNREFERENCED_STDARGS; | |
1630 UNREFERENCED(ctx); | |
1631 UNREFERENCED(opt); | |
1632 } | |
1633 | |
1634 TCN_IMPLEMENT_CALL(jint, SSLContext, getOptions)(TCN_STDARGS, jlong ctx) | |
1635 { | |
1636 UNREFERENCED_STDARGS; | |
1637 UNREFERENCED(ctx); | |
1638 } | |
1639 | |
1640 TCN_IMPLEMENT_CALL(void, SSLContext, clearOptions)(TCN_STDARGS, jlong ctx, | |
1641 jint opt) | |
1642 { | |
1643 UNREFERENCED_STDARGS; | |
1644 UNREFERENCED(ctx); | |
1645 UNREFERENCED(opt); | |
1646 } | |
1647 | |
1648 TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx, | |
1649 jboolean mode) | |
1650 { | |
1651 UNREFERENCED_STDARGS; | |
1652 UNREFERENCED(ctx); | |
1653 UNREFERENCED(mode); | |
1654 } | |
1655 | |
1656 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx, | |
1657 jstring ciphers) | |
1658 { | |
1659 UNREFERENCED_STDARGS; | |
1660 UNREFERENCED(ctx); | |
1661 UNREFERENCED(ciphers); | |
1662 return JNI_FALSE; | |
1663 } | |
1664 | |
1665 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCARevocation)(TCN_STDARGS, jlong ctx
, | |
1666 jstring file, | |
1667 jstring path) | |
1668 { | |
1669 UNREFERENCED_STDARGS; | |
1670 UNREFERENCED(ctx); | |
1671 UNREFERENCED(file); | |
1672 UNREFERENCED(path); | |
1673 return JNI_FALSE; | |
1674 } | |
1675 | |
1676 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, j
long ctx, | |
1677 jstring file, | |
1678 jboolean skipf
irst) | |
1679 { | |
1680 UNREFERENCED_STDARGS; | |
1681 UNREFERENCED(ctx); | |
1682 UNREFERENCED(file); | |
1683 UNREFERENCED(skipfirst); | |
1684 return JNI_FALSE; | |
1685 } | |
1686 | |
1687 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainBio)(TCN_STDARGS, jl
ong ctx, | |
1688 jlong chain, | |
1689 jboolean skipf
irst) | |
1690 { | |
1691 UNREFERENCED_STDARGS; | |
1692 UNREFERENCED(ctx); | |
1693 UNREFERENCED(chain); | |
1694 UNREFERENCED(skipfirst); | |
1695 return JNI_FALSE; | |
1696 } | |
1697 | |
1698 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS, | |
1699 jlong ctx, | |
1700 jstring file, | |
1701 jstring path) | |
1702 { | |
1703 UNREFERENCED_STDARGS; | |
1704 UNREFERENCED(ctx); | |
1705 UNREFERENCED(file); | |
1706 UNREFERENCED(path); | |
1707 return JNI_FALSE; | |
1708 } | |
1709 | |
1710 TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx, | |
1711 jint type) | |
1712 { | |
1713 UNREFERENCED_STDARGS; | |
1714 UNREFERENCED(ctx); | |
1715 UNREFERENCED(type); | |
1716 } | |
1717 | |
1718 TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx, | |
1719 jint level, jint depth) | |
1720 { | |
1721 UNREFERENCED_STDARGS; | |
1722 UNREFERENCED(ctx); | |
1723 UNREFERENCED(level); | |
1724 UNREFERENCED(depth); | |
1725 } | |
1726 | |
1727 TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx, | |
1728 jstring file) | |
1729 { | |
1730 UNREFERENCED_STDARGS; | |
1731 UNREFERENCED(ctx); | |
1732 UNREFERENCED(file); | |
1733 } | |
1734 | |
1735 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx, | |
1736 jstring cert, jstring k
ey, | |
1737 jstring password, jint
idx) | |
1738 { | |
1739 UNREFERENCED_STDARGS; | |
1740 UNREFERENCED(ctx); | |
1741 UNREFERENCED(cert); | |
1742 UNREFERENCED(key); | |
1743 UNREFERENCED(password); | |
1744 UNREFERENCED(idx); | |
1745 return JNI_FALSE; | |
1746 } | |
1747 | |
1748 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateBio)(TCN_STDARGS, jlong c
tx, | |
1749 jlong cert, jlong key, | |
1750 jstring password, jint
idx) | |
1751 { | |
1752 UNREFERENCED_STDARGS; | |
1753 UNREFERENCED(ctx); | |
1754 UNREFERENCED(cert); | |
1755 UNREFERENCED(key); | |
1756 UNREFERENCED(password); | |
1757 UNREFERENCED(idx); | |
1758 return JNI_FALSE; | |
1759 } | |
1760 TCN_IMPLEMENT_CALL(void, SSLContext, setNpnProtos)(TCN_STDARGS, jlong ctx, jobje
ctArray next_protos, | |
1761 jint selectorFailureBehavior) | |
1762 { | |
1763 UNREFERENCED_STDARGS; | |
1764 UNREFERENCED(ctx); | |
1765 UNREFERENCED(next_protos); | |
1766 } | |
1767 | |
1768 | |
1769 TCN_IMPLEMENT_CALL(void, SSLContext, setAlpnProtos)(TCN_STDARGS, jlong ctx, jobj
ectArray alpn_protos, | |
1770 jint selectorFailureBehavior) | |
1771 { | |
1772 UNREFERENCED_STDARGS; | |
1773 UNREFERENCED(ctx); | |
1774 UNREFERENCED(alpn_protos); | |
1775 } | |
1776 | |
1777 TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheMode)(TCN_STDARGS, jlong ct
x, jlong mode) | |
1778 { | |
1779 UNREFERENCED_STDARGS; | |
1780 UNREFERENCED(ctx); | |
1781 UNREFERENCED(mode); | |
1782 return -1; | |
1783 } | |
1784 | |
1785 TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheMode)(TCN_STDARGS, jlong ct
x) | |
1786 { | |
1787 UNREFERENCED_STDARGS; | |
1788 UNREFERENCED(ctx); | |
1789 return -1; | |
1790 } | |
1791 | |
1792 | |
1793 TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheTimeout)(TCN_STDARGS, jlong
ctx, jlong timeout) | |
1794 { | |
1795 UNREFERENCED_STDARGS; | |
1796 UNREFERENCED(ctx); | |
1797 UNREFERENCED(timeout); | |
1798 return -1; | |
1799 } | |
1800 | |
1801 TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheTimeout)(TCN_STDARGS, jlong
ctx) | |
1802 { | |
1803 UNREFERENCED_STDARGS; | |
1804 UNREFERENCED(ctx); | |
1805 return -1; | |
1806 } | |
1807 | |
1808 TCN_IMPLEMENT_CALL(jlong, SSLContext, setSessionCacheSize)(TCN_STDARGS, jlong ct
x, jlong size) | |
1809 { | |
1810 UNREFERENCED_STDARGS; | |
1811 UNREFERENCED(ctx); | |
1812 UNREFERENCED(size); | |
1813 return -1; | |
1814 } | |
1815 | |
1816 TCN_IMPLEMENT_CALL(jlong, SSLContext, getSessionCacheSize)(TCN_STDARGS, jlong ct
x) | |
1817 { | |
1818 UNREFERENCED_STDARGS; | |
1819 UNREFERENCED(ctx); | |
1820 return -1; | |
1821 } | |
1822 | |
1823 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionNumber)(TCN_STDARGS, jlong ctx) | |
1824 { | |
1825 UNREFERENCED_STDARGS; | |
1826 UNREFERENCED(ctx); | |
1827 return 0; | |
1828 } | |
1829 | |
1830 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnect)(TCN_STDARGS, jlong ctx) | |
1831 { | |
1832 UNREFERENCED_STDARGS; | |
1833 UNREFERENCED(ctx); | |
1834 return 0; | |
1835 } | |
1836 | |
1837 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnectGood)(TCN_STDARGS, jlong ctx
) | |
1838 { | |
1839 UNREFERENCED_STDARGS; | |
1840 UNREFERENCED(ctx); | |
1841 return 0; | |
1842 } | |
1843 | |
1844 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionConnectRenegotiate)(TCN_STDARGS, jl
ong ctx) | |
1845 { | |
1846 UNREFERENCED_STDARGS; | |
1847 UNREFERENCED(ctx); | |
1848 return 0; | |
1849 } | |
1850 | |
1851 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAccept)(TCN_STDARGS, jlong ctx) | |
1852 { | |
1853 UNREFERENCED_STDARGS; | |
1854 UNREFERENCED(ctx); | |
1855 return 0; | |
1856 } | |
1857 | |
1858 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAcceptGood)(TCN_STDARGS, jlong ctx) | |
1859 { | |
1860 UNREFERENCED_STDARGS; | |
1861 UNREFERENCED(ctx); | |
1862 return 0; | |
1863 } | |
1864 | |
1865 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionAcceptRenegotiate)(TCN_STDARGS, jlo
ng ctx) | |
1866 { | |
1867 UNREFERENCED_STDARGS; | |
1868 UNREFERENCED(ctx); | |
1869 return 0; | |
1870 } | |
1871 | |
1872 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionHits)(TCN_STDARGS, jlong ctx) | |
1873 { | |
1874 UNREFERENCED_STDARGS; | |
1875 UNREFERENCED(ctx); | |
1876 return 0; | |
1877 } | |
1878 | |
1879 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCbHits)(TCN_STDARGS, jlong ctx) | |
1880 { | |
1881 UNREFERENCED_STDARGS; | |
1882 UNREFERENCED(ctx); | |
1883 return 0; | |
1884 } | |
1885 | |
1886 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTimeouts)(TCN_STDARGS, jlong ctx) | |
1887 { | |
1888 UNREFERENCED_STDARGS; | |
1889 UNREFERENCED(ctx); | |
1890 return 0; | |
1891 } | |
1892 | |
1893 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionCacheFull)(TCN_STDARGS, jlong ctx) | |
1894 { | |
1895 UNREFERENCED_STDARGS; | |
1896 UNREFERENCED(ctx); | |
1897 return 0; | |
1898 } | |
1899 | |
1900 TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionMisses)(TCN_STDARGS, jlong ctx) | |
1901 { | |
1902 UNREFERENCED_STDARGS; | |
1903 UNREFERENCED(ctx); | |
1904 return 0; | |
1905 } | |
1906 | |
1907 TCN_IMPLEMENT_CALL(void, SSLContext, setSessionTicketKeys0)(TCN_STDARGS, jlong c
tx, jbyteArray keys) | |
1908 { | |
1909 UNREFERENCED_STDARGS; | |
1910 UNREFERENCED(ctx); | |
1911 UNREFERENCED(keys); | |
1912 } | |
1913 | |
1914 TCN_IMPLEMENT_CALL(void, SSLContext, setCertVerifyCallback)(TCN_STDARGS, jlong c
tx, jobject verifier) | |
1915 { | |
1916 UNREFERENCED_STDARGS; | |
1917 UNREFERENCED(ctx); | |
1918 UNREFERENCED(verifier); | |
1919 } | |
1920 TCN_IMPLEMENT_CALL(jboolean, SSLContext, setSessionIdContext)(TCN_STDARGS, jlong
ctx, jbyteArray sidCtx) | |
1921 { | |
1922 UNREFERENCED_STDARGS; | |
1923 UNREFERENCED(ctx); | |
1924 UNREFERENCED(sidCtx); | |
1925 return JNI_FALSE; | |
1926 } | |
1927 #endif | |
OLD | NEW |