xref: /aosp_15_r20/external/cronet/third_party/netty-tcnative/src/c/ssl.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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  */
16 /* Licensed to the Apache Software Foundation (ASF) under one or more
17  * contributor license agreements.  See the NOTICE file distributed with
18  * this work for additional information regarding copyright ownership.
19  * The ASF licenses this file to You under the Apache License, Version 2.0
20  * (the "License"); you may not use this file except in compliance with
21  * the License.  You may obtain a copy of the License at
22  *
23  *     http://www.apache.org/licenses/LICENSE-2.0
24  *
25  * Unless required by applicable law or agreed to in writing, software
26  * distributed under the License is distributed on an "AS IS" BASIS,
27  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28  * See the License for the specific language governing permissions and
29  * limitations under the License.
30  */
31 
32 #include <stdbool.h>
33 #include <openssl/bio.h>
34 #include "tcn.h"
35 #include "apr_file_io.h"
36 #include "apr_thread_mutex.h"
37 #include "apr_atomic.h"
38 #include "apr_strings.h"
39 #include "apr_portable.h"
40 #include "ssl_private.h"
41 
42 static int ssl_initialized = 0;
43 extern apr_pool_t *tcn_global_pool;
44 
45 ENGINE *tcn_ssl_engine = NULL;
46 void *SSL_temp_keys[SSL_TMP_KEY_MAX];
47 
48 /* Global reference to the pool used by the dynamic mutexes */
49 static apr_pool_t *dynlockpool = NULL;
50 
51 /* Dynamic lock structure */
52 struct CRYPTO_dynlock_value {
53     apr_pool_t *pool;
54     const char* file;
55     int line;
56     apr_thread_mutex_t *mutex;
57 };
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 };
69 
70 /*
71  * Handle the Temporary RSA Keys and DH Params
72  */
73 
74 #define SSL_TMP_KEY_FREE(type, idx)                     \
75     if (SSL_temp_keys[idx]) {                           \
76         type##_free((type *)SSL_temp_keys[idx]);        \
77         SSL_temp_keys[idx] = NULL;                      \
78     } else (void)(0)
79 
80 #define SSL_TMP_KEYS_FREE(type) \
81     SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_512);   \
82     SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_1024);  \
83     SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_2048);  \
84     SSL_TMP_KEY_FREE(type, SSL_TMP_KEY_##type##_4096)
85 
86 #define SSL_TMP_KEY_INIT_DH(bits)  \
87     ssl_tmp_key_init_dh(bits, SSL_TMP_KEY_DH_##bits)
88 
89 #define SSL_TMP_KEYS_INIT(R)                    \
90     R |= SSL_TMP_KEY_INIT_DH(512);              \
91     R |= SSL_TMP_KEY_INIT_DH(1024);             \
92     R |= SSL_TMP_KEY_INIT_DH(2048);             \
93     R |= SSL_TMP_KEY_INIT_DH(4096)
94 
95 /*
96  * supported_ssl_opts is a bitmask that contains all supported SSL_OP_*
97  * options at compile-time. This is used in hasOp to determine which
98  * SSL_OP_* options are available at runtime.
99  *
100  * Note that at least up through OpenSSL 0.9.8o, checking SSL_OP_ALL will
101  * return JNI_FALSE because SSL_OP_ALL is a mask that covers all bug
102  * workarounds for OpenSSL including future workarounds that are defined
103  * to be in the least-significant 3 nibbles of the SSL_OP_* bit space.
104  *
105  * This implementation has chosen NOT to simply set all those lower bits
106  * so that the return value for SSL_OP_FUTURE_WORKAROUND will only be
107  * reported by versions that actually support that specific workaround.
108  */
109 static const jint supported_ssl_opts = 0
110 /*
111   Specifically skip SSL_OP_ALL
112 #ifdef SSL_OP_ALL
113      | SSL_OP_ALL
114 #endif
115 */
116 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
117      | SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
118 #endif
119 
120 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
121      | SSL_OP_CIPHER_SERVER_PREFERENCE
122 #endif
123 
124 #ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
125      | SSL_OP_CRYPTOPRO_TLSEXT_BUG
126 #endif
127 
128 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
129      | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
130 #endif
131 
132 #ifdef SSL_OP_LEGACY_SERVER_CONNECT
133      | SSL_OP_LEGACY_SERVER_CONNECT
134 #endif
135 
136 #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
137      | SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
138 #endif
139 
140 #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
141      | SSL_OP_MICROSOFT_SESS_ID_BUG
142 #endif
143 
144 #ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
145      | SSL_OP_MSIE_SSLV2_RSA_PADDING
146 #endif
147 
148 #ifdef SSL_OP_NETSCAPE_CA_DN_BUG
149      | SSL_OP_NETSCAPE_CA_DN_BUG
150 #endif
151 
152 #ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
153      | SSL_OP_NETSCAPE_CHALLENGE_BUG
154 #endif
155 
156 #ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
157      | SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
158 #endif
159 
160 #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
161      | SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
162 #endif
163 
164 #ifdef SSL_OP_NO_COMPRESSION
165      | SSL_OP_NO_COMPRESSION
166 #endif
167 
168 #ifdef SSL_OP_NO_QUERY_MTU
169      | SSL_OP_NO_QUERY_MTU
170 #endif
171 
172 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
173      | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
174 #endif
175 
176 #ifdef SSL_OP_NO_SSLv2
177      | SSL_OP_NO_SSLv2
178 #endif
179 
180 #ifdef SSL_OP_NO_SSLv3
181      | SSL_OP_NO_SSLv3
182 #endif
183 
184 #ifdef SSL_OP_NO_TICKET
185      | SSL_OP_NO_TICKET
186 #endif
187 
188 #ifdef SSL_OP_NO_TLSv1
189      | SSL_OP_NO_TLSv1
190 #endif
191 
192 #ifdef SSL_OP_PKCS1_CHECK_1
193      | SSL_OP_PKCS1_CHECK_1
194 #endif
195 
196 #ifdef SSL_OP_PKCS1_CHECK_2
197      | SSL_OP_PKCS1_CHECK_2
198 #endif
199 
200 #ifdef SSL_OP_NO_TLSv1_1
201      | SSL_OP_NO_TLSv1_1
202 #endif
203 
204 #ifdef SSL_OP_NO_TLSv1_2
205      | SSL_OP_NO_TLSv1_2
206 #endif
207 
208 #ifdef SSL_OP_SINGLE_DH_USE
209      | SSL_OP_SINGLE_DH_USE
210 #endif
211 
212 #ifdef SSL_OP_SINGLE_ECDH_USE
213      | SSL_OP_SINGLE_ECDH_USE
214 #endif
215 
216 #ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
217      | SSL_OP_SSLEAY_080_CLIENT_DH_BUG
218 #endif
219 
220 #ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
221      | SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
222 #endif
223 
224 #ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
225      | SSL_OP_TLS_BLOCK_PADDING_BUG
226 #endif
227 
228 #ifdef SSL_OP_TLS_D5_BUG
229      | SSL_OP_TLS_D5_BUG
230 #endif
231 
232 #ifdef SSL_OP_TLS_ROLLBACK_BUG
233      | SSL_OP_TLS_ROLLBACK_BUG
234 #endif
235      | 0;
236 
tcn_flush_sslbuffer_to_bytebuffer(struct TCN_bio_bytebuffer * bioUserData)237 static jint tcn_flush_sslbuffer_to_bytebuffer(struct TCN_bio_bytebuffer* bioUserData) {
238     jint writeAmount = TCN_MIN(bioUserData->bufferLength, bioUserData->nonApplicationBufferLength) * sizeof(char);
239     jint writeChunk = bioUserData->nonApplicationBufferSize - bioUserData->nonApplicationBufferOffset;
240 
241 #ifdef NETTY_TCNATIVE_BIO_DEBUG
242     fprintf(stderr, "tcn_flush_sslbuffer_to_bytebuffer1 bioUserData->nonApplicationBufferLength %d bioUserData->nonApplicationBufferOffset %d writeChunk %d writeAmount %d\n", bioUserData->nonApplicationBufferLength, bioUserData->nonApplicationBufferOffset, writeChunk, writeAmount);
243 #endif
244 
245     // check if we need to account for wrap around when draining the internal SSL buffer.
246     if (writeAmount > writeChunk) {
247         jint newnonApplicationBufferOffset = writeAmount - writeChunk;
248         memcpy(bioUserData->buffer, &bioUserData->nonApplicationBuffer[bioUserData->nonApplicationBufferOffset], (size_t) writeChunk);
249         memcpy(&bioUserData->buffer[writeChunk], bioUserData->nonApplicationBuffer, (size_t) newnonApplicationBufferOffset);
250         bioUserData->nonApplicationBufferOffset = newnonApplicationBufferOffset;
251     } else {
252         memcpy(bioUserData->buffer, &bioUserData->nonApplicationBuffer[bioUserData->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* type
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->nonApplicationBufferLength %d bioUserData->nonApplicationBufferOffset %d\n", bioUserData->nonApplicationBufferLength, bioUserData->nonApplicationBufferOffset);
265 #endif
266 
267     return writeAmount;
268 }
269 
tcn_write_to_bytebuffer(BIO * bio,const char * in,int inl)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_get_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->nonApplicationBufferSize - 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) * sizeof(char);
298         startIndex = bioUserData->nonApplicationBufferOffset + bioUserData->nonApplicationBufferLength;
299         writeChunk = bioUserData->nonApplicationBufferSize - startIndex;
300 
301 #ifdef NETTY_TCNATIVE_BIO_DEBUG
302         fprintf(stderr, "tcn_write_to_bytebuffer bioUserData->nonApplicationBufferLength %d bioUserData->nonApplicationBufferOffset %d startIndex %d writeChunk %d writeAmount %d\n", bioUserData->nonApplicationBufferLength, bioUserData->nonApplicationBufferOffset, 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 actually 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 
tcn_read_from_bytebuffer(BIO * bio,char * out,int outl)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_get_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 || bioUserData->bufferLength == 0) {
356         // During handshake this may happen, and it means we are not setup to read 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 
bio_java_bytebuffer_create(BIO * bio)374 static int bio_java_bytebuffer_create(BIO* bio) {
375     struct TCN_bio_bytebuffer* bioUserData = (struct TCN_bio_bytebuffer*) OPENSSL_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 operation.
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 relies on some shutdown and init state.
391     // The behavior expected by OpenSSL can be found here: https://www.openssl.org/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 
bio_java_bytebuffer_destroy(BIO * bio)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 
bio_java_bytebuffer_write(BIO * bio,const char * in,int inl)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 
bio_java_bytebuffer_read(BIO * bio,char * out,int outl)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 
bio_java_bytebuffer_puts(BIO * bio,const char * in)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 
bio_java_bytebuffer_gets(BIO * b,char * out,int outl)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 
bio_java_bytebuffer_ctrl(BIO * bio,int cmd,long num,void * ptr)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 
TCN_IMPLEMENT_CALL(jint,SSL,bioLengthByteBuffer)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 
TCN_IMPLEMENT_CALL(jint,SSL,bioLengthNonApplication)470 TCN_IMPLEMENT_CALL(jint, SSL, bioLengthNonApplication)(TCN_STDARGS, jlong bioAddress) {
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 };
496 #else
497 static BIO_METHOD* bio_java_bytebuffer_methods = NULL;
498 
init_bio_methods(void)499 static void init_bio_methods(void) {
500     bio_java_bytebuffer_methods = BIO_meth_new(BIO_TYPE_MEM, "Java ByteBuffer");
501     BIO_meth_set_write(bio_java_bytebuffer_methods, &bio_java_bytebuffer_write);
502     BIO_meth_set_read(bio_java_bytebuffer_methods, &bio_java_bytebuffer_read);
503     BIO_meth_set_puts(bio_java_bytebuffer_methods, &bio_java_bytebuffer_puts);
504     BIO_meth_set_gets(bio_java_bytebuffer_methods, &bio_java_bytebuffer_gets);
505     BIO_meth_set_ctrl(bio_java_bytebuffer_methods, &bio_java_bytebuffer_ctrl);
506     BIO_meth_set_create(bio_java_bytebuffer_methods, &bio_java_bytebuffer_create);
507     BIO_meth_set_destroy(bio_java_bytebuffer_methods, &bio_java_bytebuffer_destroy);
508 }
509 
free_bio_methods(void)510 static void free_bio_methods(void) {
511     BIO_meth_free(bio_java_bytebuffer_methods);
512 }
513 #endif
514 
BIO_java_bytebuffer()515 static BIO_METHOD* BIO_java_bytebuffer() {
516 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
517     return &bio_java_bytebuffer_methods;
518 #else
519     return bio_java_bytebuffer_methods;
520 #endif
521 }
522 
ssl_tmp_key_init_dh(int bits,int idx)523 static int ssl_tmp_key_init_dh(int bits, int idx)
524 {
525 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(OPENSSL_USE_DEPRECATED) || defined(LIBRESSL_VERSION_NUMBER)
526     return (SSL_temp_keys[idx] = SSL_dh_get_tmp_param(bits)) ? 0 : 1;
527 #else
528     return 0;
529 #endif
530 }
531 
TCN_IMPLEMENT_CALL(jint,SSL,version)532 TCN_IMPLEMENT_CALL(jint, SSL, version)(TCN_STDARGS)
533 {
534     UNREFERENCED_STDARGS;
535     return OpenSSL_version_num();
536 }
537 
TCN_IMPLEMENT_CALL(jstring,SSL,versionString)538 TCN_IMPLEMENT_CALL(jstring, SSL, versionString)(TCN_STDARGS)
539 {
540     UNREFERENCED(o);
541     return AJP_TO_JSTRING(OpenSSL_version(OPENSSL_VERSION));
542 }
543 
544 /*
545  *  the various processing hooks
546  */
ssl_init_cleanup(void * data)547 static apr_status_t ssl_init_cleanup(void *data)
548 {
549     UNREFERENCED(data);
550 
551     if (!ssl_initialized)
552         return APR_SUCCESS;
553     ssl_initialized = 0;
554 
555     SSL_TMP_KEYS_FREE(DH);
556     /*
557      * Try to kill the internals of the SSL library.
558      */
559 #if OPENSSL_VERSION_NUMBER >= 0x00907001 && !defined(OPENSSL_IS_BORINGSSL)
560     /* Corresponds to OPENSSL_load_builtin_modules():
561      * XXX: borrowed from apps.h, but why not CONF_modules_free()
562      * which also invokes CONF_modules_finish()?
563      */
564     CONF_modules_unload(1);
565 #endif
566     /* Corresponds to SSL_library_init: */
567     EVP_cleanup();
568 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
569     ENGINE_cleanup();
570 #endif
571 #if OPENSSL_VERSION_NUMBER >= 0x00907001
572     CRYPTO_cleanup_all_ex_data();
573 #endif
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
580 
581     /* Don't call ERR_free_strings here; ERR_load_*_strings only
582      * actually load the error strings once per process due to static
583      * variable abuse in OpenSSL. */
584 
585     /*
586      * TODO: determine somewhere we can safely shove out diagnostics
587      *       (when enabled) at this late stage in the game:
588      * CRYPTO_mem_leaks_fp(stderr);
589      */
590     return APR_SUCCESS;
591 }
592 
593 #ifndef OPENSSL_NO_ENGINE
594 /* Try to load an engine in a shareable library */
ssl_try_load_engine(const char * engine)595 static ENGINE *ssl_try_load_engine(const char *engine)
596 {
597     ENGINE *e = ENGINE_by_id("dynamic");
598     if (e) {
599         if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
600             || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
601             ENGINE_free(e);
602             e = NULL;
603         }
604     }
605     return e;
606 }
607 #endif
608 
609 /*
610  * To ensure thread-safetyness in OpenSSL
611  */
612 
613 static apr_thread_mutex_t **ssl_lock_cs;
614 static int                  ssl_lock_num_locks;
615 
ssl_thread_lock(int mode,int type,const char * file,int line)616 static void ssl_thread_lock(int mode, int type,
617                             const char *file, int line)
618 {
619     UNREFERENCED(file);
620     UNREFERENCED(line);
621     if (type < ssl_lock_num_locks) {
622         if (mode & CRYPTO_LOCK) {
623             apr_thread_mutex_lock(ssl_lock_cs[type]);
624         }
625         else {
626             apr_thread_mutex_unlock(ssl_lock_cs[type]);
627         }
628     }
629 }
630 
ssl_thread_id(void)631 static unsigned long ssl_thread_id(void)
632 {
633     /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
634      * id is a structure twice that big.  Use the TCB pointer instead as a
635      * unique unsigned long.
636      */
637 #ifdef __MVS__
638     struct PSA {
639         char unmapped[540];
640         unsigned long PSATOLD;
641     } *psaptr = 0;
642 
643     return psaptr->PSATOLD;
644 #elif defined(WIN32)
645     return (unsigned long)GetCurrentThreadId();
646 #else
647     return (unsigned long)(apr_os_thread_current());
648 #endif
649 }
650 
ssl_set_thread_id(CRYPTO_THREADID * id)651 static void ssl_set_thread_id(CRYPTO_THREADID *id)
652 {
653     CRYPTO_THREADID_set_numeric(id, ssl_thread_id());
654 }
655 
ssl_thread_cleanup(void * data)656 static apr_status_t ssl_thread_cleanup(void *data)
657 {
658     UNREFERENCED(data);
659     CRYPTO_set_locking_callback(NULL);
660     CRYPTO_THREADID_set_callback(NULL);
661     CRYPTO_set_dynlock_create_callback(NULL);
662     CRYPTO_set_dynlock_lock_callback(NULL);
663     CRYPTO_set_dynlock_destroy_callback(NULL);
664 
665     dynlockpool = NULL;
666 
667     /* Let the registered mutex cleanups do their own thing
668      */
669     return APR_SUCCESS;
670 }
671 
672 /*
673  * Dynamic lock creation callback
674  */
ssl_dyn_create_function(const char * file,int line)675 static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
676                                                      int line)
677 {
678     struct CRYPTO_dynlock_value *value;
679     apr_pool_t *p;
680     apr_status_t rv;
681 
682     /*
683      * We need a pool to allocate our mutex.  Since we can't clear
684      * allocated memory from a pool, create a subpool that we can blow
685      * away in the destruction callback.
686      */
687     rv = apr_pool_create(&p, dynlockpool);
688     if (rv != APR_SUCCESS) {
689         /* TODO log that fprintf(stderr, "Failed to create subpool for dynamic lock"); */
690         return NULL;
691     }
692 
693     value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
694                                                       sizeof(struct CRYPTO_dynlock_value));
695     if (!value) {
696         /* TODO log that fprintf(stderr, "Failed to allocate dynamic lock structure"); */
697         return NULL;
698     }
699 
700     value->pool = p;
701     /* Keep our own copy of the place from which we were created,
702        using our own pool. */
703     value->file = apr_pstrdup(p, file);
704     value->line = line;
705     rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
706                                 p);
707     if (rv != APR_SUCCESS) {
708         /* TODO log that fprintf(stderr, "Failed to create thread mutex for dynamic lock"); */
709         apr_pool_destroy(p);
710         return NULL;
711     }
712     return value;
713 }
714 
715 /*
716  * Dynamic locking and unlocking function
717  */
ssl_dyn_lock_function(int mode,struct CRYPTO_dynlock_value * l,const char * file,int line)718 static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
719                            const char *file, int line)
720 {
721     if (mode & CRYPTO_LOCK) {
722         apr_thread_mutex_lock(l->mutex);
723     }
724     else {
725         apr_thread_mutex_unlock(l->mutex);
726     }
727 }
728 
729 /*
730  * Dynamic lock destruction callback
731  */
ssl_dyn_destroy_function(struct CRYPTO_dynlock_value * l,const char * file,int line)732 static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
733                           const char *file, int line)
734 {
735     apr_status_t rv;
736     rv = apr_thread_mutex_destroy(l->mutex);
737     if (rv != APR_SUCCESS) {
738         /* TODO log that fprintf(stderr, "Failed to destroy mutex for dynamic lock %s:%d", l->file, l->line); */
739     }
740 
741     /* Trust that whomever owned the CRYPTO_dynlock_value we were
742      * passed has no future use for it...
743      */
744     apr_pool_destroy(l->pool);
745 }
746 
ssl_thread_setup(apr_pool_t * p)747 static void ssl_thread_setup(apr_pool_t *p)
748 {
749     int i;
750 
751     ssl_lock_num_locks = CRYPTO_num_locks();
752     ssl_lock_cs = apr_palloc(p, ssl_lock_num_locks * sizeof(*ssl_lock_cs));
753 
754     for (i = 0; i < ssl_lock_num_locks; i++) {
755         apr_thread_mutex_create(&(ssl_lock_cs[i]),
756                                 APR_THREAD_MUTEX_DEFAULT, p);
757     }
758 
759     CRYPTO_THREADID_set_callback(ssl_set_thread_id);
760     CRYPTO_set_locking_callback(ssl_thread_lock);
761 
762     /* Set up dynamic locking scaffolding for OpenSSL to use at its
763      * convenience.
764      */
765     dynlockpool = p;
766     CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
767     CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
768     CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
769 
770     apr_pool_cleanup_register(p, NULL, ssl_thread_cleanup,
771                               apr_pool_cleanup_null);
772 }
773 
TCN_IMPLEMENT_CALL(jint,SSL,initialize)774 TCN_IMPLEMENT_CALL(jint, SSL, initialize)(TCN_STDARGS, jstring engine)
775 {
776     int r = 0;
777 
778     TCN_ALLOC_CSTRING(engine);
779 
780     UNREFERENCED(o);
781     if (!tcn_global_pool) {
782         TCN_FREE_CSTRING(engine);
783         tcn_ThrowAPRException(e, APR_EINVAL);
784         return (jint)APR_EINVAL;
785     }
786     /* Check if already initialized */
787     if (ssl_initialized++) {
788         TCN_FREE_CSTRING(engine);
789         return (jint)APR_SUCCESS;
790     }
791 
792 #if OPENSSL_VERSION_NUMBER < 0x10100000L
793     if (SSLeay() < 0x0090700L) {
794         TCN_FREE_CSTRING(engine);
795         tcn_ThrowAPRException(e, APR_EINVAL);
796         ssl_initialized = 0;
797         return (jint)APR_EINVAL;
798     }
799 #endif
800 
801 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
802     /* We must register the library in full, to ensure our configuration
803      * code can successfully test the SSL environment.
804      */
805     OPENSSL_malloc_init();
806 #endif
807 
808     ERR_load_crypto_strings();
809     SSL_load_error_strings();
810     SSL_library_init();
811     OpenSSL_add_all_algorithms();
812 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
813     ENGINE_load_builtin_engines();
814 #endif
815 #if OPENSSL_VERSION_NUMBER >= 0x00907001
816     OPENSSL_load_builtin_modules();
817 #endif
818 
819     /* Initialize thread support */
820     ssl_thread_setup(tcn_global_pool);
821 
822 #ifndef OPENSSL_NO_ENGINE
823     if (J2S(engine)) {
824         ENGINE *ee = NULL;
825         apr_status_t err = APR_SUCCESS;
826         if(strcmp(J2S(engine), "auto") == 0) {
827             ENGINE_register_all_complete();
828         }
829         else {
830             if ((ee = ENGINE_by_id(J2S(engine))) == NULL
831                 && (ee = ssl_try_load_engine(J2S(engine))) == NULL)
832                 err = APR_ENOTIMPL;
833             else {
834 #ifdef ENGINE_CTRL_CHIL_SET_FORKCHECK
835                 if (strcmp(J2S(engine), "chil") == 0)
836                     ENGINE_ctrl(ee, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
837 #endif
838                 if (!ENGINE_set_default(ee, ENGINE_METHOD_ALL))
839                     err = APR_ENOTIMPL;
840             }
841             /* Free our "structural" reference. */
842             if (ee)
843                 ENGINE_free(ee);
844         }
845         if (err != APR_SUCCESS) {
846             TCN_FREE_CSTRING(engine);
847             ssl_init_cleanup(NULL);
848             tcn_ThrowAPRException(e, err);
849             return (jint)err;
850         }
851         tcn_ssl_engine = ee;
852     }
853 #endif
854 
855     // For SSL_get_app_data*() at request time
856     SSL_init_app_data_idx();
857 
858 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
859     init_bio_methods();
860 #endif
861 
862     SSL_TMP_KEYS_INIT(r);
863     if (r) {
864         ERR_clear_error();
865         TCN_FREE_CSTRING(engine);
866         ssl_init_cleanup(NULL);
867         tcn_ThrowAPRException(e, APR_ENOTIMPL);
868         return APR_ENOTIMPL;
869     }
870     /*
871      * Let us cleanup the ssl library when the library is unloaded
872      */
873     apr_pool_cleanup_register(tcn_global_pool, NULL,
874                               ssl_init_cleanup,
875                               apr_pool_cleanup_null);
876     TCN_FREE_CSTRING(engine);
877 
878     return (jint)APR_SUCCESS;
879 }
880 
TCN_IMPLEMENT_CALL(jlong,SSL,newMemBIO)881 TCN_IMPLEMENT_CALL(jlong, SSL, newMemBIO)(TCN_STDARGS)
882 {
883     BIO *bio = NULL;
884 
885     UNREFERENCED(o);
886 
887     // TODO: Use BIO_s_secmem() once included in stable release
888     if ((bio = BIO_new(BIO_s_mem())) == NULL) {
889         tcn_ThrowException(e, "Create BIO failed");
890         return 0;
891     }
892     return P2J(bio);
893 }
894 
TCN_IMPLEMENT_CALL(jstring,SSL,getLastError)895 TCN_IMPLEMENT_CALL(jstring, SSL, getLastError)(TCN_STDARGS)
896 {
897     char buf[ERR_LEN];
898     UNREFERENCED(o);
899     ERR_error_string(ERR_get_error(), buf);
900     return tcn_new_string(e, buf);
901 }
902 
TCN_IMPLEMENT_CALL(jboolean,SSL,hasOp)903 TCN_IMPLEMENT_CALL(jboolean, SSL, hasOp)(TCN_STDARGS, jint op)
904 {
905     return op == (op & supported_ssl_opts) ? JNI_TRUE : JNI_FALSE;
906 }
907 
908 /*** Begin Twitter 1:1 API addition ***/
TCN_IMPLEMENT_CALL(jint,SSL,getLastErrorNumber)909 TCN_IMPLEMENT_CALL(jint, SSL, getLastErrorNumber)(TCN_STDARGS) {
910     UNREFERENCED_STDARGS;
911     return ERR_get_error();
912 }
913 
ssl_info_callback(const SSL * ssl,int where,int ret)914 static void ssl_info_callback(const SSL *ssl, int where, int ret) {
915     int *handshakeCount = NULL;
916     if (0 != (where & SSL_CB_HANDSHAKE_START)) {
917         handshakeCount = (int*) SSL_get_app_data3((SSL*) ssl);
918         if (handshakeCount != NULL) {
919             ++(*handshakeCount);
920         }
921     }
922 }
923 
TCN_IMPLEMENT_CALL(jlong,SSL,newSSL)924 TCN_IMPLEMENT_CALL(jlong /* SSL * */, SSL, newSSL)(TCN_STDARGS,
925                                                    jlong ctx /* tcn_ssl_ctxt_t * */,
926                                                    jboolean server) {
927     SSL *ssl = NULL;
928     int *handshakeCount = NULL;
929     tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
930 
931     if (c == NULL) {
932         tcn_ThrowException(e, "ssl ctx is null");
933         return 0;
934     }
935     if (c->ctx == NULL) {
936         tcn_ThrowException(e, "ctx is null");
937         return 0;
938     }
939 
940     UNREFERENCED_STDARGS;
941 
942     ssl = SSL_new(c->ctx);
943     if (ssl == NULL) {
944         tcn_ThrowException(e, "cannot create new ssl");
945         return 0;
946     }
947 
948     // Set the app_data2 before all the others because it may be used in SSL_free.
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 initalized.
954     SSL_set_app_data4(ssl, &c->verify_config);
955 
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 
964     *handshakeCount = 0;
965     SSL_set_app_data3(ssl, handshakeCount);
966 
967     // Add callback to keep track of handshakes.
968     SSL_CTX_set_info_callback(c->ctx, ssl_info_callback);
969 
970     if (server) {
971         SSL_set_accept_state(ssl);
972     } else {
973         SSL_set_connect_state(ssl);
974     }
975 
976     return P2J(ssl);
977 }
978 
TCN_IMPLEMENT_CALL(jint,SSL,getError)979 TCN_IMPLEMENT_CALL(jint, SSL, getError)(TCN_STDARGS,
980                                        jlong ssl /* SSL * */,
981                                        jint ret) {
982     SSL *ssl_ = J2P(ssl, SSL *);
983 
984     if (ssl_ == NULL) {
985         tcn_ThrowException(e, "ssl is null");
986         return 0;
987     }
988 
989     UNREFERENCED_STDARGS;
990 
991     return SSL_get_error(ssl_, ret);
992 }
993 
994 // Write wlen bytes from wbuf into bio
TCN_IMPLEMENT_CALL(jint,SSL,bioWrite)995 TCN_IMPLEMENT_CALL(jint /* status */, SSL, bioWrite)(TCN_STDARGS,
996                                                      jlong bioAddress /* BIO* */,
997                                                      jlong wbufAddress /* char* */,
998                                                      jint wlen /* sizeof(wbuf) */) {
999     BIO* bio = J2P(bioAddress, BIO*);
1000     void* wbuf = J2P(wbufAddress, void*);
1001 
1002     if (bio == NULL) {
1003         tcn_ThrowException(e, "bio is null");
1004         return 0;
1005     }
1006     if (wbuf == NULL) {
1007         tcn_ThrowException(e, "wbuf is null");
1008         return 0;
1009     }
1010 
1011     UNREFERENCED_STDARGS;
1012 
1013     return BIO_write(bio, wbuf, wlen);
1014 }
1015 
TCN_IMPLEMENT_CALL(void,SSL,bioSetByteBuffer)1016 TCN_IMPLEMENT_CALL(void, SSL, bioSetByteBuffer)(TCN_STDARGS,
1017                                                 jlong bioAddress /* BIO* */,
1018                                                 jlong bufferAddress /* Address for direct memory */,
1019                                                 jint maxUsableBytes /* max number of bytes to use */,
1020                                                 jboolean isSSLWriteSink) {
1021     BIO* bio = J2P(bioAddress, BIO*);
1022     char* buffer = J2P(bufferAddress, char*);
1023     struct TCN_bio_bytebuffer* bioUserData = NULL;
1024     TCN_ASSERT(bio != NULL);
1025     TCN_ASSERT(buffer != NULL);
1026 
1027     bioUserData = (struct TCN_bio_bytebuffer*) BIO_get_data(bio);
1028     TCN_ASSERT(bioUserData != NULL);
1029 
1030     bioUserData->buffer = buffer;
1031     bioUserData->bufferLength = maxUsableBytes;
1032     bioUserData->bufferIsSSLWriteSink = (bool) isSSLWriteSink;
1033 }
1034 
TCN_IMPLEMENT_CALL(void,SSL,bioClearByteBuffer)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;
1041     }
1042 
1043     bioUserData->buffer = NULL;
1044     bioUserData->bufferLength = 0;
1045     bioUserData->bufferIsSSLWriteSink = false;
1046 }
1047 
TCN_IMPLEMENT_CALL(jint,SSL,bioFlushByteBuffer)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)) == NULL ||
1054             bioUserData->nonApplicationBufferLength == 0 ||
1055             bioUserData->buffer == NULL ||
1056            !bioUserData->bufferIsSSLWriteSink) ? 0 : tcn_flush_sslbuffer_to_bytebuffer(bioUserData);
1057 }
1058 
1059 // Write up to wlen bytes of application data to the ssl BIO (encrypt)
TCN_IMPLEMENT_CALL(jint,SSL,writeToSSL)1060 TCN_IMPLEMENT_CALL(jint /* status */, SSL, writeToSSL)(TCN_STDARGS,
1061                                                        jlong ssl /* SSL * */,
1062                                                        jlong wbuf /* char * */,
1063                                                        jint wlen /* sizeof(wbuf) */) {
1064     SSL *ssl_ = J2P(ssl, SSL *);
1065     void *w = J2P(wbuf, void *);
1066 
1067     if (ssl_ == NULL) {
1068         tcn_ThrowException(e, "ssl is null");
1069         return 0;
1070     }
1071     if (w == NULL) {
1072         tcn_ThrowException(e, "wbuf is null");
1073         return 0;
1074     }
1075 
1076     UNREFERENCED_STDARGS;
1077 
1078     return SSL_write(ssl_, w, wlen);
1079 }
1080 
1081 // Read up to rlen bytes of application data from the given SSL BIO (decrypt)
TCN_IMPLEMENT_CALL(jint,SSL,readFromSSL)1082 TCN_IMPLEMENT_CALL(jint /* status */, SSL, readFromSSL)(TCN_STDARGS,
1083                                                         jlong ssl /* SSL * */,
1084                                                         jlong rbuf /* char * */,
1085                                                         jint rlen /* sizeof(rbuf) - 1 */) {
1086     SSL *ssl_ = J2P(ssl, SSL *);
1087     void *r = J2P(rbuf, void *);
1088 
1089     if (ssl_ == NULL) {
1090         tcn_ThrowException(e, "ssl is null");
1091         return 0;
1092     }
1093     if (r == NULL) {
1094         tcn_ThrowException(e, "rbuf is null");
1095         return 0;
1096     }
1097 
1098     UNREFERENCED_STDARGS;
1099 
1100     return SSL_read(ssl_, r, rlen);
1101 }
1102 
1103 // Get the shutdown status of the engine
TCN_IMPLEMENT_CALL(jint,SSL,getShutdown)1104 TCN_IMPLEMENT_CALL(jint /* status */, SSL, getShutdown)(TCN_STDARGS,
1105                                                         jlong ssl /* SSL * */) {
1106     SSL *ssl_ = J2P(ssl, SSL *);
1107 
1108     if (ssl_ == NULL) {
1109         tcn_ThrowException(e, "ssl is null");
1110         return 0;
1111     }
1112 
1113     UNREFERENCED_STDARGS;
1114 
1115     return SSL_get_shutdown(ssl_);
1116 }
1117 
1118 // Called when the peer closes the connection
TCN_IMPLEMENT_CALL(void,SSL,setShutdown)1119 TCN_IMPLEMENT_CALL(void, SSL, setShutdown)(TCN_STDARGS,
1120                                            jlong ssl /* SSL * */,
1121                                            jint mode) {
1122     SSL *ssl_ = J2P(ssl, SSL *);
1123 
1124     if (ssl_ == NULL) {
1125         tcn_ThrowException(e, "ssl is null");
1126         return;
1127     }
1128 
1129     UNREFERENCED_STDARGS;
1130 
1131     SSL_set_shutdown(ssl_, mode);
1132 }
1133 
1134 // Free the SSL * and its associated internal BIO
TCN_IMPLEMENT_CALL(void,SSL,freeSSL)1135 TCN_IMPLEMENT_CALL(void, SSL, freeSSL)(TCN_STDARGS,
1136                                        jlong ssl /* SSL * */) {
1137     int *handshakeCount = NULL;
1138     tcn_ssl_ctxt_t* c = NULL;
1139     tcn_ssl_verify_config_t* verify_config = NULL;
1140     SSL *ssl_ = J2P(ssl, SSL *);
1141     if (ssl_ == NULL) {
1142         tcn_ThrowException(e, "ssl is null");
1143         return;
1144     }
1145     c = SSL_get_app_data2(ssl_);
1146     handshakeCount = SSL_get_app_data3(ssl_);
1147     verify_config = SSL_get_app_data4(ssl_);
1148 
1149     UNREFERENCED_STDARGS;
1150     TCN_ASSERT(c != NULL);
1151 
1152     if (handshakeCount != NULL) {
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);
1161     }
1162     SSL_free(ssl_);
1163 }
1164 
TCN_IMPLEMENT_CALL(jlong,SSL,bioNewByteBuffer)1165 TCN_IMPLEMENT_CALL(jlong, SSL, bioNewByteBuffer)(TCN_STDARGS,
1166                                                  jlong ssl /* SSL* */,
1167                                                  jint nonApplicationBufferSize) {
1168     SSL* ssl_ = J2P(ssl, SSL*);
1169     BIO* bio;
1170     struct TCN_bio_bytebuffer* bioUserData;
1171 
1172     if (ssl_ == NULL) {
1173         tcn_ThrowException(e, "ssl is null");
1174         return 0;
1175     }
1176 
1177     if (nonApplicationBufferSize <= 0) {
1178         tcn_ThrowException(e, "nonApplicationBufferSize <= 0");
1179         return 0;
1180     }
1181 
1182     bio = BIO_new(BIO_java_bytebuffer());
1183     if (bio == NULL) {
1184         tcn_ThrowException(e, "BIO_new failed");
1185         return 0;
1186     }
1187 
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     }
1194 
1195     bioUserData->nonApplicationBuffer = (char*) OPENSSL_malloc(nonApplicationBufferSize * sizeof(char));
1196     if (bioUserData->nonApplicationBuffer == NULL) {
1197         BIO_free(bio);
1198         tcn_Throw(e, "Failed to allocate internal buffer of size %d", nonApplicationBufferSize);
1199         return 0;
1200     }
1201     bioUserData->nonApplicationBufferSize = nonApplicationBufferSize;
1202 
1203     SSL_set_bio(ssl_, bio, bio);
1204 
1205     return P2J(bio);
1206 }
1207 
1208 // Free a BIO * (typically, the network BIO)
TCN_IMPLEMENT_CALL(void,SSL,freeBIO)1209 TCN_IMPLEMENT_CALL(void, SSL, freeBIO)(TCN_STDARGS,
1210                                        jlong bio /* BIO * */) {
1211     BIO *bio_ = J2P(bio, BIO *);
1212 
1213     UNREFERENCED_STDARGS;
1214 
1215     if (bio_ != NULL) {
1216         BIO_free(bio_);
1217     }
1218 }
1219 
1220 // Send CLOSE_NOTIFY to peer
TCN_IMPLEMENT_CALL(jint,SSL,shutdownSSL)1221 TCN_IMPLEMENT_CALL(jint /* status */, SSL, shutdownSSL)(TCN_STDARGS,
1222                                                         jlong ssl /* SSL * */) {
1223     SSL *ssl_ = J2P(ssl, SSL *);
1224 
1225     if (ssl_ == NULL) {
1226         tcn_ThrowException(e, "ssl is null");
1227         return 0;
1228     }
1229 
1230     UNREFERENCED_STDARGS;
1231 
1232     return SSL_shutdown(ssl_);
1233 }
1234 
1235 // Read which cipher was negotiated for the given SSL *.
TCN_IMPLEMENT_CALL(jstring,SSL,getCipherForSSL)1236 TCN_IMPLEMENT_CALL(jstring, SSL, getCipherForSSL)(TCN_STDARGS,
1237                                                   jlong ssl /* SSL * */)
1238 {
1239     SSL *ssl_ = J2P(ssl, SSL *);
1240 
1241     if (ssl_ == NULL) {
1242         tcn_ThrowException(e, "ssl is null");
1243         return NULL;
1244     }
1245 
1246     UNREFERENCED_STDARGS;
1247 
1248     return AJP_TO_JSTRING(SSL_get_cipher(ssl_));
1249 }
1250 
1251 // Read which protocol was negotiated for the given SSL *.
TCN_IMPLEMENT_CALL(jstring,SSL,getVersion)1252 TCN_IMPLEMENT_CALL(jstring, SSL, getVersion)(TCN_STDARGS,
1253                                                   jlong ssl /* SSL * */)
1254 {
1255     SSL *ssl_ = J2P(ssl, SSL *);
1256 
1257     if (ssl_ == NULL) {
1258         tcn_ThrowException(e, "ssl is null");
1259         return NULL;
1260     }
1261 
1262     UNREFERENCED_STDARGS;
1263 
1264     return AJP_TO_JSTRING(SSL_get_version(ssl_));
1265 }
1266 
1267 // Is the handshake over yet?
TCN_IMPLEMENT_CALL(jint,SSL,isInInit)1268 TCN_IMPLEMENT_CALL(jint, SSL, isInInit)(TCN_STDARGS,
1269                                         jlong ssl /* SSL * */) {
1270     SSL *ssl_ = J2P(ssl, SSL *);
1271 
1272     if (ssl_ == NULL) {
1273         tcn_ThrowException(e, "ssl is null");
1274         return 0;
1275     }
1276 
1277     UNREFERENCED(o);
1278 
1279     return SSL_in_init(ssl_);
1280 }
1281 
TCN_IMPLEMENT_CALL(jint,SSL,doHandshake)1282 TCN_IMPLEMENT_CALL(jint, SSL, doHandshake)(TCN_STDARGS,
1283                                            jlong ssl /* SSL * */) {
1284     SSL *ssl_ = J2P(ssl, SSL *);
1285 
1286     if (ssl_ == NULL) {
1287         tcn_ThrowException(e, "ssl is null");
1288         return 0;
1289     }
1290 
1291     UNREFERENCED(o);
1292 
1293     return SSL_do_handshake(ssl_);
1294 }
1295 
1296 // Read which protocol was negotiated for the given SSL *.
TCN_IMPLEMENT_CALL(jstring,SSL,getNextProtoNegotiated)1297 TCN_IMPLEMENT_CALL(jstring, SSL, getNextProtoNegotiated)(TCN_STDARGS,
1298                                                          jlong ssl /* SSL * */) {
1299     SSL *ssl_ = J2P(ssl, SSL *);
1300     const unsigned char *proto;
1301     unsigned int proto_len;
1302 
1303     if (ssl_ == NULL) {
1304         tcn_ThrowException(e, "ssl is null");
1305         return NULL;
1306     }
1307 
1308     UNREFERENCED(o);
1309 
1310     SSL_get0_next_proto_negotiated(ssl_, &proto, &proto_len);
1311     return tcn_new_stringn(e, (char*) proto, proto_len);
1312 }
1313 
1314 /*** End Twitter API Additions ***/
1315 
1316 /*** Apple API Additions ***/
1317 
TCN_IMPLEMENT_CALL(jstring,SSL,getAlpnSelected)1318 TCN_IMPLEMENT_CALL(jstring, SSL, getAlpnSelected)(TCN_STDARGS,
1319                                                          jlong ssl /* SSL * */) {
1320     // Use weak linking with GCC as this will alow us to run the same packaged version with multiple
1321     // version of openssl.
1322     #if defined(__GNUC__) || defined(__GNUG__)
1323         if (!SSL_get0_alpn_selected) {
1324             UNREFERENCED(o);
1325             UNREFERENCED(ssl);
1326             return NULL;
1327         }
1328     #endif
1329 
1330     // We can only support it when either use openssl version >= 1.0.2 or GCC as this way we can use weak linking
1331     #if OPENSSL_VERSION_NUMBER >= 0x10002000L || defined(__GNUC__) || defined(__GNUG__)
1332         SSL *ssl_ = J2P(ssl, SSL *);
1333         const unsigned char *proto;
1334         unsigned int proto_len;
1335 
1336         if (ssl_ == NULL) {
1337             tcn_ThrowException(e, "ssl is null");
1338             return NULL;
1339         }
1340 
1341         UNREFERENCED(o);
1342 
1343         SSL_get0_alpn_selected(ssl_, &proto, &proto_len);
1344         return tcn_new_stringn(e, (char*) proto, proto_len);
1345     #else
1346         UNREFERENCED(o);
1347         UNREFERENCED(ssl);
1348         return NULL;
1349     #endif
1350 }
1351 
TCN_IMPLEMENT_CALL(jobjectArray,SSL,getPeerCertChain)1352 TCN_IMPLEMENT_CALL(jobjectArray, SSL, getPeerCertChain)(TCN_STDARGS,
1353                                                   jlong ssl /* SSL * */)
1354 {
1355     STACK_OF(X509) *sk;
1356     int len;
1357     int i;
1358     X509 *cert;
1359     int length;
1360     unsigned char *buf;
1361     jobjectArray array;
1362     jbyteArray bArray;
1363     jclass byteArrayClass = tcn_get_byte_array_class();
1364 
1365     SSL *ssl_ = J2P(ssl, SSL *);
1366 
1367     if (ssl_ == NULL) {
1368         tcn_ThrowException(e, "ssl is null");
1369         return NULL;
1370     }
1371 
1372     UNREFERENCED(o);
1373 
1374     // Get a stack of all certs in the chain.
1375     sk = SSL_get_peer_cert_chain(ssl_);
1376 
1377     len = sk_X509_num(sk);
1378     if (len <= 0) {
1379         // No peer certificate chain as no auth took place yet, or the auth was not successful.
1380         return NULL;
1381     }
1382     // Create the byte[][] array that holds all the certs
1383     array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL);
1384 
1385     for(i = 0; i < len; i++) {
1386         cert = sk_X509_value(sk, i);
1387 
1388         buf = NULL;
1389         length = i2d_X509(cert, &buf);
1390         if (length < 0) {
1391             if (buf != NULL) {
1392                 OPENSSL_free(buf);
1393             }
1394             // In case of error just return an empty byte[][]
1395             return (*e)->NewObjectArray(e, 0, byteArrayClass, NULL);
1396         }
1397         bArray = (*e)->NewByteArray(e, length);
1398         (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf);
1399         (*e)->SetObjectArrayElement(e, array, i, bArray);
1400 
1401         // Delete the local reference as we not know how long the chain is and local references are otherwise
1402         // only freed once jni method returns.
1403         (*e)->DeleteLocalRef(e, bArray);
1404 
1405         OPENSSL_free(buf);
1406     }
1407     return array;
1408 }
1409 
TCN_IMPLEMENT_CALL(jbyteArray,SSL,getPeerCertificate)1410 TCN_IMPLEMENT_CALL(jbyteArray, SSL, getPeerCertificate)(TCN_STDARGS,
1411                                                   jlong ssl /* SSL * */)
1412 {
1413     X509 *cert;
1414     int length;
1415     unsigned char *buf = NULL;
1416     jbyteArray bArray;
1417 
1418     SSL *ssl_ = J2P(ssl, SSL *);
1419 
1420     if (ssl_ == NULL) {
1421         tcn_ThrowException(e, "ssl is null");
1422         return NULL;
1423     }
1424 
1425     UNREFERENCED(o);
1426 
1427     // Get a stack of all certs in the chain
1428     cert = SSL_get_peer_certificate(ssl_);
1429     if (cert == NULL) {
1430         return NULL;
1431     }
1432 
1433     length = i2d_X509(cert, &buf);
1434 
1435     bArray = (*e)->NewByteArray(e, length);
1436     (*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf);
1437 
1438     // We need to free the cert as the reference count is incremented by one and it is not destroyed when the
1439     // session is freed.
1440     // See https://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html
1441     X509_free(cert);
1442 
1443     OPENSSL_free(buf);
1444 
1445     return bArray;
1446 }
1447 
TCN_IMPLEMENT_CALL(jstring,SSL,getErrorString)1448 TCN_IMPLEMENT_CALL(jstring, SSL, getErrorString)(TCN_STDARGS, jlong number)
1449 {
1450     char buf[ERR_LEN];
1451     UNREFERENCED(o);
1452     ERR_error_string(number, buf);
1453     return tcn_new_string(e, buf);
1454 }
1455 
TCN_IMPLEMENT_CALL(jlong,SSL,getTime)1456 TCN_IMPLEMENT_CALL(jlong, SSL, getTime)(TCN_STDARGS, jlong ssl)
1457 {
1458     SSL *ssl_ = J2P(ssl, SSL *);
1459     SSL_SESSION *session = NULL;
1460 
1461     if (ssl_ == NULL) {
1462         tcn_ThrowException(e, "ssl is null");
1463         return 0;
1464     }
1465 
1466     session = SSL_get_session(ssl_);
1467     if (session == NULL) {
1468         // BoringSSL does not protect against a NULL session. OpenSSL
1469         // returns 0 if the session is NULL, so do that here.
1470         return 0;
1471     }
1472 
1473     UNREFERENCED(o);
1474 
1475     return SSL_get_time(session);
1476 }
1477 
1478 
TCN_IMPLEMENT_CALL(jlong,SSL,getTimeout)1479 TCN_IMPLEMENT_CALL(jlong, SSL, getTimeout)(TCN_STDARGS, jlong ssl)
1480 {
1481     SSL *ssl_ = J2P(ssl, SSL *);
1482     SSL_SESSION *session = NULL;
1483 
1484     if (ssl_ == NULL) {
1485         tcn_ThrowException(e, "ssl is null");
1486         return 0;
1487     }
1488 
1489     session = SSL_get_session(ssl_);
1490     if (session == NULL) {
1491         // BoringSSL does not protect against a NULL session. OpenSSL
1492         // returns 0 if the session is NULL, so do that here.
1493         return 0;
1494     }
1495 
1496     UNREFERENCED(o);
1497 
1498     return SSL_get_timeout(session);
1499 }
1500 
1501 
TCN_IMPLEMENT_CALL(jlong,SSL,setTimeout)1502 TCN_IMPLEMENT_CALL(jlong, SSL, setTimeout)(TCN_STDARGS, jlong ssl, jlong seconds)
1503 {
1504     SSL *ssl_ = J2P(ssl, SSL *);
1505     SSL_SESSION *session = NULL;
1506 
1507     if (ssl_ == NULL) {
1508         tcn_ThrowException(e, "ssl is null");
1509         return 0;
1510     }
1511 
1512     session = SSL_get_session(ssl_);
1513     if (session == NULL) {
1514         // BoringSSL does not protect against a NULL session. OpenSSL
1515         // returns 0 if the session is NULL, so do that here.
1516         return 0;
1517     }
1518 
1519     UNREFERENCED(o);
1520 
1521     return SSL_set_timeout(session, seconds);
1522 }
1523 
1524 
TCN_IMPLEMENT_CALL(void,SSL,setVerify)1525 TCN_IMPLEMENT_CALL(void, SSL, setVerify)(TCN_STDARGS, jlong ssl, jint level, jint depth)
1526 {
1527     tcn_ssl_verify_config_t* verify_config;
1528     tcn_ssl_ctxt_t* c;
1529     SSL *ssl_ = J2P(ssl, SSL *);
1530 
1531     if (ssl_ == NULL) {
1532         tcn_ThrowException(e, "ssl is null");
1533         return;
1534     }
1535 
1536     c = SSL_get_app_data2(ssl_);
1537     verify_config = SSL_get_app_data4(ssl_);
1538 
1539     UNREFERENCED(o);
1540     TCN_ASSERT(c != NULL);
1541     TCN_ASSERT(verify_config != NULL);
1542 
1543     // If we are sharing the configuration from the SSLContext we now need to create a new configuration just for this SSL.
1544     if (verify_config == &c->verify_config) {
1545        verify_config = (tcn_ssl_verify_config_t*) OPENSSL_malloc(sizeof(tcn_ssl_verify_config_t));
1546        if (verify_config == NULL) {
1547            tcn_ThrowException(e, "failed to allocate tcn_ssl_verify_config_t");
1548            return;
1549        }
1550        // Copy the verify depth form the context in case depth is <0.
1551        verify_config->verify_depth = c->verify_config.verify_depth;
1552        SSL_set_app_data4(ssl_, verify_config);
1553     }
1554 
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), NULL);
1557     SSL_set_verify_depth(ssl_, verify_config->verify_depth);
1558 }
1559 
TCN_IMPLEMENT_CALL(void,SSL,setOptions)1560 TCN_IMPLEMENT_CALL(void, SSL, setOptions)(TCN_STDARGS, jlong ssl,
1561                                                  jint opt)
1562 {
1563     SSL *ssl_ = J2P(ssl, SSL *);
1564 
1565     if (ssl_ == NULL) {
1566         tcn_ThrowException(e, "ssl is null");
1567         return;
1568     }
1569 
1570     UNREFERENCED_STDARGS;
1571 
1572     SSL_set_options(ssl_, opt);
1573 }
1574 
TCN_IMPLEMENT_CALL(void,SSL,clearOptions)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;
1583     }
1584 
1585     UNREFERENCED_STDARGS;
1586 
1587     SSL_clear_options(ssl_, opt);
1588 }
1589 
TCN_IMPLEMENT_CALL(jint,SSL,getOptions)1590 TCN_IMPLEMENT_CALL(jint, SSL, getOptions)(TCN_STDARGS, jlong ssl)
1591 {
1592     SSL *ssl_ = J2P(ssl, SSL *);
1593 
1594     if (ssl_ == NULL) {
1595         tcn_ThrowException(e, "ssl is null");
1596         return 0;
1597     }
1598 
1599     UNREFERENCED_STDARGS;
1600 
1601     return SSL_get_options(ssl_);
1602 }
1603 
TCN_IMPLEMENT_CALL(jobjectArray,SSL,getCiphers)1604 TCN_IMPLEMENT_CALL(jobjectArray, SSL, getCiphers)(TCN_STDARGS, jlong ssl)
1605 {
1606     STACK_OF(SSL_CIPHER) *sk;
1607     int len;
1608     jobjectArray array;
1609     const SSL_CIPHER *cipher;
1610     const char *name;
1611     int i;
1612     jstring c_name;
1613     SSL *ssl_ = J2P(ssl, SSL *);
1614 
1615     if (ssl_ == NULL) {
1616         tcn_ThrowException(e, "ssl is null");
1617         return NULL;
1618     }
1619 
1620     UNREFERENCED_STDARGS;
1621 
1622     sk = SSL_get_ciphers(ssl_);
1623     len = sk_SSL_CIPHER_num(sk);
1624 
1625     if (len <= 0) {
1626         // No peer certificate chain as no auth took place yet, or the auth was not successful.
1627         return NULL;
1628     }
1629 
1630     // Create the byte[][] array that holds all the certs
1631     array = (*e)->NewObjectArray(e, len, tcn_get_string_class(), NULL);
1632 
1633     for (i = 0; i < len; i++) {
1634         cipher = sk_SSL_CIPHER_value(sk, i);
1635         name = SSL_CIPHER_get_name(cipher);
1636 
1637         c_name = (*e)->NewStringUTF(e, name);
1638         (*e)->SetObjectArrayElement(e, array, i, c_name);
1639     }
1640     return array;
1641 }
1642 
TCN_IMPLEMENT_CALL(jboolean,SSL,setCipherSuites)1643 TCN_IMPLEMENT_CALL(jboolean, SSL, setCipherSuites)(TCN_STDARGS, jlong ssl,
1644                                                          jstring ciphers)
1645 {
1646     jboolean rv = JNI_TRUE;
1647     TCN_ALLOC_CSTRING(ciphers);
1648     SSL *ssl_ = J2P(ssl, SSL *);
1649 
1650     if (ssl_ == NULL) {
1651         tcn_ThrowException(e, "ssl is null");
1652         return JNI_FALSE;
1653     }
1654 
1655     UNREFERENCED(o);
1656 
1657     if (!J2S(ciphers)) {
1658         return JNI_FALSE;
1659     }
1660 
1661     if (!SSL_set_cipher_list(ssl_, J2S(ciphers))) {
1662         char err[ERR_LEN];
1663         ERR_error_string(ERR_get_error(), err);
1664         tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err);
1665         rv = JNI_FALSE;
1666     }
1667 
1668     TCN_FREE_CSTRING(ciphers);
1669     return rv;
1670 }
1671 
TCN_IMPLEMENT_CALL(jbyteArray,SSL,getSessionId)1672 TCN_IMPLEMENT_CALL(jbyteArray, SSL, getSessionId)(TCN_STDARGS, jlong ssl)
1673 {
1674 
1675     unsigned int len;
1676     const unsigned char *session_id;
1677     SSL_SESSION *session;
1678     jbyteArray bArray;
1679     SSL *ssl_ = J2P(ssl, SSL *);
1680 
1681     if (ssl_ == NULL) {
1682         tcn_ThrowException(e, "ssl is null");
1683         return NULL;
1684     }
1685 
1686     UNREFERENCED(o);
1687 
1688     session = SSL_get_session(ssl_);
1689     if (session == NULL) {
1690         return NULL;
1691     }
1692 
1693     session_id = SSL_SESSION_get_id(session, &len);
1694     if (len == 0 || session_id == NULL) {
1695         return NULL;
1696     }
1697 
1698     bArray = (*e)->NewByteArray(e, len);
1699     (*e)->SetByteArrayRegion(e, bArray, 0, len, (jbyte*) session_id);
1700     return bArray;
1701 }
1702 
TCN_IMPLEMENT_CALL(jint,SSL,getHandshakeCount)1703 TCN_IMPLEMENT_CALL(jint, SSL, getHandshakeCount)(TCN_STDARGS, jlong ssl)
1704 {
1705     int *handshakeCount = NULL;
1706     SSL *ssl_ = J2P(ssl, SSL *);
1707 
1708     if (ssl_ == NULL) {
1709         tcn_ThrowException(e, "ssl is null");
1710         return -1;
1711     }
1712 
1713     UNREFERENCED(o);
1714 
1715     handshakeCount = SSL_get_app_data3(ssl_);
1716     return handshakeCount != NULL ? *handshakeCount : 0;
1717 }
1718 
1719 
TCN_IMPLEMENT_CALL(void,SSL,clearError)1720 TCN_IMPLEMENT_CALL(void, SSL, clearError)(TCN_STDARGS)
1721 {
1722     UNREFERENCED(o);
1723     ERR_clear_error();
1724 }
1725 
TCN_IMPLEMENT_CALL(jint,SSL,renegotiate)1726 TCN_IMPLEMENT_CALL(jint, SSL, renegotiate)(TCN_STDARGS,
1727                                            jlong ssl /* SSL * */) {
1728     SSL *ssl_ = J2P(ssl, SSL *);
1729 
1730     if (ssl_ == NULL) {
1731         tcn_ThrowException(e, "ssl is null");
1732         return 0;
1733     }
1734 
1735     UNREFERENCED(o);
1736 
1737     return SSL_renegotiate(ssl_);
1738 }
1739 
TCN_IMPLEMENT_CALL(void,SSL,setState)1740 TCN_IMPLEMENT_CALL(void, SSL, setState)(TCN_STDARGS,
1741                                            jlong ssl, /* SSL * */
1742                                            jint state) {
1743     SSL *ssl_ = J2P(ssl, SSL *);
1744 
1745     if (ssl_ == NULL) {
1746         tcn_ThrowException(e, "ssl is null");
1747         return;
1748     }
1749 
1750     UNREFERENCED(o);
1751 
1752     SSL_set_state(ssl_, state);
1753 }
1754 
TCN_IMPLEMENT_CALL(void,SSL,setTlsExtHostName)1755 TCN_IMPLEMENT_CALL(void, SSL, setTlsExtHostName)(TCN_STDARGS, jlong ssl, jstring hostname) {
1756     TCN_ALLOC_CSTRING(hostname);
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 
TCN_IMPLEMENT_CALL(void,SSL,setHostNameValidation)1774 TCN_IMPLEMENT_CALL(void, SSL, setHostNameValidation)(TCN_STDARGS, jlong sslAddress, 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)->GetStringUTFChars(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         }
1789 #else
1790         if (hostname != NULL && hostname[0] != '\0') {
1791             tcn_ThrowException(e, "hostname verification requires OpenSSL 1.0.2+");
1792         }
1793 #endif
1794         (*e)->ReleaseStringUTFChars(e, hostnameString, hostname);
1795     }
1796 }
1797 
TCN_IMPLEMENT_CALL(jobjectArray,SSL,authenticationMethods)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 
TCN_IMPLEMENT_CALL(void,SSL,setCertificateBio)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 
TCN_IMPLEMENT_CALL(void,SSL,setCertificateChainBio)1884 TCN_IMPLEMENT_CALL(void, SSL, setCertificateChainBio)(TCN_STDARGS, jlong ssl,
1885                                                                   jlong chain,
1886                                                                   jboolean skipfirst)
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 
TCN_IMPLEMENT_CALL(long,SSL,parsePrivateKey)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 
TCN_IMPLEMENT_CALL(void,SSL,freePrivateKey)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 
TCN_IMPLEMENT_CALL(long,SSL,parseX509Chain)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);
1980     return 0;
1981 }
1982 
TCN_IMPLEMENT_CALL(void,SSL,freeX509Chain)1983 TCN_IMPLEMENT_CALL(void, SSL, freeX509Chain)(TCN_STDARGS, jlong x509Chain)
1984 {
1985     STACK_OF(X509) *chain = J2P(x509Chain, STACK_OF(X509) *);
1986     UNREFERENCED(o);
1987     sk_X509_pop_free(chain, X509_free);
1988 }
1989 
1990