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 /* | 32 #include <stdbool.h> |
18 * | 33 #include <openssl/bio.h> |
19 * @author Mladen Turk | |
20 * @version $Id: ssl.c 1649733 2015-01-06 04:42:24Z billbarker $ | |
21 */ | |
22 | |
23 #include "tcn.h" | 34 #include "tcn.h" |
24 #include "apr_file_io.h" | 35 #include "apr_file_io.h" |
25 #include "apr_thread_mutex.h" | 36 #include "apr_thread_mutex.h" |
26 #include "apr_atomic.h" | 37 #include "apr_atomic.h" |
27 #include "apr_poll.h" | 38 #include "apr_strings.h" |
28 #ifdef HAVE_OPENSSL | 39 #include "apr_portable.h" |
29 #include "ssl_private.h" | 40 #include "ssl_private.h" |
30 | 41 |
31 static int ssl_initialized = 0; | 42 static int ssl_initialized = 0; |
32 static char *ssl_global_rand_file = NULL; | |
33 extern apr_pool_t *tcn_global_pool; | 43 extern apr_pool_t *tcn_global_pool; |
34 | 44 |
35 ENGINE *tcn_ssl_engine = NULL; | 45 ENGINE *tcn_ssl_engine = NULL; |
36 void *SSL_temp_keys[SSL_TMP_KEY_MAX]; | 46 void *SSL_temp_keys[SSL_TMP_KEY_MAX]; |
37 tcn_pass_cb_t tcn_password_callback; | |
38 | 47 |
39 /* Global reference to the pool used by the dynamic mutexes */ | 48 /* Global reference to the pool used by the dynamic mutexes */ |
40 static apr_pool_t *dynlockpool = NULL; | 49 static apr_pool_t *dynlockpool = NULL; |
41 | 50 |
42 static jclass byteArrayClass; | |
43 static jclass stringClass; | |
44 | |
45 /* Dynamic lock structure */ | 51 /* Dynamic lock structure */ |
46 struct CRYPTO_dynlock_value { | 52 struct CRYPTO_dynlock_value { |
47 apr_pool_t *pool; | 53 apr_pool_t *pool; |
48 const char* file; | 54 const char* file; |
49 int line; | 55 int line; |
50 apr_thread_mutex_t *mutex; | 56 apr_thread_mutex_t *mutex; |
51 }; | 57 }; |
52 | 58 |
| 59 struct TCN_bio_bytebuffer { |
| 60 // Pointer arithmetic is done on this variable. The type must correspond to
a "byte" size. |
| 61 char* buffer; |
| 62 char* nonApplicationBuffer; |
| 63 jint nonApplicationBufferSize; |
| 64 jint nonApplicationBufferOffset; |
| 65 jint nonApplicationBufferLength; |
| 66 jint bufferLength; |
| 67 bool bufferIsSSLWriteSink; |
| 68 }; |
53 | 69 |
54 /* | 70 /* |
55 * Handle the Temporary RSA Keys and DH Params | 71 * Handle the Temporary RSA Keys and DH Params |
56 */ | 72 */ |
57 | 73 |
58 #define SSL_TMP_KEY_FREE(type, idx) \ | 74 #define SSL_TMP_KEY_FREE(type, idx) \ |
59 if (SSL_temp_keys[idx]) { \ | 75 if (SSL_temp_keys[idx]) { \ |
60 type##_free((type *)SSL_temp_keys[idx]); \ | 76 type##_free((type *)SSL_temp_keys[idx]); \ |
61 SSL_temp_keys[idx] = NULL; \ | 77 SSL_temp_keys[idx] = NULL; \ |
62 } else (void)(0) | 78 } else (void)(0) |
63 | 79 |
64 #define SSL_TMP_KEYS_FREE(type) \ | 80 #define SSL_TMP_KEYS_FREE(type) \ |
65 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_512); \ | 81 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_512); \ |
66 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_1024); \ | 82 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_1024); \ |
67 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_2048); \ | 83 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_2048); \ |
68 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_4096) | 84 SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_4096) |
69 | 85 |
70 #define SSL_TMP_KEY_INIT_RSA(bits) \ | |
71 ssl_tmp_key_init_rsa(bits, SSL_TMP_KEY_RSA_##bits) | |
72 | |
73 #define SSL_TMP_KEY_INIT_DH(bits) \ | 86 #define SSL_TMP_KEY_INIT_DH(bits) \ |
74 ssl_tmp_key_init_dh(bits, SSL_TMP_KEY_DH_##bits) | 87 ssl_tmp_key_init_dh(bits, SSL_TMP_KEY_DH_##bits) |
75 | 88 |
76 #define SSL_TMP_KEYS_INIT(R) \ | 89 #define SSL_TMP_KEYS_INIT(R) \ |
77 SSL_temp_keys[SSL_TMP_KEY_RSA_2048] = NULL; \ | |
78 SSL_temp_keys[SSL_TMP_KEY_RSA_4096] = NULL; \ | |
79 R |= SSL_TMP_KEY_INIT_RSA(512); \ | |
80 R |= SSL_TMP_KEY_INIT_RSA(1024); \ | |
81 R |= SSL_TMP_KEY_INIT_DH(512); \ | 90 R |= SSL_TMP_KEY_INIT_DH(512); \ |
82 R |= SSL_TMP_KEY_INIT_DH(1024); \ | 91 R |= SSL_TMP_KEY_INIT_DH(1024); \ |
83 R |= SSL_TMP_KEY_INIT_DH(2048); \ | 92 R |= SSL_TMP_KEY_INIT_DH(2048); \ |
84 R |= SSL_TMP_KEY_INIT_DH(4096) | 93 R |= SSL_TMP_KEY_INIT_DH(4096) |
85 | 94 |
86 /* | 95 /* |
87 * supported_ssl_opts is a bitmask that contains all supported SSL_OP_* | 96 * supported_ssl_opts is a bitmask that contains all supported SSL_OP_* |
88 * options at compile-time. This is used in hasOp to determine which | 97 * options at compile-time. This is used in hasOp to determine which |
89 * SSL_OP_* options are available at runtime. | 98 * SSL_OP_* options are available at runtime. |
90 * | 99 * |
(...skipping 22 matching lines...) Expand all Loading... |
113 #endif | 122 #endif |
114 | 123 |
115 #ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG | 124 #ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG |
116 | SSL_OP_CRYPTOPRO_TLSEXT_BUG | 125 | SSL_OP_CRYPTOPRO_TLSEXT_BUG |
117 #endif | 126 #endif |
118 | 127 |
119 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | 128 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
120 | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | 129 | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
121 #endif | 130 #endif |
122 | 131 |
123 #ifdef SSL_OP_EPHEMERAL_RSA | |
124 | SSL_OP_EPHEMERAL_RSA | |
125 #endif | |
126 | |
127 #ifdef SSL_OP_LEGACY_SERVER_CONNECT | 132 #ifdef SSL_OP_LEGACY_SERVER_CONNECT |
128 | SSL_OP_LEGACY_SERVER_CONNECT | 133 | SSL_OP_LEGACY_SERVER_CONNECT |
129 #endif | 134 #endif |
130 | 135 |
131 #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER | 136 #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER |
132 | SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER | 137 | SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER |
133 #endif | 138 #endif |
134 | 139 |
135 #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG | 140 #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG |
136 | SSL_OP_MICROSOFT_SESS_ID_BUG | 141 | SSL_OP_MICROSOFT_SESS_ID_BUG |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 227 |
223 #ifdef SSL_OP_TLS_D5_BUG | 228 #ifdef SSL_OP_TLS_D5_BUG |
224 | SSL_OP_TLS_D5_BUG | 229 | SSL_OP_TLS_D5_BUG |
225 #endif | 230 #endif |
226 | 231 |
227 #ifdef SSL_OP_TLS_ROLLBACK_BUG | 232 #ifdef SSL_OP_TLS_ROLLBACK_BUG |
228 | SSL_OP_TLS_ROLLBACK_BUG | 233 | SSL_OP_TLS_ROLLBACK_BUG |
229 #endif | 234 #endif |
230 | 0; | 235 | 0; |
231 | 236 |
232 static int ssl_tmp_key_init_rsa(int bits, int idx) | 237 static jint tcn_flush_sslbuffer_to_bytebuffer(struct TCN_bio_bytebuffer* bioUser
Data) { |
233 { | 238 jint writeAmount = TCN_MIN(bioUserData->bufferLength, bioUserData->nonApplic
ationBufferLength) * sizeof(char); |
234 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) | 239 jint writeChunk = bioUserData->nonApplicationBufferSize - bioUserData->nonAp
plicationBufferOffset; |
235 return 0; | 240 |
| 241 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 242 fprintf(stderr, "tcn_flush_sslbuffer_to_bytebuffer1 bioUserData->nonApplicat
ionBufferLength %d bioUserData->nonApplicationBufferOffset %d writeChunk %d writ
eAmount %d\n", bioUserData->nonApplicationBufferLength, bioUserData->nonApplicat
ionBufferOffset, writeChunk, writeAmount); |
| 243 #endif |
| 244 |
| 245 // check if we need to account for wrap around when draining the internal SS
L buffer. |
| 246 if (writeAmount > writeChunk) { |
| 247 jint newnonApplicationBufferOffset = writeAmount - writeChunk; |
| 248 memcpy(bioUserData->buffer, &bioUserData->nonApplicationBuffer[bioUserDa
ta->nonApplicationBufferOffset], (size_t) writeChunk); |
| 249 memcpy(&bioUserData->buffer[writeChunk], bioUserData->nonApplicationBuff
er, (size_t) newnonApplicationBufferOffset); |
| 250 bioUserData->nonApplicationBufferOffset = newnonApplicationBufferOffset; |
| 251 } else { |
| 252 memcpy(bioUserData->buffer, &bioUserData->nonApplicationBuffer[bioUserDa
ta->nonApplicationBufferOffset], (size_t) writeAmount); |
| 253 bioUserData->nonApplicationBufferOffset += writeAmount; |
| 254 } |
| 255 bioUserData->nonApplicationBufferLength -= writeAmount; |
| 256 bioUserData->bufferLength -= writeAmount; |
| 257 bioUserData->buffer += writeAmount; // Pointer arithmetic based on char* typ
e |
| 258 |
| 259 if (bioUserData->nonApplicationBufferLength == 0) { |
| 260 bioUserData->nonApplicationBufferOffset = 0; |
| 261 } |
| 262 |
| 263 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 264 fprintf(stderr, "tcn_flush_sslbuffer_to_bytebuffer2 bioUserData->nonApplicat
ionBufferLength %d bioUserData->nonApplicationBufferOffset %d\n", bioUserData->n
onApplicationBufferLength, bioUserData->nonApplicationBufferOffset); |
| 265 #endif |
| 266 |
| 267 return writeAmount; |
| 268 } |
| 269 |
| 270 static jint tcn_write_to_bytebuffer(BIO* bio, const char* in, int inl) { |
| 271 jint writeAmount = 0; |
| 272 jint writeChunk; |
| 273 struct TCN_bio_bytebuffer* bioUserData = (struct TCN_bio_bytebuffer*) BIO_ge
t_data(bio); |
| 274 TCN_ASSERT(bioUserData != NULL); |
| 275 |
| 276 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 277 fprintf(stderr, "tcn_write_to_bytebuffer bioUserData->bufferIsSSLWriteSink %
d inl %d [%.*s]\n", bioUserData->bufferIsSSLWriteSink, inl, inl, in); |
| 278 #endif |
| 279 |
| 280 if (in == NULL || inl <= 0) { |
| 281 return 0; |
| 282 } |
| 283 |
| 284 // If the buffer is currently being used for reading then we have to use the
internal SSL buffer to queue the data. |
| 285 if (!bioUserData->bufferIsSSLWriteSink) { |
| 286 jint nonApplicationBufferFreeSpace = bioUserData->nonApplicationBufferSi
ze - bioUserData->nonApplicationBufferLength; |
| 287 jint startIndex; |
| 288 |
| 289 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 290 fprintf(stderr, "tcn_write_to_bytebuffer nonApplicationBufferFreeSpace %d
\n", nonApplicationBufferFreeSpace); |
| 291 #endif |
| 292 if (nonApplicationBufferFreeSpace == 0) { |
| 293 BIO_set_retry_write(bio); /* buffer is full */ |
| 294 return -1; |
| 295 } |
| 296 |
| 297 writeAmount = TCN_MIN(nonApplicationBufferFreeSpace, (jint) inl) * sizeo
f(char); |
| 298 startIndex = bioUserData->nonApplicationBufferOffset + bioUserData->nonA
pplicationBufferLength; |
| 299 writeChunk = bioUserData->nonApplicationBufferSize - startIndex; |
| 300 |
| 301 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 302 fprintf(stderr, "tcn_write_to_bytebuffer bioUserData->nonApplicationBuff
erLength %d bioUserData->nonApplicationBufferOffset %d startIndex %d writeChunk
%d writeAmount %d\n", bioUserData->nonApplicationBufferLength, bioUserData->nonA
pplicationBufferOffset, startIndex, writeChunk, writeAmount); |
| 303 #endif |
| 304 |
| 305 // check if the write will wrap around the buffer. |
| 306 if (writeAmount > writeChunk) { |
| 307 memcpy(&bioUserData->nonApplicationBuffer[startIndex], in, (size_t)
writeChunk); |
| 308 memcpy(bioUserData->nonApplicationBuffer, &in[writeChunk], (size_t)
(writeAmount - writeChunk)); |
| 309 } else { |
| 310 memcpy(&bioUserData->nonApplicationBuffer[startIndex], in, (size_t)
writeAmount); |
| 311 } |
| 312 bioUserData->nonApplicationBufferLength += writeAmount; |
| 313 // This write amount will not be used by Java, and doesn't correlate to
the ByteBuffer source. |
| 314 // The internal SSL buffer exists because a SSL_read operation may actua
lly write data (e.g. handshake). |
| 315 return writeAmount; |
| 316 } |
| 317 |
| 318 if (bioUserData->buffer == NULL || bioUserData->bufferLength == 0) { |
| 319 BIO_set_retry_write(bio); /* no buffer to write into */ |
| 320 return -1; |
| 321 } |
| 322 |
| 323 // First check if we need to drain data queued in the internal SSL buffer. |
| 324 if (bioUserData->nonApplicationBufferLength != 0) { |
| 325 writeAmount = tcn_flush_sslbuffer_to_bytebuffer(bioUserData); |
| 326 } |
| 327 |
| 328 // Next write "in" into what ever space the ByteBuffer has available. |
| 329 writeChunk = TCN_MIN(bioUserData->bufferLength, (jint) inl) * sizeof(char); |
| 330 |
| 331 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 332 fprintf(stderr, "tcn_write_to_bytebuffer2 writeChunk %d\n", writeChunk); |
| 333 #endif |
| 334 |
| 335 memcpy(bioUserData->buffer, in, (size_t) writeChunk); |
| 336 bioUserData->bufferLength -= writeChunk; |
| 337 bioUserData->buffer += writeChunk; // Pointer arithmetic based on char* type |
| 338 |
| 339 return writeAmount + writeChunk; |
| 340 } |
| 341 |
| 342 static jint tcn_read_from_bytebuffer(BIO* bio, char *out, int outl) { |
| 343 jint readAmount; |
| 344 struct TCN_bio_bytebuffer* bioUserData = (struct TCN_bio_bytebuffer*) BIO_ge
t_data(bio); |
| 345 TCN_ASSERT(bioUserData != NULL); |
| 346 |
| 347 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 348 fprintf(stderr, "tcn_read_from_bytebuffer bioUserData->bufferIsSSLWriteSink
%d outl %d [%.*s]\n", bioUserData->bufferIsSSLWriteSink, outl, outl, out); |
| 349 #endif |
| 350 |
| 351 if (out == NULL || outl <= 0) { |
| 352 return 0; |
| 353 } |
| 354 |
| 355 if (bioUserData->bufferIsSSLWriteSink || bioUserData->buffer == NULL || bioU
serData->bufferLength == 0) { |
| 356 // During handshake this may happen, and it means we are not setup to re
ad yet. |
| 357 BIO_set_retry_read(bio); |
| 358 return -1; |
| 359 } |
| 360 |
| 361 readAmount = TCN_MIN(bioUserData->bufferLength, (jint) outl) * sizeof(char); |
| 362 |
| 363 #ifdef NETTY_TCNATIVE_BIO_DEBUG |
| 364 fprintf(stderr, "tcn_read_from_bytebuffer readAmount %d\n", readAmount); |
| 365 #endif |
| 366 |
| 367 memcpy(out, bioUserData->buffer, (size_t) readAmount); |
| 368 bioUserData->bufferLength -= readAmount; |
| 369 bioUserData->buffer += readAmount; // Pointer arithmetic based on char* type |
| 370 |
| 371 return readAmount; |
| 372 } |
| 373 |
| 374 static int bio_java_bytebuffer_create(BIO* bio) { |
| 375 struct TCN_bio_bytebuffer* bioUserData = (struct TCN_bio_bytebuffer*) OPENSS
L_malloc(sizeof(struct TCN_bio_bytebuffer)); |
| 376 if (bioUserData == NULL) { |
| 377 return 0; |
| 378 } |
| 379 // The actual ByteBuffer is set from java and may be swapped out for each op
eration. |
| 380 bioUserData->buffer = NULL; |
| 381 bioUserData->bufferLength = 0; |
| 382 bioUserData->bufferIsSSLWriteSink = false; |
| 383 bioUserData->nonApplicationBuffer = NULL; |
| 384 bioUserData->nonApplicationBufferSize = 0; |
| 385 bioUserData->nonApplicationBufferOffset = 0; |
| 386 bioUserData->nonApplicationBufferLength = 0; |
| 387 |
| 388 BIO_set_data(bio, bioUserData); |
| 389 |
| 390 // In order to for OpenSSL to properly manage the lifetime of a BIO it relie
s on some shutdown and init state. |
| 391 // The behavior expected by OpenSSL can be found here: https://www.openssl.o
rg/docs/man1.1.0/crypto/BIO_set_data.html |
| 392 BIO_set_shutdown(bio, 1); |
| 393 BIO_set_init(bio, 1); |
| 394 |
| 395 return 1; |
| 396 } |
| 397 |
| 398 static int bio_java_bytebuffer_destroy(BIO* bio) { |
| 399 struct TCN_bio_bytebuffer* bioUserData; |
| 400 |
| 401 if (bio == NULL) { |
| 402 return 0; |
| 403 } |
| 404 |
| 405 bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(bio); |
| 406 if (bioUserData == NULL) { |
| 407 return 1; |
| 408 } |
| 409 |
| 410 if (bioUserData->nonApplicationBuffer != NULL) { |
| 411 OPENSSL_free(bioUserData->nonApplicationBuffer); |
| 412 bioUserData->nonApplicationBuffer = NULL; |
| 413 } |
| 414 |
| 415 // The buffer is not owned by tcn, so just free the native memory. |
| 416 OPENSSL_free(bioUserData); |
| 417 BIO_set_data(bio, NULL); |
| 418 |
| 419 return 1; |
| 420 } |
| 421 |
| 422 static int bio_java_bytebuffer_write(BIO* bio, const char* in, int inl) { |
| 423 BIO_clear_retry_flags(bio); |
| 424 return (int) tcn_write_to_bytebuffer(bio, in, inl); |
| 425 } |
| 426 |
| 427 static int bio_java_bytebuffer_read(BIO* bio, char* out, int outl) { |
| 428 BIO_clear_retry_flags(bio); |
| 429 return (int) tcn_read_from_bytebuffer(bio, out, outl); |
| 430 } |
| 431 |
| 432 static int bio_java_bytebuffer_puts(BIO* bio, const char *in) { |
| 433 BIO_clear_retry_flags(bio); |
| 434 return (int) tcn_write_to_bytebuffer(bio, in, strlen(in)); |
| 435 } |
| 436 |
| 437 static int bio_java_bytebuffer_gets(BIO* b, char* out, int outl) { |
| 438 // Not supported https://www.openssl.org/docs/man1.0.2/crypto/BIO_write.html |
| 439 return -2; |
| 440 } |
| 441 |
| 442 static long bio_java_bytebuffer_ctrl(BIO* bio, int cmd, long num, void* ptr) { |
| 443 // see https://www.openssl.org/docs/man1.0.1/crypto/BIO_ctrl.html |
| 444 switch (cmd) { |
| 445 case BIO_CTRL_GET_CLOSE: |
| 446 return (long) BIO_get_shutdown(bio); |
| 447 case BIO_CTRL_SET_CLOSE: |
| 448 BIO_set_shutdown(bio, (int) num); |
| 449 return 1; |
| 450 case BIO_CTRL_FLUSH: |
| 451 return 1; |
| 452 default: |
| 453 return 0; |
| 454 } |
| 455 } |
| 456 |
| 457 TCN_IMPLEMENT_CALL(jint, SSL, bioLengthByteBuffer)(TCN_STDARGS, jlong bioAddress
) { |
| 458 BIO* bio = J2P(bioAddress, BIO*); |
| 459 struct TCN_bio_bytebuffer* bioUserData; |
| 460 |
| 461 if (bio == NULL) { |
| 462 tcn_ThrowException(e, "bio is null"); |
| 463 return 0; |
| 464 } |
| 465 |
| 466 bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(bio); |
| 467 return bioUserData == NULL ? 0 : bioUserData->bufferLength; |
| 468 } |
| 469 |
| 470 TCN_IMPLEMENT_CALL(jint, SSL, bioLengthNonApplication)(TCN_STDARGS, jlong bioAdd
ress) { |
| 471 BIO* bio = J2P(bioAddress, BIO*); |
| 472 struct TCN_bio_bytebuffer* bioUserData; |
| 473 |
| 474 if (bio == NULL) { |
| 475 tcn_ThrowException(e, "bio is null"); |
| 476 return 0; |
| 477 } |
| 478 |
| 479 bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(bio); |
| 480 return bioUserData == NULL ? 0 : bioUserData->nonApplicationBufferLength; |
| 481 } |
| 482 |
| 483 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
| 484 static BIO_METHOD bio_java_bytebuffer_methods = { |
| 485 BIO_TYPE_MEM, |
| 486 "Java ByteBuffer", |
| 487 bio_java_bytebuffer_write, |
| 488 bio_java_bytebuffer_read, |
| 489 bio_java_bytebuffer_puts, |
| 490 bio_java_bytebuffer_gets, |
| 491 bio_java_bytebuffer_ctrl, |
| 492 bio_java_bytebuffer_create, |
| 493 bio_java_bytebuffer_destroy, |
| 494 NULL |
| 495 }; |
236 #else | 496 #else |
237 | 497 static BIO_METHOD* bio_java_bytebuffer_methods = NULL; |
238 #ifdef OPENSSL_FIPS | 498 |
239 /** | 499 static void init_bio_methods(void) { |
240 * Short RSA keys cannot be generated in FIPS mode. | 500 bio_java_bytebuffer_methods = BIO_meth_new(BIO_TYPE_MEM, "Java ByteBuffer"); |
241 */ | 501 BIO_meth_set_write(bio_java_bytebuffer_methods, &bio_java_bytebuffer_write); |
242 if (bits < 1024) | 502 BIO_meth_set_read(bio_java_bytebuffer_methods, &bio_java_bytebuffer_read); |
243 return 0; | 503 BIO_meth_set_puts(bio_java_bytebuffer_methods, &bio_java_bytebuffer_puts); |
244 #endif | 504 BIO_meth_set_gets(bio_java_bytebuffer_methods, &bio_java_bytebuffer_gets); |
245 | 505 BIO_meth_set_ctrl(bio_java_bytebuffer_methods, &bio_java_bytebuffer_ctrl); |
246 BIGNUM *e = BN_new(); | 506 BIO_meth_set_create(bio_java_bytebuffer_methods, &bio_java_bytebuffer_create
); |
247 RSA *rsa = RSA_new(); | 507 BIO_meth_set_destroy(bio_java_bytebuffer_methods, &bio_java_bytebuffer_destr
oy); |
248 int ret = 1; | 508 } |
249 | 509 |
250 if (e == NULL || | 510 static void free_bio_methods(void) { |
251 rsa == NULL || | 511 BIO_meth_free(bio_java_bytebuffer_methods); |
252 !BN_set_word(e, RSA_F4) || | 512 } |
253 RSA_generate_key_ex(rsa, bits, e, NULL) != 1) { | 513 #endif |
254 goto err; | 514 |
255 } | 515 static BIO_METHOD* BIO_java_bytebuffer() { |
256 | 516 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
257 SSL_temp_keys[idx] = rsa; | 517 return &bio_java_bytebuffer_methods; |
258 rsa = NULL; | 518 #else |
259 ret = 0; | 519 return bio_java_bytebuffer_methods; |
260 | 520 #endif |
261 err: | |
262 BN_free(e); | |
263 RSA_free(rsa); | |
264 return ret; | |
265 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ | |
266 } | 521 } |
267 | 522 |
268 static int ssl_tmp_key_init_dh(int bits, int idx) | 523 static int ssl_tmp_key_init_dh(int bits, int idx) |
269 { | 524 { |
270 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(OPENSSL_USE_DEPRECATED) | 525 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(OPENSSL_USE_DEPRECATED) ||
defined(LIBRESSL_VERSION_NUMBER) |
271 if (!(SSL_temp_keys[idx] = | 526 return (SSL_temp_keys[idx] = SSL_dh_get_tmp_param(bits)) ? 0 : 1; |
272 SSL_dh_get_tmp_param(bits))) | |
273 return 1; | |
274 else | |
275 return 0; | |
276 #else | 527 #else |
277 return 0; | 528 return 0; |
278 #endif | 529 #endif |
279 } | 530 } |
280 | 531 |
281 | |
282 TCN_IMPLEMENT_CALL(jint, SSL, version)(TCN_STDARGS) | 532 TCN_IMPLEMENT_CALL(jint, SSL, version)(TCN_STDARGS) |
283 { | 533 { |
284 UNREFERENCED_STDARGS; | 534 UNREFERENCED_STDARGS; |
285 return (jint) SSLeay(); | 535 return OpenSSL_version_num(); |
286 } | 536 } |
287 | 537 |
288 TCN_IMPLEMENT_CALL(jstring, SSL, versionString)(TCN_STDARGS) | 538 TCN_IMPLEMENT_CALL(jstring, SSL, versionString)(TCN_STDARGS) |
289 { | 539 { |
290 UNREFERENCED(o); | 540 UNREFERENCED(o); |
291 return AJP_TO_JSTRING(SSLeay_version(SSLEAY_VERSION)); | 541 return AJP_TO_JSTRING(OpenSSL_version(OPENSSL_VERSION)); |
292 } | 542 } |
293 | 543 |
294 /* | 544 /* |
295 * the various processing hooks | 545 * the various processing hooks |
296 */ | 546 */ |
297 static apr_status_t ssl_init_cleanup(void *data) | 547 static apr_status_t ssl_init_cleanup(void *data) |
298 { | 548 { |
299 UNREFERENCED(data); | 549 UNREFERENCED(data); |
300 | 550 |
301 if (!ssl_initialized) | 551 if (!ssl_initialized) |
302 return APR_SUCCESS; | 552 return APR_SUCCESS; |
303 ssl_initialized = 0; | 553 ssl_initialized = 0; |
304 | 554 |
305 if (tcn_password_callback.cb.obj) { | |
306 JNIEnv *env; | |
307 tcn_get_java_env(&env); | |
308 TCN_UNLOAD_CLASS(env, | |
309 tcn_password_callback.cb.obj); | |
310 } | |
311 | |
312 SSL_TMP_KEYS_FREE(RSA); | |
313 SSL_TMP_KEYS_FREE(DH); | 555 SSL_TMP_KEYS_FREE(DH); |
314 /* | 556 /* |
315 * Try to kill the internals of the SSL library. | 557 * Try to kill the internals of the SSL library. |
316 */ | 558 */ |
317 #if OPENSSL_VERSION_NUMBER >= 0x00907001 && !defined(OPENSSL_IS_BORINGSSL) | 559 #if OPENSSL_VERSION_NUMBER >= 0x00907001 && !defined(OPENSSL_IS_BORINGSSL) |
318 /* Corresponds to OPENSSL_load_builtin_modules(): | 560 /* Corresponds to OPENSSL_load_builtin_modules(): |
319 * XXX: borrowed from apps.h, but why not CONF_modules_free() | 561 * XXX: borrowed from apps.h, but why not CONF_modules_free() |
320 * which also invokes CONF_modules_finish()? | 562 * which also invokes CONF_modules_finish()? |
321 */ | 563 */ |
322 CONF_modules_unload(1); | 564 CONF_modules_unload(1); |
323 #endif | 565 #endif |
324 /* Corresponds to SSL_library_init: */ | 566 /* Corresponds to SSL_library_init: */ |
325 EVP_cleanup(); | 567 EVP_cleanup(); |
326 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES | 568 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES |
327 ENGINE_cleanup(); | 569 ENGINE_cleanup(); |
328 #endif | 570 #endif |
329 #if OPENSSL_VERSION_NUMBER >= 0x00907001 | 571 #if OPENSSL_VERSION_NUMBER >= 0x00907001 |
330 CRYPTO_cleanup_all_ex_data(); | 572 CRYPTO_cleanup_all_ex_data(); |
331 #endif | 573 #endif |
332 ERR_remove_state(0); | 574 #if OPENSSL_VERSION_NUMBER < 0x10100000L |
| 575 ERR_remove_thread_state(NULL); |
| 576 #endif |
| 577 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) |
| 578 free_bio_methods(); |
| 579 #endif |
333 | 580 |
334 /* Don't call ERR_free_strings here; ERR_load_*_strings only | 581 /* Don't call ERR_free_strings here; ERR_load_*_strings only |
335 * actually load the error strings once per process due to static | 582 * actually load the error strings once per process due to static |
336 * variable abuse in OpenSSL. */ | 583 * variable abuse in OpenSSL. */ |
337 | 584 |
338 /* | 585 /* |
339 * TODO: determine somewhere we can safely shove out diagnostics | 586 * TODO: determine somewhere we can safely shove out diagnostics |
340 * (when enabled) at this late stage in the game: | 587 * (when enabled) at this late stage in the game: |
341 * CRYPTO_mem_leaks_fp(stderr); | 588 * CRYPTO_mem_leaks_fp(stderr); |
342 */ | 589 */ |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 } *psaptr = 0; | 641 } *psaptr = 0; |
395 | 642 |
396 return psaptr->PSATOLD; | 643 return psaptr->PSATOLD; |
397 #elif defined(WIN32) | 644 #elif defined(WIN32) |
398 return (unsigned long)GetCurrentThreadId(); | 645 return (unsigned long)GetCurrentThreadId(); |
399 #else | 646 #else |
400 return (unsigned long)(apr_os_thread_current()); | 647 return (unsigned long)(apr_os_thread_current()); |
401 #endif | 648 #endif |
402 } | 649 } |
403 | 650 |
| 651 static void ssl_set_thread_id(CRYPTO_THREADID *id) |
| 652 { |
| 653 CRYPTO_THREADID_set_numeric(id, ssl_thread_id()); |
| 654 } |
| 655 |
404 static apr_status_t ssl_thread_cleanup(void *data) | 656 static apr_status_t ssl_thread_cleanup(void *data) |
405 { | 657 { |
406 UNREFERENCED(data); | 658 UNREFERENCED(data); |
407 CRYPTO_set_locking_callback(NULL); | 659 CRYPTO_set_locking_callback(NULL); |
408 CRYPTO_set_id_callback(NULL); | 660 CRYPTO_THREADID_set_callback(NULL); |
409 CRYPTO_set_dynlock_create_callback(NULL); | 661 CRYPTO_set_dynlock_create_callback(NULL); |
410 CRYPTO_set_dynlock_lock_callback(NULL); | 662 CRYPTO_set_dynlock_lock_callback(NULL); |
411 CRYPTO_set_dynlock_destroy_callback(NULL); | 663 CRYPTO_set_dynlock_destroy_callback(NULL); |
412 | 664 |
413 dynlockpool = NULL; | 665 dynlockpool = NULL; |
414 | 666 |
415 /* Let the registered mutex cleanups do their own thing | 667 /* Let the registered mutex cleanups do their own thing |
416 */ | 668 */ |
417 return APR_SUCCESS; | 669 return APR_SUCCESS; |
418 } | 670 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 } | 711 } |
460 return value; | 712 return value; |
461 } | 713 } |
462 | 714 |
463 /* | 715 /* |
464 * Dynamic locking and unlocking function | 716 * Dynamic locking and unlocking function |
465 */ | 717 */ |
466 static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, | 718 static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, |
467 const char *file, int line) | 719 const char *file, int line) |
468 { | 720 { |
469 | |
470 | |
471 if (mode & CRYPTO_LOCK) { | 721 if (mode & CRYPTO_LOCK) { |
472 apr_thread_mutex_lock(l->mutex); | 722 apr_thread_mutex_lock(l->mutex); |
473 } | 723 } |
474 else { | 724 else { |
475 apr_thread_mutex_unlock(l->mutex); | 725 apr_thread_mutex_unlock(l->mutex); |
476 } | 726 } |
477 } | 727 } |
478 | 728 |
479 /* | 729 /* |
480 * Dynamic lock destruction callback | 730 * Dynamic lock destruction callback |
481 */ | 731 */ |
482 static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, | 732 static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, |
483 const char *file, int line) | 733 const char *file, int line) |
484 { | 734 { |
485 apr_status_t rv; | 735 apr_status_t rv; |
486 rv = apr_thread_mutex_destroy(l->mutex); | 736 rv = apr_thread_mutex_destroy(l->mutex); |
487 if (rv != APR_SUCCESS) { | 737 if (rv != APR_SUCCESS) { |
488 /* TODO log that fprintf(stderr, "Failed to destroy mutex for dynamic lo
ck %s:%d", l->file, l->line); */ | 738 /* TODO log that fprintf(stderr, "Failed to destroy mutex for dynamic lo
ck %s:%d", l->file, l->line); */ |
489 } | 739 } |
490 | 740 |
491 /* Trust that whomever owned the CRYPTO_dynlock_value we were | 741 /* Trust that whomever owned the CRYPTO_dynlock_value we were |
492 * passed has no future use for it... | 742 * passed has no future use for it... |
493 */ | 743 */ |
494 apr_pool_destroy(l->pool); | 744 apr_pool_destroy(l->pool); |
495 } | 745 } |
| 746 |
496 static void ssl_thread_setup(apr_pool_t *p) | 747 static void ssl_thread_setup(apr_pool_t *p) |
497 { | 748 { |
498 int i; | 749 int i; |
499 | 750 |
500 ssl_lock_num_locks = CRYPTO_num_locks(); | 751 ssl_lock_num_locks = CRYPTO_num_locks(); |
501 ssl_lock_cs = apr_palloc(p, ssl_lock_num_locks * sizeof(*ssl_lock_cs)); | 752 ssl_lock_cs = apr_palloc(p, ssl_lock_num_locks * sizeof(*ssl_lock_cs)); |
502 | 753 |
503 for (i = 0; i < ssl_lock_num_locks; i++) { | 754 for (i = 0; i < ssl_lock_num_locks; i++) { |
504 apr_thread_mutex_create(&(ssl_lock_cs[i]), | 755 apr_thread_mutex_create(&(ssl_lock_cs[i]), |
505 APR_THREAD_MUTEX_DEFAULT, p); | 756 APR_THREAD_MUTEX_DEFAULT, p); |
506 } | 757 } |
507 | 758 |
508 CRYPTO_set_id_callback(ssl_thread_id); | 759 CRYPTO_THREADID_set_callback(ssl_set_thread_id); |
509 CRYPTO_set_locking_callback(ssl_thread_lock); | 760 CRYPTO_set_locking_callback(ssl_thread_lock); |
510 | 761 |
511 /* Set up dynamic locking scaffolding for OpenSSL to use at its | 762 /* Set up dynamic locking scaffolding for OpenSSL to use at its |
512 * convenience. | 763 * convenience. |
513 */ | 764 */ |
514 dynlockpool = p; | 765 dynlockpool = p; |
515 CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function); | 766 CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function); |
516 CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function); | 767 CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function); |
517 CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function); | 768 CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function); |
518 | 769 |
519 apr_pool_cleanup_register(p, NULL, ssl_thread_cleanup, | 770 apr_pool_cleanup_register(p, NULL, ssl_thread_cleanup, |
520 apr_pool_cleanup_null); | 771 apr_pool_cleanup_null); |
521 } | 772 } |
522 | 773 |
523 static int ssl_rand_choosenum(int l, int h) | |
524 { | |
525 int i; | |
526 char buf[50]; | |
527 | |
528 apr_snprintf(buf, sizeof(buf), "%.0f", | |
529 (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l))); | |
530 i = atoi(buf)+1; | |
531 if (i < l) i = l; | |
532 if (i > h) i = h; | |
533 return i; | |
534 } | |
535 | |
536 static int ssl_rand_load_file(const char *file) | |
537 { | |
538 int n; | |
539 | |
540 if (file == NULL) | |
541 file = ssl_global_rand_file; | |
542 if (file && (strcmp(file, "builtin") == 0)) | |
543 return -1; | |
544 // BoringSsl doesn't support RAND_file_name, but RAND_status() returns 1 anyways | |
545 #ifndef OPENSSL_IS_BORINGSSL | |
546 if (file == NULL) { | |
547 char buffer[APR_PATH_MAX]; | |
548 file = RAND_file_name(buffer, sizeof(buffer)); | |
549 } | |
550 #endif | |
551 if (file) { | |
552 #ifdef HAVE_SSL_RAND_EGD | |
553 if (strncmp(file, "egd:", 4) == 0) { | |
554 if ((n = RAND_egd(file + 4)) > 0) | |
555 return n; | |
556 else | |
557 return -1; | |
558 } | |
559 #endif | |
560 if ((n = RAND_load_file(file, -1)) > 0) | |
561 return n; | |
562 } | |
563 return -1; | |
564 } | |
565 | |
566 /* | |
567 * writes a number of random bytes (currently 1024) to | |
568 * file which can be used to initialize the PRNG by calling | |
569 * RAND_load_file() in a later session | |
570 */ | |
571 static int ssl_rand_save_file(const char *file) | |
572 { | |
573 #ifndef OPENSSL_IS_BORINGSSL | |
574 char buffer[APR_PATH_MAX]; | |
575 int n; | |
576 if (file == NULL) { | |
577 file = RAND_file_name(buffer, sizeof(buffer)); | |
578 #ifdef HAVE_SSL_RAND_EGD | |
579 } else if ((n = RAND_egd(file)) > 0) { | |
580 return 0; | |
581 #endif | |
582 } | |
583 if (file == NULL || !RAND_write_file(file)) | |
584 return 0; | |
585 else | |
586 return 1; | |
587 #else | |
588 // BoringSsl doesn't have RAND_file_name/RAND_write_file and RAND_egd always
return 255 | |
589 return 0; | |
590 #endif | |
591 } | |
592 | |
593 int SSL_rand_seed(const char *file) | |
594 { | |
595 unsigned char stackdata[256]; | |
596 static volatile apr_uint32_t counter = 0; | |
597 | |
598 if (ssl_rand_load_file(file) < 0) { | |
599 int n; | |
600 struct { | |
601 apr_time_t t; | |
602 pid_t p; | |
603 unsigned long i; | |
604 apr_uint32_t u; | |
605 } _ssl_seed; | |
606 if (counter == 0) { | |
607 apr_generate_random_bytes(stackdata, 256); | |
608 RAND_seed(stackdata, 128); | |
609 } | |
610 _ssl_seed.t = apr_time_now(); | |
611 _ssl_seed.p = getpid(); | |
612 _ssl_seed.i = ssl_thread_id(); | |
613 apr_atomic_inc32(&counter); | |
614 _ssl_seed.u = counter; | |
615 RAND_seed((unsigned char *)&_ssl_seed, sizeof(_ssl_seed)); | |
616 /* | |
617 * seed in some current state of the run-time stack (128 bytes) | |
618 */ | |
619 n = ssl_rand_choosenum(0, sizeof(stackdata)-128-1); | |
620 RAND_seed(stackdata + n, 128); | |
621 } | |
622 return RAND_status(); | |
623 } | |
624 | |
625 TCN_IMPLEMENT_CALL(jint, SSL, initialize)(TCN_STDARGS, jstring engine) | 774 TCN_IMPLEMENT_CALL(jint, SSL, initialize)(TCN_STDARGS, jstring engine) |
626 { | 775 { |
627 int r = 0; | 776 int r = 0; |
628 jclass clazz; | |
629 jclass sClazz; | |
630 | 777 |
631 TCN_ALLOC_CSTRING(engine); | 778 TCN_ALLOC_CSTRING(engine); |
632 | 779 |
633 UNREFERENCED(o); | 780 UNREFERENCED(o); |
634 if (!tcn_global_pool) { | 781 if (!tcn_global_pool) { |
635 TCN_FREE_CSTRING(engine); | 782 TCN_FREE_CSTRING(engine); |
636 tcn_ThrowAPRException(e, APR_EINVAL); | 783 tcn_ThrowAPRException(e, APR_EINVAL); |
637 return (jint)APR_EINVAL; | 784 return (jint)APR_EINVAL; |
638 } | 785 } |
639 /* Check if already initialized */ | 786 /* Check if already initialized */ |
640 if (ssl_initialized++) { | 787 if (ssl_initialized++) { |
641 TCN_FREE_CSTRING(engine); | 788 TCN_FREE_CSTRING(engine); |
642 return (jint)APR_SUCCESS; | 789 return (jint)APR_SUCCESS; |
643 } | 790 } |
644 | 791 |
| 792 #if OPENSSL_VERSION_NUMBER < 0x10100000L |
645 if (SSLeay() < 0x0090700L) { | 793 if (SSLeay() < 0x0090700L) { |
646 TCN_FREE_CSTRING(engine); | 794 TCN_FREE_CSTRING(engine); |
647 tcn_ThrowAPRException(e, APR_EINVAL); | 795 tcn_ThrowAPRException(e, APR_EINVAL); |
648 ssl_initialized = 0; | 796 ssl_initialized = 0; |
649 return (jint)APR_EINVAL; | 797 return (jint)APR_EINVAL; |
650 } | 798 } |
| 799 #endif |
651 | 800 |
652 #ifndef OPENSSL_IS_BORINGSSL | 801 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
653 /* We must register the library in full, to ensure our configuration | 802 /* We must register the library in full, to ensure our configuration |
654 * code can successfully test the SSL environment. | 803 * code can successfully test the SSL environment. |
655 */ | 804 */ |
656 CRYPTO_malloc_init(); | 805 OPENSSL_malloc_init(); |
657 #endif | 806 #endif |
658 | 807 |
659 ERR_load_crypto_strings(); | 808 ERR_load_crypto_strings(); |
660 SSL_load_error_strings(); | 809 SSL_load_error_strings(); |
661 SSL_library_init(); | 810 SSL_library_init(); |
662 OpenSSL_add_all_algorithms(); | 811 OpenSSL_add_all_algorithms(); |
663 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES | 812 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES |
664 ENGINE_load_builtin_engines(); | 813 ENGINE_load_builtin_engines(); |
665 #endif | 814 #endif |
666 #if OPENSSL_VERSION_NUMBER >= 0x00907001 && !defined(OPENSSL_IS_BORINGSSL) | 815 #if OPENSSL_VERSION_NUMBER >= 0x00907001 |
667 OPENSSL_load_builtin_modules(); | 816 OPENSSL_load_builtin_modules(); |
668 #endif | 817 #endif |
669 | 818 |
670 /* Initialize thread support */ | 819 /* Initialize thread support */ |
671 ssl_thread_setup(tcn_global_pool); | 820 ssl_thread_setup(tcn_global_pool); |
672 | 821 |
673 #ifndef OPENSSL_NO_ENGINE | 822 #ifndef OPENSSL_NO_ENGINE |
674 if (J2S(engine)) { | 823 if (J2S(engine)) { |
675 ENGINE *ee = NULL; | 824 ENGINE *ee = NULL; |
676 apr_status_t err = APR_SUCCESS; | 825 apr_status_t err = APR_SUCCESS; |
(...skipping 19 matching lines...) Expand all Loading... |
696 if (err != APR_SUCCESS) { | 845 if (err != APR_SUCCESS) { |
697 TCN_FREE_CSTRING(engine); | 846 TCN_FREE_CSTRING(engine); |
698 ssl_init_cleanup(NULL); | 847 ssl_init_cleanup(NULL); |
699 tcn_ThrowAPRException(e, err); | 848 tcn_ThrowAPRException(e, err); |
700 return (jint)err; | 849 return (jint)err; |
701 } | 850 } |
702 tcn_ssl_engine = ee; | 851 tcn_ssl_engine = ee; |
703 } | 852 } |
704 #endif | 853 #endif |
705 | 854 |
706 memset(&tcn_password_callback, 0, sizeof(tcn_pass_cb_t)); | 855 // For SSL_get_app_data*() at request time |
707 /* Initialize PRNG | 856 SSL_init_app_data_idx(); |
708 * This will in most cases call the builtin | 857 |
709 * low entropy seed. | 858 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) |
710 */ | 859 init_bio_methods(); |
711 SSL_rand_seed(NULL); | 860 #endif |
712 /* For SSL_get_app_data2() and SSL_get_app_data3() at request time */ | |
713 SSL_init_app_data2_3_idx(); | |
714 | 861 |
715 SSL_TMP_KEYS_INIT(r); | 862 SSL_TMP_KEYS_INIT(r); |
716 if (r) { | 863 if (r) { |
| 864 ERR_clear_error(); |
717 TCN_FREE_CSTRING(engine); | 865 TCN_FREE_CSTRING(engine); |
718 ssl_init_cleanup(NULL); | 866 ssl_init_cleanup(NULL); |
719 tcn_ThrowAPRException(e, APR_ENOTIMPL); | 867 tcn_ThrowAPRException(e, APR_ENOTIMPL); |
720 return APR_ENOTIMPL; | 868 return APR_ENOTIMPL; |
721 } | 869 } |
722 /* | 870 /* |
723 * Let us cleanup the ssl library when the library is unloaded | 871 * Let us cleanup the ssl library when the library is unloaded |
724 */ | 872 */ |
725 apr_pool_cleanup_register(tcn_global_pool, NULL, | 873 apr_pool_cleanup_register(tcn_global_pool, NULL, |
726 ssl_init_cleanup, | 874 ssl_init_cleanup, |
727 apr_pool_cleanup_null); | 875 apr_pool_cleanup_null); |
728 TCN_FREE_CSTRING(engine); | 876 TCN_FREE_CSTRING(engine); |
729 | 877 |
730 // Cache the byte[].class for performance reasons | |
731 clazz = (*e)->FindClass(e, "[B"); | |
732 byteArrayClass = (jclass) (*e)->NewGlobalRef(e, clazz); | |
733 | |
734 // Cache the String.class for performance reasons | |
735 sClazz = (*e)->FindClass(e, "java/lang/String"); | |
736 stringClass = (jclass) (*e)->NewGlobalRef(e, sClazz); | |
737 | |
738 return (jint)APR_SUCCESS; | 878 return (jint)APR_SUCCESS; |
739 } | 879 } |
740 | 880 |
741 TCN_IMPLEMENT_CALL(jboolean, SSL, randLoad)(TCN_STDARGS, jstring file) | |
742 { | |
743 TCN_ALLOC_CSTRING(file); | |
744 int r; | |
745 UNREFERENCED(o); | |
746 r = SSL_rand_seed(J2S(file)); | |
747 TCN_FREE_CSTRING(file); | |
748 return r ? JNI_TRUE : JNI_FALSE; | |
749 } | |
750 | |
751 TCN_IMPLEMENT_CALL(jboolean, SSL, randSave)(TCN_STDARGS, jstring file) | |
752 { | |
753 TCN_ALLOC_CSTRING(file); | |
754 int r; | |
755 UNREFERENCED(o); | |
756 r = ssl_rand_save_file(J2S(file)); | |
757 TCN_FREE_CSTRING(file); | |
758 return r ? JNI_TRUE : JNI_FALSE; | |
759 } | |
760 | |
761 TCN_IMPLEMENT_CALL(void, SSL, randSet)(TCN_STDARGS, jstring file) | |
762 { | |
763 TCN_ALLOC_CSTRING(file); | |
764 UNREFERENCED(o); | |
765 if (J2S(file)) { | |
766 ssl_global_rand_file = apr_pstrdup(tcn_global_pool, J2S(file)); | |
767 } | |
768 TCN_FREE_CSTRING(file); | |
769 } | |
770 | |
771 TCN_IMPLEMENT_CALL(jint, SSL, fipsModeGet)(TCN_STDARGS) | |
772 { | |
773 UNREFERENCED(o); | |
774 #ifdef OPENSSL_FIPS | |
775 return FIPS_mode(); | |
776 #else | |
777 /* FIPS is unavailable */ | |
778 tcn_ThrowException(e, "FIPS was not available to tcnative at build time. You
will need to re-build tcnative against an OpenSSL with FIPS."); | |
779 | |
780 return 0; | |
781 #endif | |
782 } | |
783 | |
784 TCN_IMPLEMENT_CALL(jint, SSL, fipsModeSet)(TCN_STDARGS, jint mode) | |
785 { | |
786 int r = 0; | |
787 UNREFERENCED(o); | |
788 | |
789 #ifdef OPENSSL_FIPS | |
790 if(1 != (r = (jint)FIPS_mode_set((int)mode))) { | |
791 /* arrange to get a human-readable error message */ | |
792 unsigned long err = ERR_get_error(); | |
793 char msg[256]; | |
794 | |
795 /* ERR_load_crypto_strings() already called in initialize() */ | |
796 | |
797 ERR_error_string_n(err, msg, 256); | |
798 | |
799 tcn_ThrowException(e, msg); | |
800 } | |
801 #else | |
802 /* FIPS is unavailable */ | |
803 tcn_ThrowException(e, "FIPS was not available to tcnative at build time. You
will need to re-build tcnative against an OpenSSL with FIPS."); | |
804 #endif | |
805 | |
806 return r; | |
807 } | |
808 | |
809 /* OpenSSL Java Stream BIO */ | |
810 | |
811 typedef struct { | |
812 int refcount; | |
813 apr_pool_t *pool; | |
814 tcn_callback_t cb; | |
815 } BIO_JAVA; | |
816 | |
817 | |
818 static apr_status_t generic_bio_cleanup(void *data) | |
819 { | |
820 BIO *b = (BIO *)data; | |
821 | |
822 if (b) { | |
823 BIO_free(b); | |
824 } | |
825 return APR_SUCCESS; | |
826 } | |
827 | |
828 void SSL_BIO_close(BIO *bi) | |
829 { | |
830 if (bi == NULL) | |
831 return; | |
832 if (bi->ptr != NULL && (bi->flags & SSL_BIO_FLAG_CALLBACK)) { | |
833 BIO_JAVA *j = (BIO_JAVA *)bi->ptr; | |
834 j->refcount--; | |
835 if (j->refcount == 0) { | |
836 if (j->pool) | |
837 apr_pool_cleanup_run(j->pool, bi, generic_bio_cleanup); | |
838 else | |
839 BIO_free(bi); | |
840 } | |
841 } | |
842 else | |
843 BIO_free(bi); | |
844 } | |
845 | |
846 void SSL_BIO_doref(BIO *bi) | |
847 { | |
848 if (bi == NULL) | |
849 return; | |
850 if (bi->ptr != NULL && (bi->flags & SSL_BIO_FLAG_CALLBACK)) { | |
851 BIO_JAVA *j = (BIO_JAVA *)bi->ptr; | |
852 j->refcount++; | |
853 } | |
854 } | |
855 | |
856 | |
857 static int jbs_new(BIO *bi) | |
858 { | |
859 BIO_JAVA *j; | |
860 | |
861 if ((j = OPENSSL_malloc(sizeof(BIO_JAVA))) == NULL) | |
862 return 0; | |
863 j->pool = NULL; | |
864 j->refcount = 1; | |
865 bi->shutdown = 1; | |
866 bi->init = 0; | |
867 bi->num = -1; | |
868 bi->ptr = (char *)j; | |
869 | |
870 return 1; | |
871 } | |
872 | |
873 static int jbs_free(BIO *bi) | |
874 { | |
875 JNIEnv *e = NULL; | |
876 BIO_JAVA *j; | |
877 | |
878 if (bi == NULL) | |
879 return 0; | |
880 if (bi->ptr != NULL) { | |
881 j = (BIO_JAVA *)bi->ptr; | |
882 if (bi->init) { | |
883 bi->init = 0; | |
884 tcn_get_java_env(&e); | |
885 TCN_UNLOAD_CLASS(e, j->cb.obj); | |
886 } | |
887 OPENSSL_free(bi->ptr); | |
888 } | |
889 bi->ptr = NULL; | |
890 return 1; | |
891 } | |
892 | |
893 static int jbs_write(BIO *b, const char *in, int inl) | |
894 { | |
895 jint ret = -1; | |
896 | |
897 if (b->init && in != NULL) { | |
898 BIO_JAVA *j = (BIO_JAVA *)b->ptr; | |
899 JNIEnv *e = NULL; | |
900 jbyteArray jb; | |
901 tcn_get_java_env(&e); | |
902 jb = (*e)->NewByteArray(e, inl); | |
903 if (!(*e)->ExceptionOccurred(e)) { | |
904 BIO_clear_retry_flags(b); | |
905 (*e)->SetByteArrayRegion(e, jb, 0, inl, (jbyte *)in); | |
906 ret = (*e)->CallIntMethod(e, j->cb.obj, | |
907 j->cb.mid[0], jb); | |
908 (*e)->DeleteLocalRef(e, jb); | |
909 } | |
910 } | |
911 if (ret == 0) { | |
912 BIO_set_retry_write(b); | |
913 ret = -1; | |
914 } | |
915 return ret; | |
916 } | |
917 | |
918 static int jbs_read(BIO *b, char *out, int outl) | |
919 { | |
920 jint ret = 0; | |
921 jbyte *jout; | |
922 | |
923 if (b->init && out != NULL) { | |
924 BIO_JAVA *j = (BIO_JAVA *)b->ptr; | |
925 JNIEnv *e = NULL; | |
926 jbyteArray jb; | |
927 tcn_get_java_env(&e); | |
928 jb = (*e)->NewByteArray(e, outl); | |
929 if (!(*e)->ExceptionOccurred(e)) { | |
930 BIO_clear_retry_flags(b); | |
931 ret = (*e)->CallIntMethod(e, j->cb.obj, | |
932 j->cb.mid[1], jb); | |
933 if (ret > 0) { | |
934 jout = (*e)->GetPrimitiveArrayCritical(e, jb, NULL); | |
935 memcpy(out, jout, ret); | |
936 (*e)->ReleasePrimitiveArrayCritical(e, jb, jout, 0); | |
937 } else if (outl != 0) { | |
938 ret = -1; | |
939 BIO_set_retry_read(b); | |
940 } | |
941 (*e)->DeleteLocalRef(e, jb); | |
942 } | |
943 } | |
944 return ret; | |
945 } | |
946 | |
947 static int jbs_puts(BIO *b, const char *in) | |
948 { | |
949 int ret = 0; | |
950 JNIEnv *e = NULL; | |
951 BIO_JAVA *j; | |
952 | |
953 if (b->init && in != NULL) { | |
954 j = (BIO_JAVA *)b->ptr; | |
955 tcn_get_java_env(&e); | |
956 ret = (*e)->CallIntMethod(e, j->cb.obj, | |
957 j->cb.mid[2], | |
958 tcn_new_string(e, in)); | |
959 } | |
960 return ret; | |
961 } | |
962 | |
963 static int jbs_gets(BIO *b, char *out, int outl) | |
964 { | |
965 int ret = 0; | |
966 JNIEnv *e = NULL; | |
967 BIO_JAVA *j; | |
968 jobject o; | |
969 int l; | |
970 | |
971 if (b->init && out != NULL) { | |
972 j = (BIO_JAVA *)b->ptr; | |
973 tcn_get_java_env(&e); | |
974 if ((o = (*e)->CallObjectMethod(e, j->cb.obj, | |
975 j->cb.mid[3], (jint)(outl - 1)))) { | |
976 TCN_ALLOC_CSTRING(o); | |
977 if (J2S(o)) { | |
978 l = (int)strlen(J2S(o)); | |
979 if (l < outl) { | |
980 strcpy(out, J2S(o)); | |
981 ret = outl; | |
982 } | |
983 } | |
984 TCN_FREE_CSTRING(o); | |
985 } | |
986 } | |
987 return ret; | |
988 } | |
989 | |
990 static long jbs_ctrl(BIO *b, int cmd, long num, void *ptr) | |
991 { | |
992 int ret = 0; | |
993 switch (cmd) { | |
994 case BIO_CTRL_FLUSH: | |
995 ret = 1; | |
996 break; | |
997 default: | |
998 ret = 0; | |
999 break; | |
1000 } | |
1001 return ret; | |
1002 } | |
1003 | |
1004 static BIO_METHOD jbs_methods = { | |
1005 BIO_TYPE_FILE, | |
1006 "Java Callback", | |
1007 jbs_write, | |
1008 jbs_read, | |
1009 jbs_puts, | |
1010 jbs_gets, | |
1011 jbs_ctrl, | |
1012 jbs_new, | |
1013 jbs_free, | |
1014 NULL | |
1015 }; | |
1016 | |
1017 static BIO_METHOD *BIO_jbs() | |
1018 { | |
1019 return(&jbs_methods); | |
1020 } | |
1021 | |
1022 | |
1023 TCN_IMPLEMENT_CALL(jlong, SSL, newMemBIO)(TCN_STDARGS) | 881 TCN_IMPLEMENT_CALL(jlong, SSL, newMemBIO)(TCN_STDARGS) |
1024 { | 882 { |
1025 BIO *bio = NULL; | 883 BIO *bio = NULL; |
1026 | 884 |
1027 UNREFERENCED(o); | 885 UNREFERENCED(o); |
1028 | 886 |
1029 // TODO: Use BIO_s_secmem() once included in stable release | 887 // TODO: Use BIO_s_secmem() once included in stable release |
1030 if ((bio = BIO_new(BIO_s_mem())) == NULL) { | 888 if ((bio = BIO_new(BIO_s_mem())) == NULL) { |
1031 tcn_ThrowException(e, "Create BIO failed"); | 889 tcn_ThrowException(e, "Create BIO failed"); |
1032 return (jlong) NULL; | 890 return 0; |
1033 } | 891 } |
1034 return P2J(bio); | 892 return P2J(bio); |
1035 } | 893 } |
1036 | 894 |
1037 TCN_IMPLEMENT_CALL(jlong, SSL, newBIO)(TCN_STDARGS, jlong pool, | |
1038 jobject callback) | |
1039 { | |
1040 BIO *bio = NULL; | |
1041 BIO_JAVA *j; | |
1042 jclass cls; | |
1043 | |
1044 UNREFERENCED(o); | |
1045 | |
1046 if ((bio = BIO_new(BIO_jbs())) == NULL) { | |
1047 tcn_ThrowException(e, "Create BIO failed"); | |
1048 goto init_failed; | |
1049 } | |
1050 j = (BIO_JAVA *)bio->ptr; | |
1051 if (j == NULL) { | |
1052 tcn_ThrowException(e, "Create BIO failed"); | |
1053 goto init_failed; | |
1054 } | |
1055 j->pool = J2P(pool, apr_pool_t *); | |
1056 if (j->pool) { | |
1057 apr_pool_cleanup_register(j->pool, (const void *)bio, | |
1058 generic_bio_cleanup, | |
1059 apr_pool_cleanup_null); | |
1060 } | |
1061 | |
1062 cls = (*e)->GetObjectClass(e, callback); | |
1063 j->cb.mid[0] = (*e)->GetMethodID(e, cls, "write", "([B)I"); | |
1064 j->cb.mid[1] = (*e)->GetMethodID(e, cls, "read", "([B)I"); | |
1065 j->cb.mid[2] = (*e)->GetMethodID(e, cls, "puts", "(Ljava/lang/String;)I"); | |
1066 j->cb.mid[3] = (*e)->GetMethodID(e, cls, "gets", "(I)Ljava/lang/String;"); | |
1067 /* TODO: Check if method id's are valid */ | |
1068 j->cb.obj = (*e)->NewGlobalRef(e, callback); | |
1069 | |
1070 bio->init = 1; | |
1071 bio->flags = SSL_BIO_FLAG_CALLBACK; | |
1072 return P2J(bio); | |
1073 init_failed: | |
1074 return 0; | |
1075 } | |
1076 | |
1077 | |
1078 TCN_IMPLEMENT_CALL(jint, SSL, closeBIO)(TCN_STDARGS, jlong bio) | |
1079 { | |
1080 BIO *b = J2P(bio, BIO *); | |
1081 | |
1082 UNREFERENCED_STDARGS; | |
1083 | |
1084 if (b != NULL) { | |
1085 SSL_BIO_close(b); | |
1086 } | |
1087 | |
1088 return APR_SUCCESS; | |
1089 } | |
1090 | |
1091 TCN_IMPLEMENT_CALL(void, SSL, setPasswordCallback)(TCN_STDARGS, | |
1092 jobject callback) | |
1093 { | |
1094 jclass cls; | |
1095 | |
1096 UNREFERENCED(o); | |
1097 if (tcn_password_callback.cb.obj) { | |
1098 TCN_UNLOAD_CLASS(e, | |
1099 tcn_password_callback.cb.obj); | |
1100 } | |
1101 cls = (*e)->GetObjectClass(e, callback); | |
1102 tcn_password_callback.cb.mid[0] = (*e)->GetMethodID(e, cls, "callback", | |
1103 "(Ljava/lang/String;)Ljava/lang/String;"); | |
1104 /* TODO: Check if method id is valid */ | |
1105 tcn_password_callback.cb.obj = (*e)->NewGlobalRef(e, callback); | |
1106 | |
1107 } | |
1108 | |
1109 TCN_IMPLEMENT_CALL(void, SSL, setPassword)(TCN_STDARGS, jstring password) | |
1110 { | |
1111 TCN_ALLOC_CSTRING(password); | |
1112 UNREFERENCED(o); | |
1113 if (J2S(password)) { | |
1114 strncpy(tcn_password_callback.password, J2S(password), SSL_MAX_PASSWORD_
LEN); | |
1115 tcn_password_callback.password[SSL_MAX_PASSWORD_LEN-1] = '\0'; | |
1116 } | |
1117 TCN_FREE_CSTRING(password); | |
1118 } | |
1119 | |
1120 TCN_IMPLEMENT_CALL(jboolean, SSL, generateRSATempKey)(TCN_STDARGS, jint idx) | |
1121 { | |
1122 int r = 1; | |
1123 UNREFERENCED_STDARGS; | |
1124 SSL_TMP_KEY_FREE(RSA, idx); | |
1125 switch (idx) { | |
1126 case SSL_TMP_KEY_RSA_512: | |
1127 r = SSL_TMP_KEY_INIT_RSA(512); | |
1128 break; | |
1129 case SSL_TMP_KEY_RSA_1024: | |
1130 r = SSL_TMP_KEY_INIT_RSA(1024); | |
1131 break; | |
1132 case SSL_TMP_KEY_RSA_2048: | |
1133 r = SSL_TMP_KEY_INIT_RSA(2048); | |
1134 break; | |
1135 case SSL_TMP_KEY_RSA_4096: | |
1136 r = SSL_TMP_KEY_INIT_RSA(4096); | |
1137 break; | |
1138 } | |
1139 return r ? JNI_FALSE : JNI_TRUE; | |
1140 } | |
1141 | |
1142 TCN_IMPLEMENT_CALL(jboolean, SSL, loadDSATempKey)(TCN_STDARGS, jint idx, | |
1143 jstring file) | |
1144 { | |
1145 jboolean r = JNI_FALSE; | |
1146 TCN_ALLOC_CSTRING(file); | |
1147 DH *dh; | |
1148 UNREFERENCED(o); | |
1149 | |
1150 if (!J2S(file)) | |
1151 return JNI_FALSE; | |
1152 SSL_TMP_KEY_FREE(DSA, idx); | |
1153 if ((dh = SSL_dh_get_param_from_file(J2S(file)))) { | |
1154 SSL_temp_keys[idx] = dh; | |
1155 r = JNI_TRUE; | |
1156 } | |
1157 TCN_FREE_CSTRING(file); | |
1158 return r; | |
1159 } | |
1160 | |
1161 TCN_IMPLEMENT_CALL(jstring, SSL, getLastError)(TCN_STDARGS) | 895 TCN_IMPLEMENT_CALL(jstring, SSL, getLastError)(TCN_STDARGS) |
1162 { | 896 { |
1163 char buf[256]; | 897 char buf[ERR_LEN]; |
1164 UNREFERENCED(o); | 898 UNREFERENCED(o); |
1165 ERR_error_string(ERR_get_error(), buf); | 899 ERR_error_string(ERR_get_error(), buf); |
1166 return tcn_new_string(e, buf); | 900 return tcn_new_string(e, buf); |
1167 } | 901 } |
1168 | 902 |
1169 TCN_IMPLEMENT_CALL(jboolean, SSL, hasOp)(TCN_STDARGS, jint op) | 903 TCN_IMPLEMENT_CALL(jboolean, SSL, hasOp)(TCN_STDARGS, jint op) |
1170 { | 904 { |
1171 return op == (op & supported_ssl_opts) ? JNI_TRUE : JNI_FALSE; | 905 return op == (op & supported_ssl_opts) ? JNI_TRUE : JNI_FALSE; |
1172 } | 906 } |
1173 | 907 |
(...skipping 24 matching lines...) Expand all Loading... |
1198 tcn_ThrowException(e, "ssl ctx is null"); | 932 tcn_ThrowException(e, "ssl ctx is null"); |
1199 return 0; | 933 return 0; |
1200 } | 934 } |
1201 if (c->ctx == NULL) { | 935 if (c->ctx == NULL) { |
1202 tcn_ThrowException(e, "ctx is null"); | 936 tcn_ThrowException(e, "ctx is null"); |
1203 return 0; | 937 return 0; |
1204 } | 938 } |
1205 | 939 |
1206 UNREFERENCED_STDARGS; | 940 UNREFERENCED_STDARGS; |
1207 | 941 |
1208 handshakeCount = malloc(sizeof(int)); | |
1209 ssl = SSL_new(c->ctx); | 942 ssl = SSL_new(c->ctx); |
1210 if (ssl == NULL) { | 943 if (ssl == NULL) { |
1211 tcn_ThrowException(e, "cannot create new ssl"); | 944 tcn_ThrowException(e, "cannot create new ssl"); |
1212 return 0; | 945 return 0; |
1213 } | 946 } |
1214 | 947 |
| 948 // Set the app_data2 before all the others because it may be used in SSL_fre
e. |
| 949 SSL_set_app_data2(ssl, c); |
| 950 |
| 951 // Initially we will share the configuration from the SSLContext. |
| 952 // Set this before other app_data because there is no chance of failure, and
if other app_data initialization fails |
| 953 // SSL_free maybe called and the state of this variable is assumed to be ini
talized. |
| 954 SSL_set_app_data4(ssl, &c->verify_config); |
| 955 |
1215 // Store the handshakeCount in the SSL instance. | 956 // Store the handshakeCount in the SSL instance. |
| 957 handshakeCount = (int*) OPENSSL_malloc(sizeof(int)); |
| 958 if (handshakeCount == NULL) { |
| 959 SSL_free(ssl); |
| 960 tcn_ThrowException(e, "cannot create handshakeCount user data"); |
| 961 return 0; |
| 962 } |
| 963 |
1216 *handshakeCount = 0; | 964 *handshakeCount = 0; |
1217 SSL_set_app_data3(ssl, handshakeCount); | 965 SSL_set_app_data3(ssl, handshakeCount); |
1218 | 966 |
1219 // Add callback to keep track of handshakes. | 967 // Add callback to keep track of handshakes. |
1220 SSL_CTX_set_info_callback(c->ctx, ssl_info_callback); | 968 SSL_CTX_set_info_callback(c->ctx, ssl_info_callback); |
1221 | 969 |
1222 if (server) { | 970 if (server) { |
1223 SSL_set_accept_state(ssl); | 971 SSL_set_accept_state(ssl); |
1224 } else { | 972 } else { |
1225 SSL_set_connect_state(ssl); | 973 SSL_set_connect_state(ssl); |
1226 } | 974 } |
1227 | 975 |
1228 // Setup verify and seed | |
1229 SSL_set_verify_result(ssl, X509_V_OK); | |
1230 SSL_rand_seed(c->rand_file); | |
1231 | |
1232 // Store for later usage in SSL_callback_SSL_verify | |
1233 SSL_set_app_data2(ssl, c); | |
1234 return P2J(ssl); | 976 return P2J(ssl); |
1235 } | 977 } |
1236 | 978 |
1237 TCN_IMPLEMENT_CALL(void, SSL, setBIO)(TCN_STDARGS, | |
1238 jlong ssl /* SSL * */, | |
1239 jlong rbio /* BIO * */, | |
1240 jlong wbio /* BIO * */) { | |
1241 SSL *ssl_ = J2P(ssl, SSL *); | |
1242 BIO *r = J2P(rbio, BIO *); | |
1243 BIO *w = J2P(wbio, BIO *); | |
1244 | |
1245 if (ssl_ == NULL) { | |
1246 tcn_ThrowException(e, "ssl is null"); | |
1247 return; | |
1248 } | |
1249 | |
1250 UNREFERENCED_STDARGS; | |
1251 | |
1252 SSL_set_bio(ssl_, r, w); | |
1253 } | |
1254 | |
1255 TCN_IMPLEMENT_CALL(jint, SSL, getError)(TCN_STDARGS, | 979 TCN_IMPLEMENT_CALL(jint, SSL, getError)(TCN_STDARGS, |
1256 jlong ssl /* SSL * */, | 980 jlong ssl /* SSL * */, |
1257 jint ret) { | 981 jint ret) { |
1258 SSL *ssl_ = J2P(ssl, SSL *); | 982 SSL *ssl_ = J2P(ssl, SSL *); |
1259 | 983 |
1260 if (ssl_ == NULL) { | 984 if (ssl_ == NULL) { |
1261 tcn_ThrowException(e, "ssl is null"); | 985 tcn_ThrowException(e, "ssl is null"); |
1262 return 0; | 986 return 0; |
1263 } | 987 } |
1264 | 988 |
1265 UNREFERENCED_STDARGS; | 989 UNREFERENCED_STDARGS; |
1266 | 990 |
1267 return SSL_get_error(ssl_, ret); | 991 return SSL_get_error(ssl_, ret); |
1268 } | 992 } |
1269 | 993 |
1270 // How much did SSL write into this BIO? | 994 // Write wlen bytes from wbuf into bio |
1271 TCN_IMPLEMENT_CALL(jint /* nbytes */, SSL, pendingWrittenBytesInBIO)(TCN_STDARGS
, | 995 TCN_IMPLEMENT_CALL(jint /* status */, SSL, bioWrite)(TCN_STDARGS, |
1272 jlong bio /
* BIO * */) { | 996 jlong bioAddress /* BIO* */
, |
1273 BIO *b = J2P(bio, BIO *); | 997 jlong wbufAddress /* char*
*/, |
| 998 jint wlen /* sizeof(wbuf) *
/) { |
| 999 BIO* bio = J2P(bioAddress, BIO*); |
| 1000 void* wbuf = J2P(wbufAddress, void*); |
1274 | 1001 |
1275 if (b == NULL) { | 1002 if (bio == NULL) { |
1276 tcn_ThrowException(e, "bio is null"); | 1003 tcn_ThrowException(e, "bio is null"); |
1277 return 0; | 1004 return 0; |
1278 } | 1005 } |
1279 | 1006 if (wbuf == NULL) { |
1280 UNREFERENCED_STDARGS; | |
1281 | |
1282 return BIO_ctrl_pending(b); | |
1283 } | |
1284 | |
1285 // How much is available for reading in the given SSL struct? | |
1286 TCN_IMPLEMENT_CALL(jint, SSL, pendingReadableBytesInSSL)(TCN_STDARGS, jlong ssl
/* SSL * */) { | |
1287 SSL *ssl_ = J2P(ssl, SSL *); | |
1288 | |
1289 if (ssl_ == NULL) { | |
1290 tcn_ThrowException(e, "ssl is null"); | |
1291 return 0; | |
1292 } | |
1293 | |
1294 UNREFERENCED_STDARGS; | |
1295 | |
1296 return SSL_pending(ssl_); | |
1297 } | |
1298 | |
1299 // Write wlen bytes from wbuf into bio | |
1300 TCN_IMPLEMENT_CALL(jint /* status */, SSL, writeToBIO)(TCN_STDARGS, | |
1301 jlong bio /* BIO * */, | |
1302 jlong wbuf /* char* */, | |
1303 jint wlen /* sizeof(wbuf)
*/) { | |
1304 BIO *b = J2P(bio, BIO *); | |
1305 void *w = J2P(wbuf, void *); | |
1306 | |
1307 if (b == NULL) { | |
1308 tcn_ThrowException(e, "bio is null"); | |
1309 return 0; | |
1310 } | |
1311 if (w == NULL) { | |
1312 tcn_ThrowException(e, "wbuf is null"); | 1007 tcn_ThrowException(e, "wbuf is null"); |
1313 return 0; | 1008 return 0; |
1314 } | 1009 } |
1315 | 1010 |
1316 UNREFERENCED_STDARGS; | 1011 UNREFERENCED_STDARGS; |
1317 | 1012 |
1318 return BIO_write(b, w, wlen); | 1013 return BIO_write(bio, wbuf, wlen); |
1319 | |
1320 } | 1014 } |
1321 | 1015 |
1322 // Read up to rlen bytes from bio into rbuf | 1016 TCN_IMPLEMENT_CALL(void, SSL, bioSetByteBuffer)(TCN_STDARGS, |
1323 TCN_IMPLEMENT_CALL(jint /* status */, SSL, readFromBIO)(TCN_STDARGS, | 1017 jlong bioAddress /* BIO* */, |
1324 jlong bio /* BIO * */, | 1018 jlong bufferAddress /* Address f
or direct memory */, |
1325 jlong rbuf /* char * */, | 1019 jint maxUsableBytes /* max numbe
r of bytes to use */, |
1326 jint rlen /* sizeof(rbuf
) - 1 */) { | 1020 jboolean isSSLWriteSink) { |
1327 BIO *b = J2P(bio, BIO *); | 1021 BIO* bio = J2P(bioAddress, BIO*); |
1328 void *r = J2P(rbuf, void *); | 1022 char* buffer = J2P(bufferAddress, char*); |
| 1023 struct TCN_bio_bytebuffer* bioUserData = NULL; |
| 1024 TCN_ASSERT(bio != NULL); |
| 1025 TCN_ASSERT(buffer != NULL); |
1329 | 1026 |
1330 if (b == NULL) { | 1027 bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(bio); |
1331 tcn_ThrowException(e, "bio is null"); | 1028 TCN_ASSERT(bioUserData != NULL); |
1332 return 0; | 1029 |
1333 } | 1030 bioUserData->buffer = buffer; |
1334 if (r == NULL) { | 1031 bioUserData->bufferLength = maxUsableBytes; |
1335 tcn_ThrowException(e, "rbuf is null"); | 1032 bioUserData->bufferIsSSLWriteSink = (bool) isSSLWriteSink; |
1336 return 0; | 1033 } |
| 1034 |
| 1035 TCN_IMPLEMENT_CALL(void, SSL, bioClearByteBuffer)(TCN_STDARGS, jlong bioAddress)
{ |
| 1036 BIO* bio = J2P(bioAddress, BIO*); |
| 1037 struct TCN_bio_bytebuffer* bioUserData = NULL; |
| 1038 |
| 1039 if (bio == NULL || (bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(
bio)) == NULL) { |
| 1040 return; |
1337 } | 1041 } |
1338 | 1042 |
1339 UNREFERENCED_STDARGS; | 1043 bioUserData->buffer = NULL; |
| 1044 bioUserData->bufferLength = 0; |
| 1045 bioUserData->bufferIsSSLWriteSink = false; |
| 1046 } |
1340 | 1047 |
1341 return BIO_read(b, r, rlen); | 1048 TCN_IMPLEMENT_CALL(jint, SSL, bioFlushByteBuffer)(TCN_STDARGS, jlong bioAddress)
{ |
| 1049 BIO* bio = J2P(bioAddress, BIO*); |
| 1050 struct TCN_bio_bytebuffer* bioUserData; |
| 1051 |
| 1052 return (bio == NULL || |
| 1053 (bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(bio)) == NUL
L || |
| 1054 bioUserData->nonApplicationBufferLength == 0 || |
| 1055 bioUserData->buffer == NULL || |
| 1056 !bioUserData->bufferIsSSLWriteSink) ? 0 : tcn_flush_sslbuffer_to_byte
buffer(bioUserData); |
1342 } | 1057 } |
1343 | 1058 |
1344 // Write up to wlen bytes of application data to the ssl BIO (encrypt) | 1059 // Write up to wlen bytes of application data to the ssl BIO (encrypt) |
1345 TCN_IMPLEMENT_CALL(jint /* status */, SSL, writeToSSL)(TCN_STDARGS, | 1060 TCN_IMPLEMENT_CALL(jint /* status */, SSL, writeToSSL)(TCN_STDARGS, |
1346 jlong ssl /* SSL * */, | 1061 jlong ssl /* SSL * */, |
1347 jlong wbuf /* char * */, | 1062 jlong wbuf /* char * */, |
1348 jint wlen /* sizeof(wbuf)
*/) { | 1063 jint wlen /* sizeof(wbuf)
*/) { |
1349 SSL *ssl_ = J2P(ssl, SSL *); | 1064 SSL *ssl_ = J2P(ssl, SSL *); |
1350 void *w = J2P(wbuf, void *); | 1065 void *w = J2P(wbuf, void *); |
1351 | 1066 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 | 1128 |
1414 UNREFERENCED_STDARGS; | 1129 UNREFERENCED_STDARGS; |
1415 | 1130 |
1416 SSL_set_shutdown(ssl_, mode); | 1131 SSL_set_shutdown(ssl_, mode); |
1417 } | 1132 } |
1418 | 1133 |
1419 // Free the SSL * and its associated internal BIO | 1134 // Free the SSL * and its associated internal BIO |
1420 TCN_IMPLEMENT_CALL(void, SSL, freeSSL)(TCN_STDARGS, | 1135 TCN_IMPLEMENT_CALL(void, SSL, freeSSL)(TCN_STDARGS, |
1421 jlong ssl /* SSL * */) { | 1136 jlong ssl /* SSL * */) { |
1422 int *handshakeCount = NULL; | 1137 int *handshakeCount = NULL; |
| 1138 tcn_ssl_ctxt_t* c = NULL; |
| 1139 tcn_ssl_verify_config_t* verify_config = NULL; |
1423 SSL *ssl_ = J2P(ssl, SSL *); | 1140 SSL *ssl_ = J2P(ssl, SSL *); |
1424 if (ssl_ == NULL) { | 1141 if (ssl_ == NULL) { |
1425 tcn_ThrowException(e, "ssl is null"); | 1142 tcn_ThrowException(e, "ssl is null"); |
1426 return; | 1143 return; |
1427 } | 1144 } |
| 1145 c = SSL_get_app_data2(ssl_); |
1428 handshakeCount = SSL_get_app_data3(ssl_); | 1146 handshakeCount = SSL_get_app_data3(ssl_); |
| 1147 verify_config = SSL_get_app_data4(ssl_); |
1429 | 1148 |
1430 UNREFERENCED_STDARGS; | 1149 UNREFERENCED_STDARGS; |
| 1150 TCN_ASSERT(c != NULL); |
1431 | 1151 |
1432 if (handshakeCount != NULL) { | 1152 if (handshakeCount != NULL) { |
1433 free(handshakeCount); | 1153 OPENSSL_free(handshakeCount); |
| 1154 SSL_set_app_data3(ssl_, NULL); |
| 1155 } |
| 1156 |
| 1157 // Only free the verify_config if it is not shared with the SSLContext. |
| 1158 if (verify_config != NULL && verify_config != &c->verify_config) { |
| 1159 OPENSSL_free(verify_config); |
| 1160 SSL_set_app_data4(ssl_, &c->verify_config); |
1434 } | 1161 } |
1435 SSL_free(ssl_); | 1162 SSL_free(ssl_); |
1436 } | 1163 } |
1437 | 1164 |
1438 // Make a BIO pair (network and internal) for the provided SSL * and return the
network BIO | 1165 TCN_IMPLEMENT_CALL(jlong, SSL, bioNewByteBuffer)(TCN_STDARGS, |
1439 TCN_IMPLEMENT_CALL(jlong, SSL, makeNetworkBIO)(TCN_STDARGS, | 1166 jlong ssl /* SSL* */, |
1440 jlong ssl /* SSL * */) { | 1167 jint nonApplicationBufferSize)
{ |
1441 SSL *ssl_ = J2P(ssl, SSL *); | 1168 SSL* ssl_ = J2P(ssl, SSL*); |
1442 BIO *internal_bio; | 1169 BIO* bio; |
1443 BIO *network_bio; | 1170 struct TCN_bio_bytebuffer* bioUserData; |
1444 | 1171 |
1445 if (ssl_ == NULL) { | 1172 if (ssl_ == NULL) { |
1446 tcn_ThrowException(e, "ssl is null"); | 1173 tcn_ThrowException(e, "ssl is null"); |
1447 return 0; | 1174 return 0; |
1448 } | 1175 } |
1449 | 1176 |
1450 if (BIO_new_bio_pair(&internal_bio, 0, &network_bio, 0) != 1) { | 1177 if (nonApplicationBufferSize <= 0) { |
1451 tcn_ThrowException(e, "BIO_new_bio_pair failed"); | 1178 tcn_ThrowException(e, "nonApplicationBufferSize <= 0"); |
1452 return 0; | 1179 return 0; |
1453 } | 1180 } |
1454 | 1181 |
1455 UNREFERENCED(o); | 1182 bio = BIO_new(BIO_java_bytebuffer()); |
| 1183 if (bio == NULL) { |
| 1184 tcn_ThrowException(e, "BIO_new failed"); |
| 1185 return 0; |
| 1186 } |
1456 | 1187 |
1457 SSL_set_bio(ssl_, internal_bio, internal_bio); | 1188 bioUserData = BIO_get_data(bio); |
| 1189 if (bioUserData == NULL) { |
| 1190 BIO_free(bio); |
| 1191 tcn_ThrowException(e, "BIO_get_data failed"); |
| 1192 return 0; |
| 1193 } |
1458 | 1194 |
1459 return P2J(network_bio); | 1195 bioUserData->nonApplicationBuffer = (char*) OPENSSL_malloc(nonApplicationBuf
ferSize * sizeof(char)); |
| 1196 if (bioUserData->nonApplicationBuffer == NULL) { |
| 1197 BIO_free(bio); |
| 1198 tcn_Throw(e, "Failed to allocate internal buffer of size %d", nonApplica
tionBufferSize); |
| 1199 return 0; |
| 1200 } |
| 1201 bioUserData->nonApplicationBufferSize = nonApplicationBufferSize; |
| 1202 |
| 1203 SSL_set_bio(ssl_, bio, bio); |
| 1204 |
| 1205 return P2J(bio); |
1460 } | 1206 } |
1461 | 1207 |
1462 // Free a BIO * (typically, the network BIO) | 1208 // Free a BIO * (typically, the network BIO) |
1463 TCN_IMPLEMENT_CALL(void, SSL, freeBIO)(TCN_STDARGS, | 1209 TCN_IMPLEMENT_CALL(void, SSL, freeBIO)(TCN_STDARGS, |
1464 jlong bio /* BIO * */) { | 1210 jlong bio /* BIO * */) { |
1465 BIO *bio_ = J2P(bio, BIO *); | 1211 BIO *bio_ = J2P(bio, BIO *); |
1466 | 1212 |
1467 UNREFERENCED_STDARGS; | 1213 UNREFERENCED_STDARGS; |
1468 | 1214 |
1469 if (bio_ != NULL) { | 1215 if (bio_ != NULL) { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1607 jlong ssl /* SSL * */) | 1353 jlong ssl /* SSL * */) |
1608 { | 1354 { |
1609 STACK_OF(X509) *sk; | 1355 STACK_OF(X509) *sk; |
1610 int len; | 1356 int len; |
1611 int i; | 1357 int i; |
1612 X509 *cert; | 1358 X509 *cert; |
1613 int length; | 1359 int length; |
1614 unsigned char *buf; | 1360 unsigned char *buf; |
1615 jobjectArray array; | 1361 jobjectArray array; |
1616 jbyteArray bArray; | 1362 jbyteArray bArray; |
| 1363 jclass byteArrayClass = tcn_get_byte_array_class(); |
1617 | 1364 |
1618 SSL *ssl_ = J2P(ssl, SSL *); | 1365 SSL *ssl_ = J2P(ssl, SSL *); |
1619 | 1366 |
1620 if (ssl_ == NULL) { | 1367 if (ssl_ == NULL) { |
1621 tcn_ThrowException(e, "ssl is null"); | 1368 tcn_ThrowException(e, "ssl is null"); |
1622 return NULL; | 1369 return NULL; |
1623 } | 1370 } |
1624 | 1371 |
1625 UNREFERENCED(o); | 1372 UNREFERENCED(o); |
1626 | 1373 |
1627 // Get a stack of all certs in the chain. | 1374 // Get a stack of all certs in the chain. |
1628 sk = SSL_get_peer_cert_chain(ssl_); | 1375 sk = SSL_get_peer_cert_chain(ssl_); |
1629 | 1376 |
1630 len = sk_num((_STACK*) sk); | 1377 len = sk_X509_num(sk); |
1631 if (len <= 0) { | 1378 if (len <= 0) { |
1632 // No peer certificate chain as no auth took place yet, or the auth was
not successful. | 1379 // No peer certificate chain as no auth took place yet, or the auth was
not successful. |
1633 return NULL; | 1380 return NULL; |
1634 } | 1381 } |
1635 // Create the byte[][]Â array that holds all the certs | 1382 // Create the byte[][]Â array that holds all the certs |
1636 array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL); | 1383 array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL); |
1637 | 1384 |
1638 for(i = 0; i < len; i++) { | 1385 for(i = 0; i < len; i++) { |
1639 cert = (X509*) sk_value((_STACK*) sk, i); | 1386 cert = sk_X509_value(sk, i); |
1640 | 1387 |
1641 buf = NULL; | 1388 buf = NULL; |
1642 length = i2d_X509(cert, &buf); | 1389 length = i2d_X509(cert, &buf); |
1643 if (length < 0) { | 1390 if (length < 0) { |
1644 OPENSSL_free(buf); | 1391 if (buf != NULL) { |
| 1392 OPENSSL_free(buf); |
| 1393 } |
1645 // In case of error just return an empty byte[][] | 1394 // In case of error just return an empty byte[][] |
1646 return (*e)->NewObjectArray(e, 0, byteArrayClass, NULL); | 1395 return (*e)->NewObjectArray(e, 0, byteArrayClass, NULL); |
1647 } | 1396 } |
1648 bArray = (*e)->NewByteArray(e, length); | 1397 bArray = (*e)->NewByteArray(e, length); |
1649 (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf); | 1398 (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf); |
1650 (*e)->SetObjectArrayElement(e, array, i, bArray); | 1399 (*e)->SetObjectArrayElement(e, array, i, bArray); |
1651 | 1400 |
1652 // Delete the local reference as we not know how long the chain is and l
ocal references are otherwise | 1401 // Delete the local reference as we not know how long the chain is and l
ocal references are otherwise |
1653 // only freed once jni method returns. | 1402 // only freed once jni method returns. |
1654 (*e)->DeleteLocalRef(e, bArray); | 1403 (*e)->DeleteLocalRef(e, bArray); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1691 // See https://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html | 1440 // See https://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html |
1692 X509_free(cert); | 1441 X509_free(cert); |
1693 | 1442 |
1694 OPENSSL_free(buf); | 1443 OPENSSL_free(buf); |
1695 | 1444 |
1696 return bArray; | 1445 return bArray; |
1697 } | 1446 } |
1698 | 1447 |
1699 TCN_IMPLEMENT_CALL(jstring, SSL, getErrorString)(TCN_STDARGS, jlong number) | 1448 TCN_IMPLEMENT_CALL(jstring, SSL, getErrorString)(TCN_STDARGS, jlong number) |
1700 { | 1449 { |
1701 char buf[256]; | 1450 char buf[ERR_LEN]; |
1702 UNREFERENCED(o); | 1451 UNREFERENCED(o); |
1703 ERR_error_string(number, buf); | 1452 ERR_error_string(number, buf); |
1704 return tcn_new_string(e, buf); | 1453 return tcn_new_string(e, buf); |
1705 } | 1454 } |
1706 | 1455 |
1707 TCN_IMPLEMENT_CALL(jlong, SSL, getTime)(TCN_STDARGS, jlong ssl) | 1456 TCN_IMPLEMENT_CALL(jlong, SSL, getTime)(TCN_STDARGS, jlong ssl) |
1708 { | 1457 { |
1709 SSL *ssl_ = J2P(ssl, SSL *); | 1458 SSL *ssl_ = J2P(ssl, SSL *); |
1710 SSL_SESSION *session = NULL; | 1459 SSL_SESSION *session = NULL; |
1711 | 1460 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1766 // returns 0 if the session is NULL, so do that here. | 1515 // returns 0 if the session is NULL, so do that here. |
1767 return 0; | 1516 return 0; |
1768 } | 1517 } |
1769 | 1518 |
1770 UNREFERENCED(o); | 1519 UNREFERENCED(o); |
1771 | 1520 |
1772 return SSL_set_timeout(session, seconds); | 1521 return SSL_set_timeout(session, seconds); |
1773 } | 1522 } |
1774 | 1523 |
1775 | 1524 |
1776 TCN_IMPLEMENT_CALL(void, SSL, setVerify)(TCN_STDARGS, jlong ssl, | 1525 TCN_IMPLEMENT_CALL(void, SSL, setVerify)(TCN_STDARGS, jlong ssl, jint level, jin
t depth) |
1777 jint level, jint depth) | |
1778 { | 1526 { |
1779 tcn_ssl_ctxt_t *c; | 1527 tcn_ssl_verify_config_t* verify_config; |
1780 int verify; | 1528 tcn_ssl_ctxt_t* c; |
1781 SSL *ssl_ = J2P(ssl, SSL *); | 1529 SSL *ssl_ = J2P(ssl, SSL *); |
1782 | 1530 |
1783 if (ssl_ == NULL) { | 1531 if (ssl_ == NULL) { |
1784 tcn_ThrowException(e, "ssl is null"); | 1532 tcn_ThrowException(e, "ssl is null"); |
1785 return; | 1533 return; |
1786 } | 1534 } |
1787 | 1535 |
1788 c = SSL_get_app_data2(ssl_); | 1536 c = SSL_get_app_data2(ssl_); |
1789 | 1537 verify_config = SSL_get_app_data4(ssl_); |
1790 verify = SSL_VERIFY_NONE; | |
1791 | 1538 |
1792 UNREFERENCED(o); | 1539 UNREFERENCED(o); |
1793 TCN_ASSERT(c->ctx != 0); | 1540 TCN_ASSERT(c != NULL); |
1794 c->verify_mode = level; | 1541 TCN_ASSERT(verify_config != NULL); |
1795 | 1542 |
1796 if (c->verify_mode == SSL_CVERIFY_UNSET) | 1543 // If we are sharing the configuration from the SSLContext we now need to cr
eate a new configuration just for this SSL. |
1797 c->verify_mode = SSL_CVERIFY_NONE; | 1544 if (verify_config == &c->verify_config) { |
1798 if (depth > 0) | 1545 verify_config = (tcn_ssl_verify_config_t*) OPENSSL_malloc(sizeof(tcn_ssl_
verify_config_t)); |
1799 c->verify_depth = depth; | 1546 if (verify_config == NULL) { |
1800 /* | 1547 tcn_ThrowException(e, "failed to allocate tcn_ssl_verify_config_t"); |
1801 * Configure callbacks for SSL context | 1548 return; |
1802 */ | 1549 } |
1803 if (c->verify_mode == SSL_CVERIFY_REQUIRE) | 1550 // Copy the verify depth form the context in case depth is <0. |
1804 verify |= SSL_VERIFY_PEER_STRICT; | 1551 verify_config->verify_depth = c->verify_config.verify_depth; |
1805 if ((c->verify_mode == SSL_CVERIFY_OPTIONAL) || | 1552 SSL_set_app_data4(ssl_, verify_config); |
1806 (c->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) | |
1807 verify |= SSL_VERIFY_PEER; | |
1808 if (!c->store) { | |
1809 if (SSL_CTX_set_default_verify_paths(c->ctx)) { | |
1810 c->store = SSL_CTX_get_cert_store(c->ctx); | |
1811 X509_STORE_set_flags(c->store, 0); | |
1812 } | |
1813 else { | |
1814 /* XXX: See if this is fatal */ | |
1815 } | |
1816 } | 1553 } |
1817 | 1554 |
1818 SSL_set_verify(ssl_, verify, SSL_callback_SSL_verify); | 1555 // No need to specify a callback for SSL_set_verify because we override the
default certificate verification via SSL_CTX_set_cert_verify_callback. |
| 1556 SSL_set_verify(ssl_, tcn_set_verify_config(verify_config, level, depth), NUL
L); |
| 1557 SSL_set_verify_depth(ssl_, verify_config->verify_depth); |
1819 } | 1558 } |
1820 | 1559 |
1821 TCN_IMPLEMENT_CALL(void, SSL, setOptions)(TCN_STDARGS, jlong ssl, | 1560 TCN_IMPLEMENT_CALL(void, SSL, setOptions)(TCN_STDARGS, jlong ssl, |
1822 jint opt) | 1561 jint opt) |
1823 { | 1562 { |
1824 SSL *ssl_ = J2P(ssl, SSL *); | 1563 SSL *ssl_ = J2P(ssl, SSL *); |
1825 | 1564 |
1826 if (ssl_ == NULL) { | 1565 if (ssl_ == NULL) { |
1827 tcn_ThrowException(e, "ssl is null"); | 1566 tcn_ThrowException(e, "ssl is null"); |
1828 return; | 1567 return; |
1829 } | 1568 } |
1830 | 1569 |
1831 UNREFERENCED_STDARGS; | 1570 UNREFERENCED_STDARGS; |
1832 | 1571 |
1833 #ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | 1572 SSL_set_options(ssl_, opt); |
1834 /* Clear the flag if not supported */ | 1573 } |
1835 if (opt & 0x00040000) { | 1574 |
1836 opt &= ~0x00040000; | 1575 TCN_IMPLEMENT_CALL(void, SSL, clearOptions)(TCN_STDARGS, jlong ssl, |
| 1576 jint opt) |
| 1577 { |
| 1578 SSL *ssl_ = J2P(ssl, SSL *); |
| 1579 |
| 1580 if (ssl_ == NULL) { |
| 1581 tcn_ThrowException(e, "ssl is null"); |
| 1582 return; |
1837 } | 1583 } |
1838 #endif | 1584 |
1839 SSL_set_options(ssl_, opt); | 1585 UNREFERENCED_STDARGS; |
| 1586 |
| 1587 SSL_clear_options(ssl_, opt); |
1840 } | 1588 } |
1841 | 1589 |
1842 TCN_IMPLEMENT_CALL(jint, SSL, getOptions)(TCN_STDARGS, jlong ssl) | 1590 TCN_IMPLEMENT_CALL(jint, SSL, getOptions)(TCN_STDARGS, jlong ssl) |
1843 { | 1591 { |
1844 SSL *ssl_ = J2P(ssl, SSL *); | 1592 SSL *ssl_ = J2P(ssl, SSL *); |
1845 | 1593 |
1846 if (ssl_ == NULL) { | 1594 if (ssl_ == NULL) { |
1847 tcn_ThrowException(e, "ssl is null"); | 1595 tcn_ThrowException(e, "ssl is null"); |
1848 return 0; | 1596 return 0; |
1849 } | 1597 } |
1850 | 1598 |
1851 UNREFERENCED_STDARGS; | 1599 UNREFERENCED_STDARGS; |
1852 | 1600 |
1853 return SSL_get_options(ssl_); | 1601 return SSL_get_options(ssl_); |
1854 } | 1602 } |
1855 | 1603 |
1856 TCN_IMPLEMENT_CALL(jobjectArray, SSL, getCiphers)(TCN_STDARGS, jlong ssl) | 1604 TCN_IMPLEMENT_CALL(jobjectArray, SSL, getCiphers)(TCN_STDARGS, jlong ssl) |
1857 { | 1605 { |
1858 STACK_OF(SSL_CIPHER) *sk; | 1606 STACK_OF(SSL_CIPHER) *sk; |
1859 int len; | 1607 int len; |
1860 jobjectArray array; | 1608 jobjectArray array; |
1861 SSL_CIPHER *cipher; | 1609 const SSL_CIPHER *cipher; |
1862 const char *name; | 1610 const char *name; |
1863 int i; | 1611 int i; |
1864 jstring c_name; | 1612 jstring c_name; |
1865 SSL *ssl_ = J2P(ssl, SSL *); | 1613 SSL *ssl_ = J2P(ssl, SSL *); |
1866 | 1614 |
1867 if (ssl_ == NULL) { | 1615 if (ssl_ == NULL) { |
1868 tcn_ThrowException(e, "ssl is null"); | 1616 tcn_ThrowException(e, "ssl is null"); |
1869 return NULL; | 1617 return NULL; |
1870 } | 1618 } |
1871 | 1619 |
1872 UNREFERENCED_STDARGS; | 1620 UNREFERENCED_STDARGS; |
1873 | 1621 |
1874 sk = SSL_get_ciphers(ssl_); | 1622 sk = SSL_get_ciphers(ssl_); |
1875 len = sk_num((_STACK*) sk); | 1623 len = sk_SSL_CIPHER_num(sk); |
1876 | 1624 |
1877 if (len <= 0) { | 1625 if (len <= 0) { |
1878 // No peer certificate chain as no auth took place yet, or the auth was
not successful. | 1626 // No peer certificate chain as no auth took place yet, or the auth was
not successful. |
1879 return NULL; | 1627 return NULL; |
1880 } | 1628 } |
1881 | 1629 |
1882 // Create the byte[][]Â array that holds all the certs | 1630 // Create the byte[][]Â array that holds all the certs |
1883 array = (*e)->NewObjectArray(e, len, stringClass, NULL); | 1631 array = (*e)->NewObjectArray(e, len, tcn_get_string_class(), NULL); |
1884 | 1632 |
1885 for (i = 0; i < len; i++) { | 1633 for (i = 0; i < len; i++) { |
1886 cipher = (SSL_CIPHER*) sk_value((_STACK*) sk, i); | 1634 cipher = sk_SSL_CIPHER_value(sk, i); |
1887 name = SSL_CIPHER_get_name(cipher); | 1635 name = SSL_CIPHER_get_name(cipher); |
1888 | 1636 |
1889 c_name = (*e)->NewStringUTF(e, name); | 1637 c_name = (*e)->NewStringUTF(e, name); |
1890 (*e)->SetObjectArrayElement(e, array, i, c_name); | 1638 (*e)->SetObjectArrayElement(e, array, i, c_name); |
1891 } | 1639 } |
1892 return array; | 1640 return array; |
1893 } | 1641 } |
1894 | 1642 |
1895 TCN_IMPLEMENT_CALL(jboolean, SSL, setCipherSuites)(TCN_STDARGS, jlong ssl, | 1643 TCN_IMPLEMENT_CALL(jboolean, SSL, setCipherSuites)(TCN_STDARGS, jlong ssl, |
1896 jstring ciphers) | 1644 jstring ciphers) |
1897 { | 1645 { |
1898 jboolean rv = JNI_TRUE; | 1646 jboolean rv = JNI_TRUE; |
1899 TCN_ALLOC_CSTRING(ciphers); | 1647 TCN_ALLOC_CSTRING(ciphers); |
1900 SSL *ssl_ = J2P(ssl, SSL *); | 1648 SSL *ssl_ = J2P(ssl, SSL *); |
1901 | 1649 |
1902 if (ssl_ == NULL) { | 1650 if (ssl_ == NULL) { |
1903 tcn_ThrowException(e, "ssl is null"); | 1651 tcn_ThrowException(e, "ssl is null"); |
1904 return JNI_FALSE; | 1652 return JNI_FALSE; |
1905 } | 1653 } |
1906 | 1654 |
1907 UNREFERENCED(o); | 1655 UNREFERENCED(o); |
1908 | 1656 |
1909 if (!J2S(ciphers)) { | 1657 if (!J2S(ciphers)) { |
1910 return JNI_FALSE; | 1658 return JNI_FALSE; |
1911 } | 1659 } |
1912 | 1660 |
1913 if (!SSL_set_cipher_list(ssl_, J2S(ciphers))) { | 1661 if (!SSL_set_cipher_list(ssl_, J2S(ciphers))) { |
1914 char err[256]; | 1662 char err[ERR_LEN]; |
1915 ERR_error_string(ERR_get_error(), err); | 1663 ERR_error_string(ERR_get_error(), err); |
1916 tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err); | 1664 tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err); |
1917 rv = JNI_FALSE; | 1665 rv = JNI_FALSE; |
1918 } | 1666 } |
1919 | 1667 |
1920 TCN_FREE_CSTRING(ciphers); | 1668 TCN_FREE_CSTRING(ciphers); |
1921 return rv; | 1669 return rv; |
1922 } | 1670 } |
1923 | 1671 |
1924 TCN_IMPLEMENT_CALL(jbyteArray, SSL, getSessionId)(TCN_STDARGS, jlong ssl) | 1672 TCN_IMPLEMENT_CALL(jbyteArray, SSL, getSessionId)(TCN_STDARGS, jlong ssl) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 SSL *ssl_ = J2P(ssl, SSL *); | 1706 SSL *ssl_ = J2P(ssl, SSL *); |
1959 | 1707 |
1960 if (ssl_ == NULL) { | 1708 if (ssl_ == NULL) { |
1961 tcn_ThrowException(e, "ssl is null"); | 1709 tcn_ThrowException(e, "ssl is null"); |
1962 return -1; | 1710 return -1; |
1963 } | 1711 } |
1964 | 1712 |
1965 UNREFERENCED(o); | 1713 UNREFERENCED(o); |
1966 | 1714 |
1967 handshakeCount = SSL_get_app_data3(ssl_); | 1715 handshakeCount = SSL_get_app_data3(ssl_); |
1968 if (handshakeCount != NULL) { | 1716 return handshakeCount != NULL ? *handshakeCount : 0; |
1969 return *handshakeCount; | |
1970 } | |
1971 return 0; | |
1972 } | 1717 } |
1973 | 1718 |
1974 | 1719 |
1975 TCN_IMPLEMENT_CALL(void, SSL, clearError)(TCN_STDARGS) | 1720 TCN_IMPLEMENT_CALL(void, SSL, clearError)(TCN_STDARGS) |
1976 { | 1721 { |
1977 UNREFERENCED(o); | 1722 UNREFERENCED(o); |
1978 ERR_clear_error(); | 1723 ERR_clear_error(); |
1979 } | 1724 } |
1980 | 1725 |
1981 TCN_IMPLEMENT_CALL(jint, SSL, renegotiate)(TCN_STDARGS, | 1726 TCN_IMPLEMENT_CALL(jint, SSL, renegotiate)(TCN_STDARGS, |
(...skipping 18 matching lines...) Expand all Loading... |
2000 if (ssl_ == NULL) { | 1745 if (ssl_ == NULL) { |
2001 tcn_ThrowException(e, "ssl is null"); | 1746 tcn_ThrowException(e, "ssl is null"); |
2002 return; | 1747 return; |
2003 } | 1748 } |
2004 | 1749 |
2005 UNREFERENCED(o); | 1750 UNREFERENCED(o); |
2006 | 1751 |
2007 SSL_set_state(ssl_, state); | 1752 SSL_set_state(ssl_, state); |
2008 } | 1753 } |
2009 | 1754 |
2010 | 1755 TCN_IMPLEMENT_CALL(void, SSL, setTlsExtHostName)(TCN_STDARGS, jlong ssl, jstring
hostname) { |
2011 /*** End Apple API Additions ***/ | 1756 TCN_ALLOC_CSTRING(hostname); |
2012 | 1757 SSL *ssl_ = J2P(ssl, SSL *); |
| 1758 |
| 1759 if (ssl_ == NULL) { |
| 1760 tcn_ThrowException(e, "ssl is null"); |
| 1761 } else { |
| 1762 UNREFERENCED(o); |
| 1763 |
| 1764 if (SSL_set_tlsext_host_name(ssl_, J2S(hostname)) != 1) { |
| 1765 char err[ERR_LEN]; |
| 1766 ERR_error_string(ERR_get_error(), err); |
| 1767 tcn_Throw(e, "Unable to set TLS servername extension (%s)", err); |
| 1768 } |
| 1769 } |
| 1770 |
| 1771 TCN_FREE_CSTRING(hostname); |
| 1772 } |
| 1773 |
| 1774 TCN_IMPLEMENT_CALL(void, SSL, setHostNameValidation)(TCN_STDARGS, jlong sslAddre
ss, jint flags, jstring hostnameString) { |
| 1775 SSL* ssl = J2P(sslAddress, SSL*); |
| 1776 |
| 1777 if (ssl == NULL) { |
| 1778 tcn_ThrowException(e, "ssl is null"); |
| 1779 } else { |
| 1780 const char* hostname = hostnameString == NULL ? NULL : (*e)->GetStringUT
FChars(e, hostnameString, 0); |
| 1781 #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) |
| 1782 X509_VERIFY_PARAM* param = SSL_get0_param(ssl); |
| 1783 X509_VERIFY_PARAM_set_hostflags(param, flags); |
| 1784 if (X509_VERIFY_PARAM_set1_host(param, hostname, 0) != 1) { |
| 1785 char err[ERR_LEN]; |
| 1786 ERR_error_string(ERR_get_error(), err); |
| 1787 tcn_Throw(e, "X509_VERIFY_PARAM_set1_host error (%s)", err); |
| 1788 } |
2013 #else | 1789 #else |
2014 #error OpenSSL is required! | 1790 if (hostname != NULL && hostname[0] != '\0') { |
2015 | 1791 tcn_ThrowException(e, "hostname verification requires OpenSSL 1.0.2+
"); |
2016 /* OpenSSL is not supported. | 1792 } |
2017 * Create empty stubs. | 1793 #endif |
2018 */ | 1794 (*e)->ReleaseStringUTFChars(e, hostnameString, hostname); |
2019 | 1795 } |
2020 TCN_IMPLEMENT_CALL(jint, SSL, version)(TCN_STDARGS) | 1796 } |
2021 { | 1797 |
2022 UNREFERENCED_STDARGS; | 1798 TCN_IMPLEMENT_CALL(jobjectArray, SSL, authenticationMethods)(TCN_STDARGS, jlong
ssl) { |
| 1799 SSL *ssl_ = J2P(ssl, SSL *); |
| 1800 const STACK_OF(SSL_CIPHER) *ciphers = NULL; |
| 1801 int len; |
| 1802 int i; |
| 1803 jobjectArray array; |
| 1804 |
| 1805 TCN_ASSERT(ssl_ != NULL); |
| 1806 |
| 1807 UNREFERENCED(o); |
| 1808 |
| 1809 ciphers = SSL_get_ciphers(ssl_); |
| 1810 len = sk_SSL_CIPHER_num(ciphers); |
| 1811 |
| 1812 array = (*e)->NewObjectArray(e, len, tcn_get_string_class(), NULL); |
| 1813 |
| 1814 for (i = 0; i < len; i++) { |
| 1815 (*e)->SetObjectArrayElement(e, array, i, |
| 1816 (*e)->NewStringUTF(e, SSL_cipher_authentication_method((SSL_CIPHER*) sk_
value((_STACK*) ciphers, i)))); |
| 1817 } |
| 1818 return array; |
| 1819 } |
| 1820 |
| 1821 TCN_IMPLEMENT_CALL(void, SSL, setCertificateBio)(TCN_STDARGS, jlong ssl, |
| 1822 jlong cert, jlong key, |
| 1823 jstring password) |
| 1824 { |
| 1825 SSL *ssl_ = J2P(ssl, SSL *); |
| 1826 BIO *cert_bio = J2P(cert, BIO *); |
| 1827 BIO *key_bio = J2P(key, BIO *); |
| 1828 EVP_PKEY* pkey = NULL; |
| 1829 X509* xcert = NULL; |
| 1830 TCN_ALLOC_CSTRING(password); |
| 1831 char err[ERR_LEN]; |
| 1832 |
| 1833 UNREFERENCED(o); |
| 1834 TCN_ASSERT(ssl != NULL); |
| 1835 |
| 1836 if (key <= 0) { |
| 1837 key = cert; |
| 1838 } |
| 1839 |
| 1840 if (cert <= 0 || key <= 0) { |
| 1841 tcn_Throw(e, "No Certificate file specified or invalid file format"); |
| 1842 goto cleanup; |
| 1843 } |
| 1844 |
| 1845 if ((pkey = load_pem_key_bio(cpassword, key_bio)) == NULL) { |
| 1846 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1847 ERR_clear_error(); |
| 1848 tcn_Throw(e, "Unable to load certificate key (%s)",err); |
| 1849 goto cleanup; |
| 1850 } |
| 1851 if ((xcert = load_pem_cert_bio(cpassword, cert_bio)) == NULL) { |
| 1852 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1853 ERR_clear_error(); |
| 1854 tcn_Throw(e, "Unable to load certificate (%s) ", err); |
| 1855 goto cleanup; |
| 1856 } |
| 1857 |
| 1858 if (SSL_use_certificate(ssl_, xcert) <= 0) { |
| 1859 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1860 ERR_clear_error(); |
| 1861 tcn_Throw(e, "Error setting certificate (%s)", err); |
| 1862 goto cleanup; |
| 1863 } |
| 1864 if (SSL_use_PrivateKey(ssl_, pkey) <= 0) { |
| 1865 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1866 ERR_clear_error(); |
| 1867 tcn_Throw(e, "Error setting private key (%s)", err); |
| 1868 goto cleanup; |
| 1869 } |
| 1870 if (SSL_check_private_key(ssl_) <= 0) { |
| 1871 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1872 ERR_clear_error(); |
| 1873 |
| 1874 tcn_Throw(e, "Private key does not match the certificate public key (%s)
", |
| 1875 err); |
| 1876 goto cleanup; |
| 1877 } |
| 1878 cleanup: |
| 1879 TCN_FREE_CSTRING(password); |
| 1880 EVP_PKEY_free(pkey); // this function is safe to call with NULL |
| 1881 X509_free(xcert); // this function is safe to call with NULL |
| 1882 } |
| 1883 |
| 1884 TCN_IMPLEMENT_CALL(void, SSL, setCertificateChainBio)(TCN_STDARGS, jlong ssl, |
| 1885 jlong chain, |
| 1886 jboolean skipf
irst) |
| 1887 { |
| 1888 SSL *ssl_ = J2P(ssl, SSL *); |
| 1889 BIO *b = J2P(chain, BIO *); |
| 1890 char err[ERR_LEN]; |
| 1891 |
| 1892 UNREFERENCED(o); |
| 1893 TCN_ASSERT(ssl_ != NULL); |
| 1894 TCN_ASSERT(b != NULL); |
| 1895 |
| 1896 if (SSL_use_certificate_chain_bio(ssl_, b, skipfirst) < 0) { |
| 1897 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1898 ERR_clear_error(); |
| 1899 tcn_Throw(e, "Error setting certificate chain (%s)", err); |
| 1900 } |
| 1901 } |
| 1902 |
| 1903 TCN_IMPLEMENT_CALL(long, SSL, parsePrivateKey)(TCN_STDARGS, jlong privateKeyBio,
jstring password) |
| 1904 { |
| 1905 EVP_PKEY* pkey = NULL; |
| 1906 BIO *bio = J2P(privateKeyBio, BIO *); |
| 1907 TCN_ALLOC_CSTRING(password); |
| 1908 char err[ERR_LEN]; |
| 1909 |
| 1910 UNREFERENCED(o); |
| 1911 |
| 1912 if (bio == NULL) { |
| 1913 tcn_Throw(e, "Unable to load certificate key"); |
| 1914 goto cleanup; |
| 1915 } |
| 1916 |
| 1917 if ((pkey = load_pem_key_bio(cpassword, bio)) == NULL) { |
| 1918 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1919 ERR_clear_error(); |
| 1920 tcn_Throw(e, "Unable to load certificate key (%s)",err); |
| 1921 goto cleanup; |
| 1922 } |
| 1923 |
| 1924 cleanup: |
| 1925 TCN_FREE_CSTRING(password); |
| 1926 return P2J(pkey); |
| 1927 } |
| 1928 |
| 1929 TCN_IMPLEMENT_CALL(void, SSL, freePrivateKey)(TCN_STDARGS, jlong privateKey) |
| 1930 { |
| 1931 EVP_PKEY *key = J2P(privateKey, EVP_PKEY *); |
| 1932 UNREFERENCED(o); |
| 1933 EVP_PKEY_free(key); // Safe to call with NULL as well. |
| 1934 } |
| 1935 |
| 1936 TCN_IMPLEMENT_CALL(long, SSL, parseX509Chain)(TCN_STDARGS, jlong x509ChainBio) |
| 1937 { |
| 1938 BIO *cert_bio = J2P(x509ChainBio, BIO *); |
| 1939 X509* cert = NULL; |
| 1940 STACK_OF(X509) *chain = NULL; |
| 1941 char err[ERR_LEN]; |
| 1942 unsigned long error; |
| 1943 int n = 0; |
| 1944 |
| 1945 UNREFERENCED(o); |
| 1946 |
| 1947 if (cert_bio == NULL) { |
| 1948 tcn_Throw(e, "No Certificate specified or invalid format"); |
| 1949 goto cleanup; |
| 1950 } |
| 1951 |
| 1952 chain = sk_X509_new_null(); |
| 1953 while ((cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL)) != NULL) { |
| 1954 if (sk_X509_push(chain, cert) <= 0) { |
| 1955 tcn_Throw(e, "No Certificate specified or invalid format"); |
| 1956 goto cleanup; |
| 1957 } |
| 1958 cert = NULL; |
| 1959 n++; |
| 1960 } |
| 1961 |
| 1962 // ensure that if we have an error its just for EOL. |
| 1963 if ((error = ERR_peek_error()) > 0) { |
| 1964 if (!(ERR_GET_LIB(error) == ERR_LIB_PEM |
| 1965 && ERR_GET_REASON(error) == PEM_R_NO_START_LINE)) { |
| 1966 |
| 1967 ERR_error_string_n(ERR_get_error(), err, ERR_LEN); |
| 1968 tcn_Throw(e, "Invalid format (%s)", err); |
| 1969 goto cleanup; |
| 1970 } |
| 1971 ERR_clear_error(); |
| 1972 } |
| 1973 |
| 1974 return P2J(chain); |
| 1975 |
| 1976 cleanup: |
| 1977 ERR_clear_error(); |
| 1978 sk_X509_pop_free(chain, X509_free); |
| 1979 X509_free(cert); |
2023 return 0; | 1980 return 0; |
2024 } | 1981 } |
2025 | 1982 |
2026 TCN_IMPLEMENT_CALL(jstring, SSL, versionString)(TCN_STDARGS) | 1983 TCN_IMPLEMENT_CALL(void, SSL, freeX509Chain)(TCN_STDARGS, jlong x509Chain) |
2027 { | 1984 { |
2028 UNREFERENCED_STDARGS; | 1985 STACK_OF(X509) *chain = J2P(x509Chain, STACK_OF(X509) *); |
2029 return NULL; | 1986 UNREFERENCED(o); |
2030 } | 1987 sk_X509_pop_free(chain, X509_free); |
2031 | 1988 } |
2032 TCN_IMPLEMENT_CALL(jint, SSL, initialize)(TCN_STDARGS, jstring engine) | 1989 |
2033 { | |
2034 UNREFERENCED(o); | |
2035 UNREFERENCED(engine); | |
2036 tcn_ThrowAPRException(e, APR_ENOTIMPL); | |
2037 return (jint)APR_ENOTIMPL; | |
2038 } | |
2039 | |
2040 TCN_IMPLEMENT_CALL(jboolean, SSL, randLoad)(TCN_STDARGS, jstring file) | |
2041 { | |
2042 UNREFERENCED_STDARGS; | |
2043 UNREFERENCED(file); | |
2044 return JNI_FALSE; | |
2045 } | |
2046 | |
2047 TCN_IMPLEMENT_CALL(jboolean, SSL, randSave)(TCN_STDARGS, jstring file) | |
2048 { | |
2049 UNREFERENCED_STDARGS; | |
2050 return JNI_FALSE; | |
2051 } | |
2052 | |
2053 TCN_IMPLEMENT_CALL(jboolean, SSL, randMake)(TCN_STDARGS, jstring file, | |
2054 jint length, jboolean base64) | |
2055 { | |
2056 UNREFERENCED_STDARGS; | |
2057 UNREFERENCED(file); | |
2058 UNREFERENCED(length); | |
2059 UNREFERENCED(base64); | |
2060 return JNI_FALSE; | |
2061 } | |
2062 | |
2063 TCN_IMPLEMENT_CALL(void, SSL, randSet)(TCN_STDARGS, jstring file) | |
2064 { | |
2065 UNREFERENCED_STDARGS; | |
2066 UNREFERENCED(file); | |
2067 } | |
2068 | |
2069 TCN_IMPLEMENT_CALL(jint, SSL, fipsModeGet)(TCN_STDARGS) | |
2070 { | |
2071 UNREFERENCED(o); | |
2072 tcn_ThrowException(e, "FIPS was not available to tcnative at build time. You
will need to re-build tcnative against an OpenSSL with FIPS."); | |
2073 return 0; | |
2074 } | |
2075 | |
2076 TCN_IMPLEMENT_CALL(jint, SSL, fipsModeSet)(TCN_STDARGS, jint mode) | |
2077 { | |
2078 UNREFERENCED(o); | |
2079 UNREFERENCED(mode); | |
2080 tcn_ThrowException(e, "FIPS was not available to tcnative at build time. You
will need to re-build tcnative against an OpenSSL with FIPS."); | |
2081 return 0; | |
2082 } | |
2083 | |
2084 TCN_IMPLEMENT_CALL(jlong, SSL, newBIO)(TCN_STDARGS, jlong pool, | |
2085 jobject callback) | |
2086 { | |
2087 UNREFERENCED_STDARGS; | |
2088 UNREFERENCED(pool); | |
2089 UNREFERENCED(callback); | |
2090 return 0; | |
2091 } | |
2092 | |
2093 TCN_IMPLEMENT_CALL(jlong, SSL, newMemBIO)(TCN_STDARGS) | |
2094 { | |
2095 UNREFERENCED_STDARGS; | |
2096 return 0; | |
2097 } | |
2098 | |
2099 TCN_IMPLEMENT_CALL(jint, SSL, closeBIO)(TCN_STDARGS, jlong bio) | |
2100 { | |
2101 UNREFERENCED_STDARGS; | |
2102 UNREFERENCED(bio); | |
2103 return (jint)APR_ENOTIMPL; | |
2104 } | |
2105 | |
2106 TCN_IMPLEMENT_CALL(void, SSL, setPasswordCallback)(TCN_STDARGS, | |
2107 jobject callback) | |
2108 { | |
2109 UNREFERENCED_STDARGS; | |
2110 UNREFERENCED(callback); | |
2111 } | |
2112 | |
2113 TCN_IMPLEMENT_CALL(void, SSL, setPassword)(TCN_STDARGS, jstring password) | |
2114 { | |
2115 UNREFERENCED_STDARGS; | |
2116 UNREFERENCED(password); | |
2117 } | |
2118 | |
2119 TCN_IMPLEMENT_CALL(jboolean, SSL, generateRSATempKey)(TCN_STDARGS, jint idx) | |
2120 { | |
2121 UNREFERENCED_STDARGS; | |
2122 UNREFERENCED(idx); | |
2123 return JNI_FALSE; | |
2124 } | |
2125 | |
2126 TCN_IMPLEMENT_CALL(jboolean, SSL, loadDSATempKey)(TCN_STDARGS, jint idx, | |
2127 jstring file) | |
2128 { | |
2129 UNREFERENCED_STDARGS; | |
2130 UNREFERENCED(idx); | |
2131 UNREFERENCED(file); | |
2132 return JNI_FALSE; | |
2133 } | |
2134 | |
2135 TCN_IMPLEMENT_CALL(jstring, SSL, getLastError)(TCN_STDARGS) | |
2136 { | |
2137 UNREFERENCED_STDARGS; | |
2138 return NULL; | |
2139 } | |
2140 | |
2141 TCN_IMPLEMENT_CALL(jboolean, SSL, hasOp)(TCN_STDARGS, jint op) | |
2142 { | |
2143 UNREFERENCED_STDARGS; | |
2144 UNREFERENCED(op); | |
2145 return JNI_FALSE; | |
2146 } | |
2147 | |
2148 /*** Begin Twitter 1:1 API addition ***/ | |
2149 TCN_IMPLEMENT_CALL(jint, SSL, getLastErrorNumber)(TCN_STDARGS) { | |
2150 UNREFERENCED(o); | |
2151 tcn_ThrowException(e, "Not implemented"); | |
2152 return 0; | |
2153 } | |
2154 | |
2155 TCN_IMPLEMENT_CALL(jlong, SSL, newSSL)(TCN_STDARGS, jlong ssl_ctx) { | |
2156 UNREFERENCED(o); | |
2157 UNREFERENCED(ssl_ctx); | |
2158 tcn_ThrowException(e, "Not implemented"); | |
2159 return 0; | |
2160 } | |
2161 | |
2162 TCN_IMPLEMENT_CALL(void, SSL, setBIO)(TCN_STDARGS, jlong ssl, jlong rbio, jlong
wbio) { | |
2163 UNREFERENCED(o); | |
2164 UNREFERENCED(ssl); | |
2165 UNREFERENCED(rbio); | |
2166 UNREFERENCED(wbio); | |
2167 tcn_ThrowException(e, "Not implemented"); | |
2168 } | |
2169 | |
2170 TCN_IMPLEMENT_CALL(jint, SSL, pendingWrittenBytesInBIO)(TCN_STDARGS, jlong bio)
{ | |
2171 UNREFERENCED(o); | |
2172 UNREFERENCED(bio); | |
2173 tcn_ThrowException(e, "Not implemented"); | |
2174 return 0; | |
2175 } | |
2176 | |
2177 TCN_IMPLEMENT_CALL(jint, SSL, pendingReadableBytesInSSL)(TCN_STDARGS, jlong ssl)
{ | |
2178 UNREFERENCED(o); | |
2179 UNREFERENCED(ssl); | |
2180 tcn_ThrowException(e, "Not implemented"); | |
2181 return 0; | |
2182 } | |
2183 | |
2184 TCN_IMPLEMENT_CALL(jint, SSL, writeToBIO)(TCN_STDARGS, jlong bio, jlong wbuf, ji
nt wlen) { | |
2185 UNREFERENCED(o); | |
2186 UNREFERENCED(bio); | |
2187 UNREFERENCED(wbuf); | |
2188 UNREFERENCED(wlen); | |
2189 tcn_ThrowException(e, "Not implemented"); | |
2190 return 0; | |
2191 } | |
2192 | |
2193 TCN_IMPLEMENT_CALL(jint, SSL, readFromBIO)(TCN_STDARGS, jlong bio, jlong rbuf, j
int rlen) { | |
2194 UNREFERENCED(o); | |
2195 UNREFERENCED(bio); | |
2196 UNREFERENCED(rbuf); | |
2197 UNREFERENCED(rlen); | |
2198 tcn_ThrowException(e, "Not implemented"); | |
2199 return 0; | |
2200 } | |
2201 | |
2202 TCN_IMPLEMENT_CALL(jint, SSL, writeToSSL)(TCN_STDARGS, jlong ssl, jlong wbuf, ji
nt wlen) { | |
2203 UNREFERENCED(o); | |
2204 UNREFERENCED(ssl); | |
2205 UNREFERENCED(wbuf); | |
2206 UNREFERENCED(wlen); | |
2207 tcn_ThrowException(e, "Not implemented"); | |
2208 return 0; | |
2209 } | |
2210 | |
2211 TCN_IMPLEMENT_CALL(jint, SSL, readFromSSL)(TCN_STDARGS, jlong ssl, jlong rbuf, j
int rlen) { | |
2212 UNREFERENCED(o); | |
2213 UNREFERENCED(ssl); | |
2214 UNREFERENCED(rbuf); | |
2215 UNREFERENCED(rlen); | |
2216 tcn_ThrowException(e, "Not implemented"); | |
2217 return 0; | |
2218 } | |
2219 | |
2220 TCN_IMPLEMENT_CALL(jint, SSL, getShutdown)(TCN_STDARGS, jlong ssl) { | |
2221 UNREFERENCED(o); | |
2222 UNREFERENCED(ssl); | |
2223 tcn_ThrowException(e, "Not implemented"); | |
2224 return 0; | |
2225 } | |
2226 | |
2227 TCN_IMPLEMENT_CALL(void, SSL, setShutdown)(TCN_STDARGS, jlong ssl, jint mode) { | |
2228 UNREFERENCED(o); | |
2229 UNREFERENCED(ssl); | |
2230 UNREFERENCED(mode); | |
2231 tcn_ThrowException(e, "Not implemented"); | |
2232 } | |
2233 | |
2234 TCN_IMPLEMENT_CALL(void, SSL, freeSSL)(TCN_STDARGS, jlong ssl) { | |
2235 UNREFERENCED(o); | |
2236 UNREFERENCED(ssl); | |
2237 tcn_ThrowException(e, "Not implemented"); | |
2238 } | |
2239 | |
2240 TCN_IMPLEMENT_CALL(jlong, SSL, makeNetworkBIO)(TCN_STDARGS, jlong ssl) { | |
2241 UNREFERENCED(o); | |
2242 UNREFERENCED(ssl); | |
2243 tcn_ThrowException(e, "Not implemented"); | |
2244 return 0; | |
2245 } | |
2246 | |
2247 TCN_IMPLEMENT_CALL(void, SSL, freeBIO)(TCN_STDARGS, jlong bio) { | |
2248 UNREFERENCED(o); | |
2249 UNREFERENCED(bio); | |
2250 tcn_ThrowException(e, "Not implemented"); | |
2251 } | |
2252 | |
2253 TCN_IMPLEMENT_CALL(jint, SSL, shutdownSSL)(TCN_STDARGS, jlong ssl) { | |
2254 UNREFERENCED(o); | |
2255 UNREFERENCED(ssl); | |
2256 tcn_ThrowException(e, "Not implemented"); | |
2257 return 0; | |
2258 } | |
2259 | |
2260 TCN_IMPLEMENT_CALL(jstring, SSL, getCipherForSSL)(TCN_STDARGS, jlong ssl) { | |
2261 UNREFERENCED(o); | |
2262 UNREFERENCED(ssl); | |
2263 tcn_ThrowException(e, "Not implemented"); | |
2264 return NULL; | |
2265 } | |
2266 | |
2267 TCN_IMPLEMENT_CALL(jint, SSL, isInInit)(TCN_STDARGS, jlong ssl) { | |
2268 UNREFERENCED(o); | |
2269 UNREFERENCED(ssl); | |
2270 tcn_ThrowException(e, "Not implemented"); | |
2271 return 0; | |
2272 } | |
2273 | |
2274 TCN_IMPLEMENT_CALL(jint, SSL, doHandshake)(TCN_STDARGS, jlong ssl) { | |
2275 UNREFERENCED(o); | |
2276 UNREFERENCED(ssl); | |
2277 tcn_ThrowException(e, "Not implemented"); | |
2278 } | |
2279 | |
2280 TCN_IMPLEMENT_CALL(jstring, SSL, getNextProtoNegotiated)(TCN_STDARGS, jlong ssl)
{ | |
2281 UNREFERENCED(o); | |
2282 UNREFERENCED(ssl); | |
2283 tcn_ThrowException(e, "Not implemented"); | |
2284 return NULL; | |
2285 } | |
2286 | |
2287 /*** End Twitter 1:1 API addition ***/ | |
2288 | |
2289 /*** Begin Apple 1:1 API addition ***/ | |
2290 | |
2291 TCN_IMPLEMENT_CALL(jstring, SSL, getAlpnSelected)(TCN_STDARGS, jlong ssl) { | |
2292 UNREFERENCED(o); | |
2293 UNREFERENCED(ssl); | |
2294 tcn_ThrowException(e, "Not implemented"); | |
2295 return NULL; | |
2296 } | |
2297 | |
2298 TCN_IMPLEMENT_CALL(jobjectArray, SSL, getPeerCertChain)(TCN_STDARGS, jlong ssl) | |
2299 { | |
2300 UNREFERENCED(o); | |
2301 UNREFERENCED(ssl); | |
2302 tcn_ThrowException(e, "Not implemented"); | |
2303 return NULL; | |
2304 } | |
2305 | |
2306 TCN_IMPLEMENT_CALL(jbyteArray, SSL, getPeerCertificate)(TCN_STDARGS, jlong ssl) | |
2307 { | |
2308 UNREFERENCED(o); | |
2309 UNREFERENCED(ssl); | |
2310 tcn_ThrowException(e, "Not implemented"); | |
2311 return NULL; | |
2312 } | |
2313 | |
2314 TCN_IMPLEMENT_CALL(jstring, SSL, getErrorString)(TCN_STDARGS, jlong number) | |
2315 { | |
2316 UNREFERENCED(o); | |
2317 tcn_ThrowException(e, "Not implemented"); | |
2318 return NULL; | |
2319 } | |
2320 | |
2321 TCN_IMPLEMENT_CALL(jstring, SSL, getVersion)(TCN_STDARGS, jlong ssl) | |
2322 { | |
2323 UNREFERENCED(o); | |
2324 UNREFERENCED(ssl); | |
2325 tcn_ThrowException(e, "Not implemented"); | |
2326 return NULL; | |
2327 } | |
2328 | |
2329 TCN_IMPLEMENT_CALL(jlong, SSL, getTime)(TCN_STDARGS, jlong ssl) | |
2330 { | |
2331 UNREFERENCED(o); | |
2332 UNREFERENCED(ssl); | |
2333 tcn_ThrowException(e, "Not implemented"); | |
2334 return 0; | |
2335 } | |
2336 | |
2337 TCN_IMPLEMENT_CALL(jlong, SSL, getTimeout)(TCN_STDARGS, jlong ssl) | |
2338 { | |
2339 UNREFERENCED(o); | |
2340 UNREFERENCED(ssl); | |
2341 tcn_ThrowException(e, "Not implemented"); | |
2342 return 0; | |
2343 } | |
2344 | |
2345 TCN_IMPLEMENT_CALL(jlong, SSL, setTimeout)(TCN_STDARGS, jlong ssl, jlong seconds
) | |
2346 { | |
2347 UNREFERENCED(o); | |
2348 UNREFERENCED(ssl); | |
2349 UNREFERENCED(seconds); | |
2350 tcn_ThrowException(e, "Not implemented"); | |
2351 return 0; | |
2352 } | |
2353 | |
2354 TCN_IMPLEMENT_CALL(void, SSL, setVerify)(TCN_STDARGS, jlong ssl, | |
2355 jint level, jint depth) | |
2356 { | |
2357 UNREFERENCED(o); | |
2358 UNREFERENCED(ssl); | |
2359 tcn_ThrowException(e, "Not implemented"); | |
2360 } | |
2361 | |
2362 TCN_IMPLEMENT_CALL(void, SSL, setOptions)(TCN_STDARGS, jlong ssl, | |
2363 jint opt) | |
2364 { | |
2365 UNREFERENCED_STDARGS; | |
2366 UNREFERENCED(ssl); | |
2367 UNREFERENCED(opt); | |
2368 tcn_ThrowException(e, "Not implemented"); | |
2369 } | |
2370 | |
2371 TCN_IMPLEMENT_CALL(jint, SSL, getOptions)(TCN_STDARGS, jlong ssl) | |
2372 { | |
2373 UNREFERENCED_STDARGS; | |
2374 UNREFERENCED(ssl); | |
2375 tcn_ThrowException(e, "Not implemented"); | |
2376 return 0; | |
2377 } | |
2378 TCN_IMPLEMENT_CALL(jobjectArray, SSL, getCiphers)(TCN_STDARGS, jlong ssl) | |
2379 { | |
2380 UNREFERENCED_STDARGS; | |
2381 UNREFERENCED(ssl); | |
2382 tcn_ThrowException(e, "Not implemented"); | |
2383 return 0; | |
2384 } | |
2385 TCN_IMPLEMENT_CALL(jboolean, SSL, setCipherSuites)(TCN_STDARGS, jlong ssl, | |
2386 jstring ciphers) | |
2387 { | |
2388 UNREFERENCED_STDARGS; | |
2389 UNREFERENCED(ssl); | |
2390 UNREFERENCED(ciphers); | |
2391 tcn_ThrowException(e, "Not implemented"); | |
2392 return JNI_FALSE; | |
2393 } | |
2394 TCN_IMPLEMENT_CALL(jbyteArray, SSL, getSessionId)(TCN_STDARGS, jlong ssl) | |
2395 { | |
2396 UNREFERENCED(o); | |
2397 UNREFERENCED(ssl); | |
2398 tcn_ThrowException(e, "Not implemented"); | |
2399 } | |
2400 TCN_IMPLEMENT_CALL(jint, SSL, getHandshakeCount)(TCN_STDARGS, jlong ssl) | |
2401 { | |
2402 UNREFERENCED(o); | |
2403 UNREFERENCED(ssl); | |
2404 tcn_ThrowException(e, "Not implemented"); | |
2405 } | |
2406 | |
2407 TCN_IMPLEMENT_CALL(void, SSL, clearError)(TCN_STDARGS) | |
2408 { | |
2409 UNREFERENCED(o); | |
2410 tcn_ThrowException(e, "Not implemented"); | |
2411 } | |
2412 | |
2413 TCN_IMPLEMENT_CALL(jint, SSL, renegotiate)(TCN_STDARGS, jlong ssl) { | |
2414 UNREFERENCED(o); | |
2415 UNREFERENCED(ssl); | |
2416 tcn_ThrowException(e, "Not implemented"); | |
2417 } | |
2418 | |
2419 TCN_IMPLEMENT_CALL(void, SSL, setState)(TCN_STDARGS, jlong ssl, jint state) { | |
2420 UNREFERENCED(o); | |
2421 UNREFERENCED(ssl); | |
2422 UNREFERENCED(state); | |
2423 tcn_ThrowException(e, "Not implemented"); | |
2424 } | |
2425 /*** End Apple API Additions ***/ | |
2426 #endif | |
OLD | NEW |