| 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 |