OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / main / native / NativeCrypto.cpp
1 /*
2  * Copyright (C) 2007-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * Native glue for Java class org.apache.harmony.xnet.provider.jsse.NativeCrypto
19  */
20
21 #define LOG_TAG "NativeCrypto"
22
23 #include <fcntl.h>
24 #include <sys/socket.h>
25 #include <unistd.h>
26
27 #include <jni.h>
28
29 #include <openssl/dsa.h>
30 #include <openssl/err.h>
31 #include <openssl/evp.h>
32 #include <openssl/rand.h>
33 #include <openssl/rsa.h>
34 #include <openssl/ssl.h>
35
36 #include "AsynchronousSocketCloseMonitor.h"
37 #include "JNIHelp.h"
38 #include "JniConstants.h"
39 #include "JniException.h"
40 #include "LocalArray.h"
41 #include "NetFd.h"
42 #include "NetworkUtilities.h"
43 #include "ScopedLocalRef.h"
44 #include "ScopedPrimitiveArray.h"
45 #include "ScopedUtfChars.h"
46 #include "UniquePtr.h"
47
48 #undef WITH_JNI_TRACE
49 #ifdef WITH_JNI_TRACE
50 #define JNI_TRACE(...) \
51         ((void)LOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__));     \
52 /*
53         ((void)printf("I/" LOG_TAG "-jni:"));         \
54         ((void)printf(__VA_ARGS__));          \
55         ((void)printf("\n"))
56 */
57 #else
58 #define JNI_TRACE(...) ((void)0)
59 #endif
60
61 struct BIO_Delete {
62     void operator()(BIO* p) const {
63         BIO_free(p);
64     }
65 };
66 typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
67
68 struct BIGNUM_Delete {
69     void operator()(BIGNUM* p) const {
70         BN_free(p);
71     }
72 };
73 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
74
75 struct DH_Delete {
76     void operator()(DH* p) const {
77         DH_free(p);
78     }
79 };
80 typedef UniquePtr<DH, DH_Delete> Unique_DH;
81
82 struct DSA_Delete {
83     void operator()(DSA* p) const {
84         DSA_free(p);
85     }
86 };
87 typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
88
89 struct EVP_PKEY_Delete {
90     void operator()(EVP_PKEY* p) const {
91         EVP_PKEY_free(p);
92     }
93 };
94 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
95
96 struct PKCS8_PRIV_KEY_INFO_Delete {
97     void operator()(PKCS8_PRIV_KEY_INFO* p) const {
98         PKCS8_PRIV_KEY_INFO_free(p);
99     }
100 };
101 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
102
103 struct RSA_Delete {
104     void operator()(RSA* p) const {
105         RSA_free(p);
106     }
107 };
108 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
109
110 struct SSL_Delete {
111     void operator()(SSL* p) const {
112         SSL_free(p);
113     }
114 };
115 typedef UniquePtr<SSL, SSL_Delete> Unique_SSL;
116
117 struct SSL_CTX_Delete {
118     void operator()(SSL_CTX* p) const {
119         SSL_CTX_free(p);
120     }
121 };
122 typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX;
123
124 struct X509_Delete {
125     void operator()(X509* p) const {
126         X509_free(p);
127     }
128 };
129 typedef UniquePtr<X509, X509_Delete> Unique_X509;
130
131 struct X509_NAME_Delete {
132     void operator()(X509_NAME* p) const {
133         X509_NAME_free(p);
134     }
135 };
136 typedef UniquePtr<X509_NAME, X509_NAME_Delete> Unique_X509_NAME;
137
138 struct sk_SSL_CIPHER_Delete {
139     void operator()(STACK_OF(SSL_CIPHER)* p) const {
140         sk_SSL_CIPHER_free(p);
141     }
142 };
143 typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER;
144
145 struct sk_X509_Delete {
146     void operator()(STACK_OF(X509)* p) const {
147         sk_X509_free(p);
148     }
149 };
150 typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509;
151
152 struct sk_X509_NAME_Delete {
153     void operator()(STACK_OF(X509_NAME)* p) const {
154         sk_X509_NAME_free(p);
155     }
156 };
157 typedef UniquePtr<STACK_OF(X509_NAME), sk_X509_NAME_Delete> Unique_sk_X509_NAME;
158
159 /**
160  * Frees the SSL error state.
161  *
162  * OpenSSL keeps an "error stack" per thread, and given that this code
163  * can be called from arbitrary threads that we don't keep track of,
164  * we err on the side of freeing the error state promptly (instead of,
165  * say, at thread death).
166  */
167 static void freeSslErrorState(void) {
168     ERR_clear_error();
169     ERR_remove_state(0);
170 }
171
172 /*
173  * Checks this thread's OpenSSL error queue and throws a RuntimeException if
174  * necessary.
175  *
176  * @return 1 if an exception was thrown, 0 if not.
177  */
178 static int throwExceptionIfNecessary(JNIEnv* env, const char* location  __attribute__ ((unused))) {
179     int error = ERR_get_error();
180     int result = 0;
181
182     if (error != 0) {
183         char message[256];
184         ERR_error_string_n(error, message, sizeof(message));
185         JNI_TRACE("OpenSSL error in %s %d: %s", location, error, message);
186         jniThrowRuntimeException(env, message);
187         result = 1;
188     }
189
190     freeSslErrorState();
191     return result;
192 }
193
194 /**
195  * Throws an SocketTimeoutException with the given string as a message.
196  */
197 static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
198     JNI_TRACE("throwSocketTimeoutException %s", message);
199     jniThrowException(env, "java/net/SocketTimeoutException", message);
200 }
201
202 /**
203  * Throws a javax.net.ssl.SSLException with the given string as a message.
204  */
205 static void throwSSLExceptionStr(JNIEnv* env, const char* message) {
206     JNI_TRACE("throwSSLExceptionStr %s", message);
207     jniThrowException(env, "javax/net/ssl/SSLException", message);
208 }
209
210 /**
211  * Throws a javax.net.ssl.SSLProcotolException with the given string as a message.
212  */
213 static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) {
214     JNI_TRACE("throwSSLProtocolExceptionStr %s", message);
215     jniThrowException(env, "javax/net/ssl/SSLProtocolException", message);
216 }
217
218 /**
219  * Throws an SSLException with a message constructed from the current
220  * SSL errors. This will also log the errors.
221  *
222  * @param env the JNI environment
223  * @param ssl the possibly NULL SSL
224  * @param sslErrorCode error code returned from SSL_get_error() or
225  * SSL_ERROR_NONE to probe with ERR_get_error
226  * @param message null-ok; general error message
227  */
228 static void throwSSLExceptionWithSslErrors(
229         JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message) {
230
231     if (message == NULL) {
232         message = "SSL error";
233     }
234
235     // First consult the SSL error code for the general message.
236     const char* sslErrorStr = NULL;
237     switch (sslErrorCode) {
238         case SSL_ERROR_NONE:
239             if (ERR_peek_error() == 0) {
240                 sslErrorStr = "OK";
241             } else {
242                 sslErrorStr = "";
243             }
244             break;
245         case SSL_ERROR_SSL:
246             sslErrorStr = "Failure in SSL library, usually a protocol error";
247             break;
248         case SSL_ERROR_WANT_READ:
249             sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this.";
250             break;
251         case SSL_ERROR_WANT_WRITE:
252             sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this.";
253             break;
254         case SSL_ERROR_WANT_X509_LOOKUP:
255             sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this.";
256             break;
257         case SSL_ERROR_SYSCALL:
258             sslErrorStr = "I/O error during system call";
259             break;
260         case SSL_ERROR_ZERO_RETURN:
261             sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this.";
262             break;
263         case SSL_ERROR_WANT_CONNECT:
264             sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this.";
265             break;
266         case SSL_ERROR_WANT_ACCEPT:
267             sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this.";
268             break;
269         default:
270             sslErrorStr = "Unknown SSL error";
271     }
272
273     // Prepend either our explicit message or a default one.
274     char* str;
275     if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) {
276         // problem with asprintf, just throw argument message, log everything
277         throwSSLExceptionStr(env, message);
278         LOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr);
279         freeSslErrorState();
280         return;
281     }
282
283     char* allocStr = str;
284
285     // For protocol errors, SSL might have more information.
286     if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) {
287         // Append each error as an additional line to the message.
288         for (;;) {
289             char errStr[256];
290             const char* file;
291             int line;
292             const char* data;
293             int flags;
294             unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags);
295             if (err == 0) {
296                 break;
297             }
298
299             ERR_error_string_n(err, errStr, sizeof(errStr));
300
301             int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
302                                (allocStr == NULL) ? "" : allocStr,
303                                errStr,
304                                file,
305                                line,
306                                (flags & ERR_TXT_STRING) ? data : "(no data)",
307                                flags);
308
309             if (ret < 0) {
310                 break;
311             }
312
313             free(allocStr);
314             allocStr = str;
315         }
316     // For errors during system calls, errno might be our friend.
317     } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
318         if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
319             free(allocStr);
320             allocStr = str;
321         }
322     // If the error code is invalid, print it.
323     } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
324         if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
325             free(allocStr);
326             allocStr = str;
327         }
328     }
329
330     if (sslErrorCode == SSL_ERROR_SSL) {
331         throwSSLProtocolExceptionStr(env, allocStr);
332     } else {
333         throwSSLExceptionStr(env, allocStr);
334     }
335
336     LOGV("%s", allocStr);
337     free(allocStr);
338     freeSslErrorState();
339 }
340
341 /**
342  * Helper function that grabs the casts an ssl pointer and then checks for nullness.
343  * If this function returns NULL and <code>throwIfNull</code> is
344  * passed as <code>true</code>, then this function will call
345  * <code>throwSSLExceptionStr</code> before returning, so in this case of
346  * NULL, a caller of this function should simply return and allow JNI
347  * to do its thing.
348  *
349  * @param env the JNI environment
350  * @param ssl_address; the ssl_address pointer as an integer
351  * @param throwIfNull whether to throw if the SSL pointer is NULL
352  * @returns the pointer, which may be NULL
353  */
354 static SSL_CTX* to_SSL_CTX(JNIEnv* env, int ssl_ctx_address, bool throwIfNull) {
355     SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
356     if ((ssl_ctx == NULL) && throwIfNull) {
357         JNI_TRACE("ssl_ctx == null");
358         jniThrowNullPointerException(env, "ssl_ctx == null");
359     }
360     return ssl_ctx;
361 }
362
363 static SSL* to_SSL(JNIEnv* env, int ssl_address, bool throwIfNull) {
364     SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
365     if ((ssl == NULL) && throwIfNull) {
366         JNI_TRACE("ssl == null");
367         jniThrowNullPointerException(env, "ssl == null");
368     }
369     return ssl;
370 }
371
372 static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, int ssl_session_address, bool throwIfNull) {
373     SSL_SESSION* ssl_session
374         = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
375     if ((ssl_session == NULL) && throwIfNull) {
376         JNI_TRACE("ssl_session == null");
377         jniThrowNullPointerException(env, "ssl_session == null");
378     }
379     return ssl_session;
380 }
381
382 /**
383  * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
384  * fly.
385  */
386 static BIGNUM* arrayToBignum(JNIEnv* env, jbyteArray source) {
387     JNI_TRACE("arrayToBignum(%p)", source);
388
389     ScopedByteArrayRO sourceBytes(env, source);
390     if (sourceBytes.get() == NULL) {
391         JNI_TRACE("arrayToBignum(%p) => NULL", source);
392         return NULL;
393     }
394     BIGNUM* bn = BN_bin2bn(reinterpret_cast<const unsigned char*>(sourceBytes.get()),
395                            sourceBytes.size(),
396                            NULL);
397     JNI_TRACE("arrayToBignum(%p) => %p", source, bn);
398     return bn;
399 }
400
401 /**
402  * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
403  * suppose there are not many other ways to do this on a Linux system (modulo
404  * isomorphism).
405  */
406 #define MUTEX_TYPE pthread_mutex_t
407 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
408 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
409 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
410 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
411 #define THREAD_ID pthread_self()
412 #define THROW_EXCEPTION (-2)
413 #define THROW_SOCKETTIMEOUTEXCEPTION (-3)
414 #define THROWN_SOCKETEXCEPTION (-4)
415
416 static MUTEX_TYPE* mutex_buf = NULL;
417
418 static void locking_function(int mode, int n, const char*, int) {
419     if (mode & CRYPTO_LOCK) {
420         MUTEX_LOCK(mutex_buf[n]);
421     } else {
422         MUTEX_UNLOCK(mutex_buf[n]);
423     }
424 }
425
426 static unsigned long id_function(void) {
427     return ((unsigned long)THREAD_ID);
428 }
429
430 int THREAD_setup(void) {
431     mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
432     if (!mutex_buf) {
433         return 0;
434     }
435
436     for (int i = 0; i < CRYPTO_num_locks(); ++i) {
437         MUTEX_SETUP(mutex_buf[i]);
438     }
439
440     CRYPTO_set_id_callback(id_function);
441     CRYPTO_set_locking_callback(locking_function);
442
443     return 1;
444 }
445
446 int THREAD_cleanup(void) {
447     if (!mutex_buf) {
448         return 0;
449     }
450
451     CRYPTO_set_id_callback(NULL);
452     CRYPTO_set_locking_callback(NULL);
453
454     for (int i = 0; i < CRYPTO_num_locks( ); i++) {
455         MUTEX_CLEANUP(mutex_buf[i]);
456     }
457
458     free(mutex_buf);
459     mutex_buf = NULL;
460
461     return 1;
462 }
463
464 /**
465  * Initialization phase for every OpenSSL job: Loads the Error strings, the
466  * crypto algorithms and reset the OpenSSL library
467  */
468 static void NativeCrypto_clinit(JNIEnv*, jclass)
469 {
470     SSL_load_error_strings();
471     ERR_load_crypto_strings();
472     SSL_library_init();
473     OpenSSL_add_all_algorithms();
474     THREAD_setup();
475 }
476
477 /**
478  * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
479  *                                           byte[] pub_key, byte[] priv_key);
480  */
481 static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
482                                                jbyteArray p, jbyteArray q, jbyteArray g,
483                                                jbyteArray pub_key, jbyteArray priv_key) {
484     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
485               p, q, g, pub_key, priv_key);
486
487     Unique_DSA dsa(DSA_new());
488     if (dsa.get() == NULL) {
489         jniThrowRuntimeException(env, "DSA_new failed");
490         return NULL;
491     }
492
493     dsa->p = arrayToBignum(env, p);
494     dsa->q = arrayToBignum(env, q);
495     dsa->g = arrayToBignum(env, g);
496     dsa->pub_key = arrayToBignum(env, pub_key);
497
498     if (priv_key != NULL) {
499         dsa->priv_key = arrayToBignum(env, priv_key);
500     }
501
502     if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) {
503         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
504         return NULL;
505     }
506
507     Unique_EVP_PKEY pkey(EVP_PKEY_new());
508     if (pkey.get() == NULL) {
509         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
510         return NULL;
511     }
512     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
513         jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
514         return NULL;
515     }
516     dsa.release();
517     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
518               p, q, g, pub_key, priv_key, pkey.get());
519     return pkey.release();
520 }
521
522 /**
523  * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
524  */
525 static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
526                                                jbyteArray n, jbyteArray e, jbyteArray d,
527                                                jbyteArray p, jbyteArray q) {
528     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p)", n, e, d, p, q);
529
530     Unique_RSA rsa(RSA_new());
531     if (rsa.get() == NULL) {
532         jniThrowRuntimeException(env, "RSA_new failed");
533         return NULL;
534     }
535
536     rsa->n = arrayToBignum(env, n);
537     rsa->e = arrayToBignum(env, e);
538
539     if (d != NULL) {
540         rsa->d = arrayToBignum(env, d);
541     }
542
543     if (p != NULL) {
544         rsa->p = arrayToBignum(env, p);
545     }
546
547     if (q != NULL) {
548         rsa->q = arrayToBignum(env, q);
549     }
550
551 #ifdef WITH_JNI_TRACE
552     if (p != NULL && q != NULL) {
553         int check = RSA_check_key(rsa.get());
554         JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check);
555     }
556 #endif
557
558     if (rsa->n == NULL || rsa->e == NULL) {
559         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
560         return NULL;
561     }
562
563     Unique_EVP_PKEY pkey(EVP_PKEY_new());
564     if (pkey.get() == NULL) {
565         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
566         return NULL;
567     }
568     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
569         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
570         return NULL;
571     }
572     rsa.release();
573     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p) => %p", n, e, d, p, q, pkey.get());
574     return pkey.release();
575 }
576
577 /**
578  * private static native void EVP_PKEY_free(int pkey);
579  */
580 static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, EVP_PKEY* pkey) {
581     JNI_TRACE("EVP_PKEY_free(%p)", pkey);
582
583     if (pkey != NULL) {
584         EVP_PKEY_free(pkey);
585     }
586 }
587
588 /*
589  * public static native int EVP_MD_CTX_create()
590  */
591 static jint NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
592     JNI_TRACE("NativeCrypto_EVP_MD_CTX_create");
593
594     EVP_MD_CTX* ctx = EVP_MD_CTX_create();
595     if (ctx == NULL) {
596         jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX");
597     }
598     JNI_TRACE("NativeCrypto_EVP_MD_CTX_create => %p", ctx);
599     return (jint) ctx;
600
601 }
602
603 /*
604  * public static native void EVP_MD_CTX_destroy(int)
605  */
606 static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, EVP_MD_CTX* ctx) {
607     JNI_TRACE("NativeCrypto_EVP_MD_CTX_destroy(%p)", ctx);
608
609     if (ctx != NULL) {
610         EVP_MD_CTX_destroy(ctx);
611     }
612 }
613
614 /*
615  * public static native int EVP_MD_CTX_copy(int)
616  */
617 static jint NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
618     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p)", ctx);
619
620     if (ctx == NULL) {
621         jniThrowNullPointerException(env, NULL);
622         return NULL;
623     }
624     EVP_MD_CTX* copy = EVP_MD_CTX_create();
625     if (copy == NULL) {
626         jniThrowOutOfMemoryError(env, "Unable to allocate copy of EVP_MD_CTX");
627         return NULL;
628     }
629     EVP_MD_CTX_init(copy);
630     int result = EVP_MD_CTX_copy_ex(copy, ctx);
631     if (result == 0) {
632         EVP_MD_CTX_destroy(copy);
633         jniThrowRuntimeException(env, "Unable to copy EVP_MD_CTX");
634         return NULL;
635     }
636     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p) => %p", ctx, copy);
637     return (jint) copy;
638 }
639
640 /*
641  * public static native int EVP_DigestFinal(int, byte[], int)
642  */
643 static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx,
644                                          jbyteArray hash, jint offset) {
645     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
646
647     if (ctx == NULL || hash == NULL) {
648         jniThrowNullPointerException(env, NULL);
649         return -1;
650     }
651
652     int result = -1;
653
654     ScopedByteArrayRW hashBytes(env, hash);
655     if (hashBytes.get() == NULL) {
656         return -1;
657     }
658     EVP_DigestFinal(ctx,
659                     reinterpret_cast<unsigned char*>(hashBytes.get() + offset),
660                     reinterpret_cast<unsigned int*>(&result));
661
662     throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal");
663
664     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, result);
665     return result;
666 }
667
668 /*
669  * public static native void EVP_DigestInit(int, java.lang.String)
670  */
671 static void NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jstring algorithm) {
672     JNI_TRACE("NativeCrypto_EVP_DigestInit(%p, %p)", ctx, algorithm);
673
674     if (ctx == NULL || algorithm == NULL) {
675         jniThrowNullPointerException(env, NULL);
676         return;
677     }
678
679     ScopedUtfChars algorithmChars(env, algorithm);
680     if (algorithmChars.c_str() == NULL) {
681         return;
682     }
683
684     JNI_TRACE("NativeCrypto_EVP_DigestInit(%p, %s)", ctx, algorithmChars.c_str());
685     const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
686
687     if (digest == NULL) {
688         jniThrowRuntimeException(env, "Hash algorithm not found");
689         return;
690     }
691
692     EVP_DigestInit(ctx, digest);
693
694     throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit");
695 }
696
697 /*
698  * public static native int EVP_MD_CTX_size(int)
699  */
700 static jint NativeCrypto_EVP_MD_CTX_size(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
701     JNI_TRACE("NativeCrypto_EVP_MD_CTX_size(%p)", ctx);
702
703     if (ctx == NULL) {
704         jniThrowNullPointerException(env, NULL);
705         return -1;
706     }
707
708     int result = EVP_MD_CTX_size(ctx);
709
710     throwExceptionIfNecessary(env, "NativeCrypto_EVP_MD_CTX_size");
711
712     JNI_TRACE("NativeCrypto_EVP_MD_CTX_size(%p) => %d", ctx, result);
713     return result;
714 }
715
716 /*
717  * public static int void EVP_MD_CTX_block_size(int)
718  */
719 static jint NativeCrypto_EVP_MD_CTX_block_size(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
720     JNI_TRACE("NativeCrypto_EVP_MD_CTX_block_size(%p)", ctx);
721
722     if (ctx == NULL) {
723         jniThrowNullPointerException(env, NULL);
724         return -1;
725     }
726
727     int result = EVP_MD_CTX_block_size(ctx);
728
729     throwExceptionIfNecessary(env, "NativeCrypto_EVP_MD_CTX_block_size");
730
731     JNI_TRACE("NativeCrypto_EVP_MD_CTX_block_size(%p) => %d", ctx, result);
732     return result;
733 }
734
735 /*
736  * public static native void EVP_DigestUpdate(int, byte[], int, int)
737  */
738 static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, EVP_MD_CTX* ctx,
739                                           jbyteArray buffer, jint offset, jint length) {
740     JNI_TRACE("NativeCrypto_EVP_DigestUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
741
742     if (offset < 0 || length < 0) {
743         jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
744         return;
745     }
746
747     if (ctx == NULL || buffer == NULL) {
748         jniThrowNullPointerException(env, NULL);
749         return;
750     }
751
752     ScopedByteArrayRO bufferBytes(env, buffer);
753     if (bufferBytes.get() == NULL) {
754         return;
755     }
756     EVP_DigestUpdate(ctx,
757                      reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
758                      length);
759
760     throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate");
761 }
762
763 /*
764  * public static native void EVP_VerifyInit(int, java.lang.String)
765  */
766 static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jstring algorithm) {
767     JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p, %p)", ctx, algorithm);
768
769     if (ctx == NULL || algorithm == NULL) {
770         jniThrowNullPointerException(env, NULL);
771         return;
772     }
773
774     ScopedUtfChars algorithmChars(env, algorithm);
775     if (algorithmChars.c_str() == NULL) {
776         return;
777     }
778
779     JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p, %s)", ctx, algorithmChars.c_str());
780     const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
781
782     if (digest == NULL) {
783         jniThrowRuntimeException(env, "Hash algorithm not found");
784         return;
785     }
786
787     EVP_VerifyInit(ctx, digest);
788
789     throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit");
790 }
791
792 /*
793  * public static native void EVP_VerifyUpdate(int, byte[], int, int)
794  */
795 static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, EVP_MD_CTX* ctx,
796                                           jbyteArray buffer, jint offset, jint length) {
797     JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
798
799     if (ctx == NULL || buffer == NULL) {
800         jniThrowNullPointerException(env, NULL);
801         return;
802     }
803
804     ScopedByteArrayRO bufferBytes(env, buffer);
805     if (bufferBytes.get() == NULL) {
806         return;
807     }
808     EVP_VerifyUpdate(ctx,
809                      reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
810                      length);
811
812     throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate");
813 }
814
815 /*
816  * public static native int EVP_VerifyFinal(int, byte[], int, int, int)
817  */
818 static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jbyteArray buffer,
819                                         jint offset, jint length, EVP_PKEY* pkey) {
820     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
821               ctx, buffer, offset, length, pkey);
822
823     if (ctx == NULL || buffer == NULL || pkey == NULL) {
824         jniThrowNullPointerException(env, NULL);
825         return -1;
826     }
827
828     ScopedByteArrayRO bufferBytes(env, buffer);
829     if (bufferBytes.get() == NULL) {
830         return -1;
831     }
832     int result = EVP_VerifyFinal(ctx,
833                                  reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
834                                  length,
835                                  pkey);
836
837     throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal");
838
839     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d",
840               ctx, buffer, offset, length, pkey, result);
841
842     return result;
843 }
844
845 /**
846  * Helper function that creates an RSA public key from two buffers containing
847  * the big-endian bit representation of the modulus and the public exponent.
848  *
849  * @param mod The data of the modulus
850  * @param modLen The length of the modulus data
851  * @param exp The data of the exponent
852  * @param expLen The length of the exponent data
853  *
854  * @return A pointer to the new RSA structure, or NULL on error
855  */
856 static RSA* rsaCreateKey(const jbyte* mod, int modLen, const jbyte* exp, int expLen) {
857     JNI_TRACE("rsaCreateKey(..., %d, ..., %d)", modLen, expLen);
858
859     Unique_RSA rsa(RSA_new());
860     if (rsa.get() == NULL) {
861         return NULL;
862     }
863
864     rsa->n = BN_bin2bn(reinterpret_cast<const unsigned char*>(mod), modLen, NULL);
865     rsa->e = BN_bin2bn(reinterpret_cast<const unsigned char*>(exp), expLen, NULL);
866
867     if (rsa->n == NULL || rsa->e == NULL) {
868         return NULL;
869     }
870
871     JNI_TRACE("rsaCreateKey(..., %d, ..., %d) => %p", modLen, expLen, rsa.get());
872     return rsa.release();
873 }
874
875 /**
876  * Helper function that verifies a given RSA signature for a given message.
877  *
878  * @param msg The message to verify
879  * @param msgLen The length of the message
880  * @param sig The signature to verify
881  * @param sigLen The length of the signature
882  * @param algorithm The name of the hash/sign algorithm to use, e.g. "RSA-SHA1"
883  * @param rsa The RSA public key to use
884  *
885  * @return 1 on success, 0 on failure, -1 on error (check SSL errors then)
886  *
887  */
888 static int rsaVerify(const jbyte* msg, unsigned int msgLen, const jbyte* sig,
889                      unsigned int sigLen, const char* algorithm, RSA* rsa) {
890
891     JNI_TRACE("rsaVerify(%p, %d, %p, %d, %s, %p)",
892               msg, msgLen, sig, sigLen, algorithm, rsa);
893
894     Unique_EVP_PKEY pkey(EVP_PKEY_new());
895     if (pkey.get() == NULL) {
896         return -1;
897     }
898     EVP_PKEY_set1_RSA(pkey.get(), rsa);
899
900     const EVP_MD* type = EVP_get_digestbyname(algorithm);
901     if (type == NULL) {
902         return -1;
903     }
904
905     EVP_MD_CTX ctx;
906     EVP_MD_CTX_init(&ctx);
907     if (EVP_VerifyInit_ex(&ctx, type, NULL) == 0) {
908         return -1;
909     }
910
911     EVP_VerifyUpdate(&ctx, msg, msgLen);
912     int result = EVP_VerifyFinal(&ctx, reinterpret_cast<const unsigned char*>(sig), sigLen,
913             pkey.get());
914     EVP_MD_CTX_cleanup(&ctx);
915
916     JNI_TRACE("rsaVerify(%p, %d, %p, %d, %s, %p) => %d",
917               msg, msgLen, sig, sigLen, algorithm, rsa, result);
918     return result;
919 }
920
921 /**
922  * Verifies an RSA signature.
923  */
924 static int NativeCrypto_verifySignature(JNIEnv* env, jclass,
925         jbyteArray msg, jbyteArray sig, jstring algorithm, jbyteArray mod, jbyteArray exp) {
926
927     JNI_TRACE("NativeCrypto_verifySignature msg=%p sig=%p algorithm=%p mod=%p exp%p",
928               msg, sig, algorithm, mod, exp);
929
930     ScopedByteArrayRO msgBytes(env, msg);
931     if (msgBytes.get() == NULL) {
932         return -1;
933     }
934     ScopedByteArrayRO sigBytes(env, sig);
935     if (sigBytes.get() == NULL) {
936         return -1;
937     }
938     ScopedByteArrayRO modBytes(env, mod);
939     if (modBytes.get() == NULL) {
940         return -1;
941     }
942     ScopedByteArrayRO expBytes(env, exp);
943     if (expBytes.get() == NULL) {
944         return -1;
945     }
946
947     ScopedUtfChars algorithmChars(env, algorithm);
948     if (algorithmChars.c_str() == NULL) {
949         return -1;
950     }
951     JNI_TRACE("NativeCrypto_verifySignature algorithmChars=%s", algorithmChars.c_str());
952
953     Unique_RSA rsa(rsaCreateKey(modBytes.get(), modBytes.size(), expBytes.get(), expBytes.size()));
954     int result = -1;
955     if (rsa.get() != NULL) {
956         result = rsaVerify(msgBytes.get(), msgBytes.size(), sigBytes.get(), sigBytes.size(),
957                 algorithmChars.c_str(), rsa.get());
958     }
959
960     if (result == -1) {
961         if (!throwExceptionIfNecessary(env, "NativeCrypto_verifySignature")) {
962             jniThrowRuntimeException(env, "Internal error during verification");
963         }
964     }
965
966     JNI_TRACE("NativeCrypto_verifySignature => %d", result);
967     return result;
968 }
969
970 static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) {
971     JNI_TRACE("NativeCrypto_RAND_seed seed=%p", seed);
972     ScopedByteArrayRO randseed(env, seed);
973     if (randseed.get() == NULL) {
974         return;
975     }
976     RAND_seed(randseed.get(), randseed.size());
977 }
978
979 static int NativeCrypto_RAND_load_file(JNIEnv* env, jclass, jstring filename, jlong max_bytes) {
980     JNI_TRACE("NativeCrypto_RAND_load_file filename=%p max_bytes=%lld", filename, max_bytes);
981     ScopedUtfChars file(env, filename);
982     if (file.c_str() == NULL) {
983         return -1;
984     }
985     int result = RAND_load_file(file.c_str(), max_bytes);
986     JNI_TRACE("NativeCrypto_RAND_load_file file=%s => %d", file.c_str(), result);
987     return result;
988 }
989
990 /**
991  * Convert ssl version constant to string. Based on SSL_get_version
992  */
993 // TODO move to jsse.patch
994 static const char* get_ssl_version(int ssl_version) {
995     switch (ssl_version) {
996         // newest to oldest
997         case TLS1_VERSION: {
998           return SSL_TXT_TLSV1;
999         }
1000         case SSL3_VERSION: {
1001           return SSL_TXT_SSLV3;
1002         }
1003         case SSL2_VERSION: {
1004           return SSL_TXT_SSLV2;
1005         }
1006         default: {
1007           return "unknown";
1008         }
1009     }
1010 }
1011
1012 #ifdef WITH_JNI_TRACE
1013 /**
1014  * Convert content type constant to string.
1015  */
1016 // TODO move to jsse.patch
1017 static const char* get_content_type(int content_type) {
1018     switch (content_type) {
1019         case SSL3_RT_CHANGE_CIPHER_SPEC: {
1020             return "SSL3_RT_CHANGE_CIPHER_SPEC";
1021         }
1022         case SSL3_RT_ALERT: {
1023             return "SSL3_RT_ALERT";
1024         }
1025         case SSL3_RT_HANDSHAKE: {
1026             return "SSL3_RT_HANDSHAKE";
1027         }
1028         case SSL3_RT_APPLICATION_DATA: {
1029             return "SSL3_RT_APPLICATION_DATA";
1030         }
1031         default: {
1032             LOGD("Unknown TLS/SSL content type %d", content_type);
1033             return "<unknown>";
1034         }
1035     }
1036 }
1037 #endif
1038
1039 #ifdef WITH_JNI_TRACE
1040 /**
1041  * Simple logging call back to show hand shake messages
1042  */
1043 static void ssl_msg_callback_LOG(int write_p, int ssl_version, int content_type,
1044                                  const void* buf, size_t len, SSL* ssl, void* arg) {
1045   JNI_TRACE("ssl=%p SSL msg %s %s %s %p %d %p",
1046            ssl,
1047            (write_p) ? "send" : "recv",
1048            get_ssl_version(ssl_version),
1049            get_content_type(content_type),
1050            buf,
1051            len,
1052            arg);
1053 }
1054 #endif
1055
1056 #ifdef WITH_JNI_TRACE
1057 /**
1058  * Based on example logging call back from SSL_CTX_set_info_callback man page
1059  */
1060 static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, int ret)
1061 {
1062     int w = where & ~SSL_ST_MASK;
1063     const char* str;
1064     if (w & SSL_ST_CONNECT) {
1065         str = "SSL_connect";
1066     } else if (w & SSL_ST_ACCEPT) {
1067         str = "SSL_accept";
1068     } else {
1069         str = "undefined";
1070     }
1071
1072     if (where & SSL_CB_LOOP) {
1073         JNI_TRACE("ssl=%p %s:%s %s", s, str, SSL_state_string(s), SSL_state_string_long(s));
1074     } else if (where & SSL_CB_ALERT) {
1075         str = (where & SSL_CB_READ) ? "read" : "write";
1076         JNI_TRACE("ssl=%p SSL3 alert %s:%s:%s %s %s",
1077                   s,
1078                   str,
1079                   SSL_alert_type_string(ret),
1080                   SSL_alert_desc_string(ret),
1081                   SSL_alert_type_string_long(ret),
1082                   SSL_alert_desc_string_long(ret));
1083     } else if (where & SSL_CB_EXIT) {
1084         if (ret == 0) {
1085             JNI_TRACE("ssl=%p %s:failed exit in %s %s",
1086                       s, str, SSL_state_string(s), SSL_state_string_long(s));
1087         } else if (ret < 0) {
1088             JNI_TRACE("ssl=%p %s:error exit in %s %s",
1089                       s, str, SSL_state_string(s), SSL_state_string_long(s));
1090         } else if (ret == 1) {
1091             JNI_TRACE("ssl=%p %s:ok exit in %s %s",
1092                       s, str, SSL_state_string(s), SSL_state_string_long(s));
1093         } else {
1094             JNI_TRACE("ssl=%p %s:unknown exit %d in %s %s",
1095                       s, str, ret, SSL_state_string(s), SSL_state_string_long(s));
1096         }
1097     } else if (where & SSL_CB_HANDSHAKE_START) {
1098         JNI_TRACE("ssl=%p handshake start in %s %s",
1099                   s, SSL_state_string(s), SSL_state_string_long(s));
1100     } else if (where & SSL_CB_HANDSHAKE_DONE) {
1101         JNI_TRACE("ssl=%p handshake done in %s %s",
1102                   s, SSL_state_string(s), SSL_state_string_long(s));
1103     } else {
1104         JNI_TRACE("ssl=%p %s:unknown where %d in %s %s",
1105                   s, str, where, SSL_state_string(s), SSL_state_string_long(s));
1106     }
1107 }
1108 #endif
1109
1110 /**
1111  * Returns an array containing all the X509 certificate's bytes.
1112  */
1113 static jobjectArray getCertificateBytes(JNIEnv* env, const STACK_OF(X509)* chain)
1114 {
1115     if (chain == NULL) {
1116         // Chain can be NULL if the associated cipher doesn't do certs.
1117         return NULL;
1118     }
1119
1120     int count = sk_X509_num(chain);
1121     if (count <= 0) {
1122         return NULL;
1123     }
1124
1125     jobjectArray joa = env->NewObjectArray(count, JniConstants::byteArrayClass, NULL);
1126     if (joa == NULL) {
1127         return NULL;
1128     }
1129
1130     for (int i = 0; i < count; i++) {
1131         X509* cert = sk_X509_value(chain, i);
1132
1133         int len = i2d_X509(cert, NULL);
1134         if (len < 0) {
1135             return NULL;
1136         }
1137         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
1138         if (byteArray.get() == NULL) {
1139             return NULL;
1140         }
1141         ScopedByteArrayRW bytes(env, byteArray.get());
1142         if (bytes.get() == NULL) {
1143             return NULL;
1144         }
1145         unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
1146         int n = i2d_X509(cert, &p);
1147         if (n < 0) {
1148             return NULL;
1149         }
1150         env->SetObjectArrayElement(joa, i, byteArray.get());
1151     }
1152
1153     return joa;
1154 }
1155
1156 /**
1157  * Returns an array containing all the X500 principal's bytes.
1158  */
1159 static jobjectArray getPrincipalBytes(JNIEnv* env, const STACK_OF(X509_NAME)* names)
1160 {
1161     if (names == NULL) {
1162         return NULL;
1163     }
1164
1165     int count = sk_X509_NAME_num(names);
1166     if (count <= 0) {
1167         return NULL;
1168     }
1169
1170     jobjectArray joa = env->NewObjectArray(count, JniConstants::byteArrayClass, NULL);
1171     if (joa == NULL) {
1172         return NULL;
1173     }
1174
1175     for (int i = 0; i < count; i++) {
1176         X509_NAME* principal = sk_X509_NAME_value(names, i);
1177
1178         int len = i2d_X509_NAME(principal, NULL);
1179         if (len < 0) {
1180             return NULL;
1181         }
1182         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
1183         if (byteArray.get() == NULL) {
1184             return NULL;
1185         }
1186         ScopedByteArrayRW bytes(env, byteArray.get());
1187         if (bytes.get() == NULL) {
1188             return NULL;
1189         }
1190         unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
1191         int n = i2d_X509_NAME(principal, &p);
1192         if (n < 0) {
1193             return NULL;
1194         }
1195         env->SetObjectArrayElement(joa, i, byteArray.get());
1196     }
1197
1198     return joa;
1199 }
1200
1201 /**
1202  * Our additional application data needed for getting synchronization right.
1203  * This maybe warrants a bit of lengthy prose:
1204  *
1205  * (1) We use a flag to reflect whether we consider the SSL connection alive.
1206  * Any read or write attempt loops will be cancelled once this flag becomes 0.
1207  *
1208  * (2) We use an int to count the number of threads that are blocked by the
1209  * underlying socket. This may be at most two (one reader and one writer), since
1210  * the Java layer ensures that no more threads will enter the native code at the
1211  * same time.
1212  *
1213  * (3) The pipe is used primarily as a means of cancelling a blocking select()
1214  * when we want to close the connection (aka "emergency button"). It is also
1215  * necessary for dealing with a possible race condition situation: There might
1216  * be cases where both threads see an SSL_ERROR_WANT_READ or
1217  * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
1218  * If one leaves the select() successfully before the other enters it, the
1219  * "success" event is already consumed and the second thread will be blocked,
1220  * possibly forever (depending on network conditions).
1221  *
1222  * The idea for solving the problem looks like this: Whenever a thread is
1223  * successful in moving around data on the network, and it knows there is
1224  * another thread stuck in a select(), it will write a byte to the pipe, waking
1225  * up the other thread. A thread that returned from select(), on the other hand,
1226  * knows whether it's been woken up by the pipe. If so, it will consume the
1227  * byte, and the original state of affairs has been restored.
1228  *
1229  * The pipe may seem like a bit of overhead, but it fits in nicely with the
1230  * other file descriptors of the select(), so there's only one condition to wait
1231  * for.
1232  *
1233  * (4) Finally, a mutex is needed to make sure that at most one thread is in
1234  * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
1235  * requirement. We use the same mutex to guard the field for counting the
1236  * waiting threads.
1237  *
1238  * Note: The current implementation assumes that we don't have to deal with
1239  * problems induced by multiple cores or processors and their respective
1240  * memory caches. One possible problem is that of inconsistent views on the
1241  * "aliveAndKicking" field. This could be worked around by also enclosing all
1242  * accesses to that field inside a lock/unlock sequence of our mutex, but
1243  * currently this seems a bit like overkill. Marking volatile at the very least.
1244  *
1245  * During handshaking, additional fields are used to up-call into
1246  * Java to perform certificate verification and handshake
1247  * completion. These are also used in any renegotiation.
1248  *
1249  * (5) the JNIEnv so we can invoke the Java callback
1250  *
1251  * (6) a NativeCrypto.SSLHandshakeCallbacks instance for callbacks from native to Java
1252  *
1253  * (7) a java.io.FileDescriptor wrapper to check for socket close
1254  *
1255  * Because renegotiation can be requested by the peer at any time,
1256  * care should be taken to maintain an appropriate JNIEnv on any
1257  * downcall to openssl since it could result in an upcall to Java. The
1258  * current code does try to cover these cases by conditionally setting
1259  * the JNIEnv on calls that can read and write to the SSL such as
1260  * SSL_do_handshake, SSL_read, SSL_write, and SSL_shutdown.
1261  *
1262  * Finally, we have one other piece of state setup by OpenSSL callbacks:
1263  *
1264  * (8) a set of ephemeral RSA keys that is lazily generated if a peer
1265  * wants to use an exportable RSA cipher suite.
1266  *
1267  */
1268 class AppData {
1269   public:
1270     volatile int aliveAndKicking;
1271     int waitingThreads;
1272     int fdsEmergency[2];
1273     MUTEX_TYPE mutex;
1274     JNIEnv* env;
1275     jobject sslHandshakeCallbacks;
1276     jobject fileDescriptor;
1277     Unique_RSA ephemeralRsa;
1278
1279     /**
1280      * Creates the application data context for the SSL*.
1281      */
1282   public:
1283     static AppData* create() {
1284         UniquePtr<AppData> appData(new AppData());
1285         if (pipe(appData.get()->fdsEmergency) == -1) {
1286             return NULL;
1287         }
1288         if (MUTEX_SETUP(appData.get()->mutex) == -1) {
1289             return NULL;
1290         }
1291         return appData.release();
1292     }
1293
1294     ~AppData() {
1295         aliveAndKicking = 0;
1296         if (fdsEmergency[0] != -1) {
1297             close(fdsEmergency[0]);
1298         }
1299         if (fdsEmergency[1] != -1) {
1300             close(fdsEmergency[1]);
1301         }
1302         MUTEX_CLEANUP(mutex);
1303     }
1304
1305   private:
1306     AppData() :
1307             aliveAndKicking(1),
1308             waitingThreads(0),
1309             env(NULL),
1310             sslHandshakeCallbacks(NULL),
1311             ephemeralRsa(NULL) {
1312         fdsEmergency[0] = -1;
1313         fdsEmergency[1] = -1;
1314     }
1315
1316   public:
1317     /**
1318      * Used to set the SSL-to-Java callback state before each SSL_*
1319      * call that may result in a callback. It should be cleared after
1320      * the operation returns with clearCallbackState.
1321      *
1322      * @param env The JNIEnv
1323      * @param shc The SSLHandshakeCallbacks
1324      * @param fd The FileDescriptor
1325      */
1326     bool setCallbackState(JNIEnv* e, jobject shc, jobject fd) {
1327         NetFd netFd(e, fd);
1328         if (netFd.isClosed()) {
1329             return false;
1330         }
1331         env = e;
1332         sslHandshakeCallbacks = shc;
1333         fileDescriptor = fd;
1334         return true;
1335     }
1336
1337     void clearCallbackState() {
1338         env = NULL;
1339         sslHandshakeCallbacks = NULL;
1340         fileDescriptor = NULL;
1341     }
1342
1343 };
1344
1345 /**
1346  * Dark magic helper function that checks, for a given SSL session, whether it
1347  * can SSL_read() or SSL_write() without blocking. Takes into account any
1348  * concurrent attempts to close the SSL session from the Java side. This is
1349  * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
1350  * while thread #2 is sitting in a blocking read or write. The type argument
1351  * specifies whether we are waiting for readability or writability. It expects
1352  * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
1353  * only need to wait in case one of these problems occurs.
1354  *
1355  * @param env
1356  * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
1357  * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL
1358  * @param appData The application data structure with mutex info etc.
1359  * @param timeout The timeout value for select call, with the special value
1360  *                0 meaning no timeout at all (wait indefinitely). Note: This is
1361  *                the Java semantics of the timeout value, not the usual
1362  *                select() semantics.
1363  * @return The result of the inner select() call,
1364  * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on
1365  * additional errors
1366  */
1367 static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout) {
1368     // This loop is an expanded version of the NET_FAILURE_RETRY
1369     // macro. It cannot simply be used in this case because select
1370     // cannot be restarted without recreating the fd_sets and timeout
1371     // structure.
1372     int result;
1373     fd_set rfds;
1374     fd_set wfds;
1375     do {
1376         NetFd fd(env, fdObject);
1377         if (fd.isClosed()) {
1378             result = THROWN_SOCKETEXCEPTION;
1379             break;
1380         }
1381         int intFd = fd.get();
1382         JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout=%d",
1383                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout);
1384
1385         FD_ZERO(&rfds);
1386         FD_ZERO(&wfds);
1387
1388         if (type == SSL_ERROR_WANT_READ) {
1389             FD_SET(intFd, &rfds);
1390         } else {
1391             FD_SET(intFd, &wfds);
1392         }
1393
1394         FD_SET(appData->fdsEmergency[0], &rfds);
1395
1396         int max = intFd > appData->fdsEmergency[0] ? intFd : appData->fdsEmergency[0];
1397
1398         // Build a struct for the timeout data if we actually want a timeout.
1399         timeval tv;
1400         timeval* ptv;
1401         if (timeout > 0) {
1402             tv.tv_sec = timeout / 1000;
1403             tv.tv_usec = 0;
1404             ptv = &tv;
1405         } else {
1406             ptv = NULL;
1407         }
1408
1409         {
1410             AsynchronousSocketCloseMonitor monitor(intFd);
1411             result = select(max + 1, &rfds, &wfds, NULL, ptv);
1412             JNI_TRACE("sslSelect %s fd=%d appData=%p timeout=%d => %d",
1413                       (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE",
1414                       fd.get(), appData, timeout, result);
1415             if (result == -1) {
1416                 if (fd.isClosed()) {
1417                     result = THROWN_SOCKETEXCEPTION;
1418                     break;
1419                 }
1420                 if (errno != EINTR) {
1421                     break;
1422                 }
1423             }
1424         }
1425     } while (result == -1);
1426
1427     // Lock
1428     if (MUTEX_LOCK(appData->mutex) == -1) {
1429         return -1;
1430     }
1431
1432     if (result > 0) {
1433         // If we have been woken up by the emergency pipe, there must be a token in
1434         // it. Thus we can safely read it (even in a blocking way).
1435         if (FD_ISSET(appData->fdsEmergency[0], &rfds)) {
1436             char token;
1437             do {
1438                 read(appData->fdsEmergency[0], &token, 1);
1439             } while (errno == EINTR);
1440         }
1441     }
1442
1443     // Tell the world that there is now one thread less waiting for the
1444     // underlying network.
1445     appData->waitingThreads--;
1446
1447     // Unlock
1448     MUTEX_UNLOCK(appData->mutex);
1449
1450     return result;
1451 }
1452
1453 /**
1454  * Helper function that wakes up a thread blocked in select(), in case there is
1455  * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
1456  * before closing the connection.
1457  *
1458  * @param data The application data structure with mutex info etc.
1459  */
1460 static void sslNotify(AppData* appData) {
1461     // Write a byte to the emergency pipe, so a concurrent select() can return.
1462     // Note we have to restore the errno of the original system call, since the
1463     // caller relies on it for generating error messages.
1464     int errnoBackup = errno;
1465     char token = '*';
1466     do {
1467         errno = 0;
1468         write(appData->fdsEmergency[1], &token, 1);
1469     } while (errno == EINTR);
1470     errno = errnoBackup;
1471 }
1472
1473 // From private header file external/openssl/ssl_locl.h
1474 // TODO move dependent code to jsse.patch to avoid dependency
1475 #define SSL_aRSA                0x00000001L
1476 #define SSL_aDSS                0x00000002L
1477 #define SSL_aNULL               0x00000004L
1478 #define SSL_aDH                 0x00000008L
1479 #define SSL_aECDH               0x00000010L
1480 #define SSL_aKRB5               0x00000020L
1481 #define SSL_aECDSA              0x00000040L
1482 #define SSL_aPSK                0x00000080L
1483
1484 /**
1485  * Converts an SSL_CIPHER's algorithms field to a TrustManager auth argument
1486  */
1487 // TODO move to jsse.patch
1488 static const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
1489 {
1490     unsigned long alg_auth = cipher->algorithm_auth;
1491
1492     const char* au;
1493     switch (alg_auth) {
1494         case SSL_aRSA:
1495             au="RSA";
1496             break;
1497         case SSL_aDSS:
1498             au="DSS";
1499             break;
1500         case SSL_aDH:
1501             au="DH";
1502             break;
1503         case SSL_aKRB5:
1504             au="KRB5";
1505             break;
1506         case SSL_aECDH:
1507             au = "ECDH";
1508             break;
1509         case SSL_aNULL:
1510             au="None";
1511             break;
1512         case SSL_aECDSA:
1513             au="ECDSA";
1514             break;
1515         case SSL_aPSK:
1516             au="PSK";
1517             break;
1518         default:
1519             au="unknown";
1520             break;
1521     }
1522     return au;
1523 }
1524
1525 /**
1526  * Converts an SSL_CIPHER's algorithms field to a TrustManager auth argument
1527  */
1528 // TODO move to jsse.patch
1529 static const char* SSL_authentication_method(SSL* ssl)
1530 {
1531     switch (ssl->version) {
1532       case SSL2_VERSION:
1533         return "RSA";
1534       case SSL3_VERSION:
1535       case TLS1_VERSION:
1536       case DTLS1_VERSION:
1537         return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
1538       default:
1539         return "unknown";
1540     }
1541 }
1542
1543 static AppData* toAppData(const SSL* ssl) {
1544     return reinterpret_cast<AppData*>(SSL_get_app_data(ssl));
1545 }
1546
1547 /**
1548  * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback
1549  */
1550 static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused)))
1551 {
1552     /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
1553     SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx,
1554             SSL_get_ex_data_X509_STORE_CTX_idx()));
1555     JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg);
1556
1557     AppData* appData = toAppData(ssl);
1558     JNIEnv* env = appData->env;
1559     if (env == NULL) {
1560         LOGE("AppData->env missing in cert_verify_callback");
1561         JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl);
1562         return 0;
1563     }
1564     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
1565
1566     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
1567     jmethodID methodID
1568         = env->GetMethodID(cls, "verifyCertificateChain", "([[BLjava/lang/String;)V");
1569
1570     jobjectArray objectArray = getCertificateBytes(env, x509_store_ctx->untrusted);
1571
1572     const char* authMethod = SSL_authentication_method(ssl);
1573     JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s",
1574               ssl, authMethod);
1575     jstring authMethodString = env->NewStringUTF(authMethod);
1576     env->CallVoidMethod(sslHandshakeCallbacks, methodID, objectArray, authMethodString);
1577
1578     int result = (env->ExceptionCheck()) ? 0 : 1;
1579     JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result);
1580     return result;
1581 }
1582
1583 /**
1584  * Call back to watch for handshake to be completed. This is necessary
1585  * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake
1586  * returns before the handshake is completed in this case.
1587  */
1588 static void info_callback(const SSL* ssl, int where, int ret __attribute__ ((unused))) {
1589     JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret);
1590 #ifdef WITH_JNI_TRACE
1591     info_callback_LOG(ssl, where, ret);
1592 #endif
1593     if (!(where & SSL_CB_HANDSHAKE_DONE)) {
1594         JNI_TRACE("ssl=%p info_callback ignored", ssl);
1595         return;
1596     }
1597
1598     AppData* appData = toAppData(ssl);
1599     JNIEnv* env = appData->env;
1600     if (env == NULL) {
1601         LOGE("AppData->env missing in info_callback");
1602         JNI_TRACE("ssl=%p info_callback env error", ssl);
1603         return;
1604     }
1605     if (env->ExceptionCheck()) {
1606         JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
1607         return;
1608     }
1609
1610     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
1611
1612     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
1613     jmethodID methodID = env->GetMethodID(cls, "handshakeCompleted", "()V");
1614
1615     JNI_TRACE("ssl=%p info_callback calling handshakeCompleted", ssl);
1616     env->CallVoidMethod(sslHandshakeCallbacks, methodID);
1617
1618     if (env->ExceptionCheck()) {
1619         JNI_TRACE("ssl=%p info_callback exception", ssl);
1620     }
1621     JNI_TRACE("ssl=%p info_callback completed", ssl);
1622 }
1623
1624 /**
1625  * Call back to ask for a client certificate
1626  */
1627 static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) {
1628     JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut);
1629
1630     AppData* appData = toAppData(ssl);
1631     JNIEnv* env = appData->env;
1632     if (env == NULL) {
1633         LOGE("AppData->env missing in client_cert_cb");
1634         JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl);
1635         return 0;
1636     }
1637     if (env->ExceptionCheck()) {
1638         JNI_TRACE("ssl=%p client_cert_cb already pending exception", ssl);
1639         return 0;
1640     }
1641     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
1642
1643     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
1644     jmethodID methodID
1645         = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V");
1646
1647     // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values
1648     char ssl2_ctype = SSL3_CT_RSA_SIGN;
1649     const char* ctype = NULL;
1650     int ctype_num = 0;
1651     jobjectArray issuers = NULL;
1652     switch (ssl->version) {
1653         case SSL2_VERSION:
1654             ctype = &ssl2_ctype;
1655             ctype_num = 1;
1656             break;
1657         case SSL3_VERSION:
1658         case TLS1_VERSION:
1659         case DTLS1_VERSION:
1660             ctype = ssl->s3->tmp.ctype;
1661             ctype_num = ssl->s3->tmp.ctype_num;
1662             issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names);
1663             break;
1664     }
1665 #ifdef WITH_JNI_TRACE
1666     for (int i = 0; i < ctype_num; i++) {
1667         JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]);
1668     }
1669 #endif
1670
1671     jbyteArray keyTypes = env->NewByteArray(ctype_num);
1672     if (keyTypes == NULL) {
1673         JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl);
1674         return 0;
1675     }
1676     env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype));
1677
1678     JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested "
1679               "keyTypes=%p issuers=%p", ssl, keyTypes, issuers);
1680     env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers);
1681
1682     if (env->ExceptionCheck()) {
1683         JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl);
1684         return 0;
1685     }
1686
1687     // Check for values set from Java
1688     X509*     certificate = SSL_get_certificate(ssl);
1689     EVP_PKEY* privatekey  = SSL_get_privatekey(ssl);
1690     int result;
1691     if (certificate != NULL && privatekey != NULL) {
1692         *x509Out = certificate;
1693         *pkeyOut = privatekey;
1694         result = 1;
1695     } else {
1696         *x509Out = NULL;
1697         *pkeyOut = NULL;
1698         result = 0;
1699     }
1700     JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result);
1701     return result;
1702 }
1703
1704 static RSA* rsaGenerateKey(int keylength) {
1705     Unique_BIGNUM bn(BN_new());
1706     if (bn.get() == NULL) {
1707         return NULL;
1708     }
1709     int setWordResult = BN_set_word(bn.get(), RSA_F4);
1710     if (setWordResult != 1) {
1711         return NULL;
1712     }
1713     Unique_RSA rsa(RSA_new());
1714     if (rsa.get() == NULL) {
1715         return NULL;
1716     }
1717     int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL);
1718     if (generateResult != 1) {
1719         return NULL;
1720     }
1721     return rsa.release();
1722 }
1723
1724 /**
1725  * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5)
1726  */
1727 static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)),
1728                              int is_export __attribute__ ((unused)),
1729                              int keylength) {
1730     JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength);
1731
1732     AppData* appData = toAppData(ssl);
1733     if (appData->ephemeralRsa.get() == NULL) {
1734         JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl);
1735         appData->ephemeralRsa.reset(rsaGenerateKey(keylength));
1736     }
1737     JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get());
1738     return appData->ephemeralRsa.get();
1739 }
1740
1741 static DH* dhGenerateParameters(int keylength) {
1742
1743     /*
1744      * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two
1745      * different options for generating DH keys. One is generating the
1746      * keys using a single set of DH parameters. However, generating
1747      * DH parameters is slow enough (minutes) that they suggest doing
1748      * it once at install time. The other is to generate DH keys from
1749      * DSA parameters. Generating DSA parameters is faster than DH
1750      * parameters, but to prevent small subgroup attacks, they needed
1751      * to be regenerated for each set of DH keys. Setting the
1752      * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back
1753      * for new DH parameters every type it needs to generate DH keys.
1754      */
1755 #if 0
1756     // Slow path that takes minutes but could be cached
1757     Unique_DH dh(DH_new());
1758     if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) {
1759         return NULL;
1760     }
1761     return dh.release();
1762 #else
1763     // Faster path but must have SSL_OP_SINGLE_DH_USE set
1764     Unique_DSA dsa(DSA_new());
1765     if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) {
1766         return NULL;
1767     }
1768     DH* dh = DSA_dup_DH(dsa.get());
1769     return dh;
1770 #endif
1771 }
1772
1773 /**
1774  * Call back to ask for Diffie-Hellman parameters
1775  */
1776 static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)),
1777                            int is_export __attribute__ ((unused)),
1778                            int keylength) {
1779     JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
1780     DH* tmp_dh = dhGenerateParameters(keylength);
1781     JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh);
1782     return tmp_dh;
1783 }
1784
1785 /*
1786  * public static native int SSL_CTX_new();
1787  */
1788 static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
1789     Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
1790     if (sslCtx.get() == NULL) {
1791         jniThrowRuntimeException(env, "SSL_CTX_new");
1792         return NULL;
1793     }
1794     SSL_CTX_set_options(sslCtx.get(),
1795                         SSL_OP_ALL
1796                         // Note: We explicitly do not allow SSLv2 to be used.
1797                         | SSL_OP_NO_SSLv2
1798                         // We also disable session tickets for better compatibility b/2682876
1799                         | SSL_OP_NO_TICKET
1800                         // We also disable compression for better compatibility b/2710492 b/2710497
1801                         | SSL_OP_NO_COMPRESSION
1802                         // Because dhGenerateParameters uses DSA_generate_parameters_ex
1803                         | SSL_OP_SINGLE_DH_USE);
1804
1805     int mode = SSL_CTX_get_mode(sslCtx.get());
1806     /*
1807      * Turn on "partial write" mode. This means that SSL_write() will
1808      * behave like Posix write() and possibly return after only
1809      * writing a partial buffer. Note: The alternative, perhaps
1810      * surprisingly, is not that SSL_write() always does full writes
1811      * but that it will force you to retry write calls having
1812      * preserved the full state of the original call. (This is icky
1813      * and undesirable.)
1814      */
1815     mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
1816 #if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
1817     mode |= SSL_MODE_SMALL_BUFFERS;  /* lazily allocate record buffers; usually saves
1818                                       * 44k over the default */
1819 #endif
1820 #if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) /* not all SSL versions have this */
1821     mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;  /* enable sending of client data as soon as
1822                                              * ClientCCS and ClientFinished are sent */
1823 #endif
1824     SSL_CTX_set_mode(sslCtx.get(), mode);
1825
1826     SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL);
1827     SSL_CTX_set_info_callback(sslCtx.get(), info_callback);
1828     SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb);
1829     SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback);
1830     SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback);
1831
1832 #ifdef WITH_JNI_TRACE
1833     SSL_CTX_set_msg_callback(sslCtx.get(), ssl_msg_callback_LOG); /* enable for message debug */
1834 #endif
1835     JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
1836     return (jint) sslCtx.release();
1837 }
1838
1839 /**
1840  * public static native void SSL_CTX_free(int ssl_ctx)
1841  */
1842 static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
1843         jclass, jint ssl_ctx_address)
1844 {
1845     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
1846     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
1847     if (ssl_ctx == NULL) {
1848         return;
1849     }
1850     SSL_CTX_free(ssl_ctx);
1851 }
1852
1853 /**
1854  * public static native int SSL_new(int ssl_ctx) throws SSLException;
1855  */
1856 static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address)
1857 {
1858     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
1859     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
1860     if (ssl_ctx == NULL) {
1861         return NULL;
1862     }
1863     Unique_SSL ssl(SSL_new(ssl_ctx));
1864     if (ssl.get() == NULL) {
1865         throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE,
1866                 "Unable to create SSL structure");
1867         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
1868         return NULL;
1869     }
1870
1871     /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
1872      * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
1873      * (by default disabled), the server will send a certificate which will
1874      * be checked. The result of the certificate verification process can be
1875      * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
1876      * function. The handshake will be continued regardless of the
1877      * verification result.
1878      */
1879     SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL);
1880
1881     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get());
1882     return (jint) ssl.release();
1883 }
1884
1885 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass,
1886                                             jint ssl_address, jbyteArray privatekey)
1887 {
1888     SSL* ssl = to_SSL(env, ssl_address, true);
1889     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey privatekey=%p", ssl, privatekey);
1890     if (ssl == NULL) {
1891         return;
1892     }
1893
1894     ScopedByteArrayRO buf(env, privatekey);
1895     if (buf.get() == NULL) {
1896         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => threw exception", ssl);
1897         return;
1898     }
1899     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
1900     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, buf.size()));
1901     if (pkcs8.get() == NULL) {
1902         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
1903         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
1904                                        "Error parsing private key from DER to PKCS8");
1905         SSL_clear(ssl);
1906         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from DER to PKCS8", ssl);
1907         return;
1908     }
1909
1910     Unique_EVP_PKEY privatekeyevp(EVP_PKCS82PKEY(pkcs8.get()));
1911     if (privatekeyevp.get() == NULL) {
1912         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
1913         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
1914                                        "Error creating private key from PKCS8");
1915         SSL_clear(ssl);
1916         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from PKCS8 to key", ssl);
1917         return;
1918     }
1919
1920     int ret = SSL_use_PrivateKey(ssl, privatekeyevp.get());
1921     if (ret == 1) {
1922         privatekeyevp.release();
1923     } else {
1924         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
1925         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
1926         SSL_clear(ssl);
1927         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error", ssl);
1928         return;
1929     }
1930
1931     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => ok", ssl);
1932 }
1933
1934 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
1935                                              jint ssl_address, jobjectArray certificates)
1936 {
1937     SSL* ssl = to_SSL(env, ssl_address, true);
1938     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
1939     if (ssl == NULL) {
1940         return;
1941     }
1942
1943     if (certificates == NULL) {
1944         jniThrowNullPointerException(env, "certificates == null");
1945         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
1946         return;
1947     }
1948
1949     int length = env->GetArrayLength(certificates);
1950     if (length == 0) {
1951         jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
1952         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
1953         return;
1954     }
1955
1956     Unique_X509 certificatesX509[length];
1957     for (int i = 0; i < length; i++) {
1958         ScopedLocalRef<jbyteArray> certificate(env,
1959                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i)));
1960         if (certificate.get() == NULL) {
1961             jniThrowNullPointerException(env, "certificates element == null");
1962             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl);
1963             return;
1964         }
1965
1966         ScopedByteArrayRO buf(env, certificate.get());
1967         if (buf.get() == NULL) {
1968             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl);
1969             return;
1970         }
1971         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
1972         certificatesX509[i].reset(d2i_X509(NULL, &tmp, buf.size()));
1973
1974         if (certificatesX509[i].get() == NULL) {
1975             LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
1976             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
1977             SSL_clear(ssl);
1978             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
1979             return;
1980         }
1981     }
1982
1983     int ret = SSL_use_certificate(ssl, certificatesX509[0].get());
1984     if (ret == 1) {
1985         certificatesX509[0].release();
1986     } else {
1987         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
1988         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
1989         SSL_clear(ssl);
1990         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
1991         return;
1992     }
1993
1994     Unique_sk_X509 chain(sk_X509_new_null());
1995     if (chain.get() == NULL) {
1996         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
1997         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
1998         return;
1999     }
2000     for (int i = 1; i < length; i++) {
2001         if (!sk_X509_push(chain.get(), certificatesX509[i].release())) {
2002             jniThrowOutOfMemoryError(env, "Unable to push certificate");
2003             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl);
2004             return;
2005         }
2006     }
2007     int chainResult = SSL_use_certificate_chain(ssl, chain.get());
2008     if (chainResult == 0) {
2009         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
2010         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
2011                   ssl);
2012         return;
2013     } else {
2014         chain.release();
2015     }
2016
2017     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
2018 }
2019
2020 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jint ssl_address)
2021 {
2022     SSL* ssl = to_SSL(env, ssl_address, true);
2023     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
2024     if (ssl == NULL) {
2025         return;
2026     }
2027     int ret = SSL_check_private_key(ssl);
2028     if (ret != 1) {
2029         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
2030         SSL_clear(ssl);
2031         JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
2032         return;
2033     }
2034     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
2035 }
2036
2037 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
2038                                                 jint ssl_address, jobjectArray principals)
2039 {
2040     SSL* ssl = to_SSL(env, ssl_address, true);
2041     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
2042     if (ssl == NULL) {
2043         return;
2044     }
2045
2046     if (principals == NULL) {
2047         jniThrowNullPointerException(env, "principals == null");
2048         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
2049         return;
2050     }
2051
2052     int length = env->GetArrayLength(principals);
2053     if (length == 0) {
2054         jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
2055         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
2056         return;
2057     }
2058
2059     Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
2060     if (principalsStack.get() == NULL) {
2061         jniThrowOutOfMemoryError(env, "Unable to allocate principal stack");
2062         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
2063         return;
2064     }
2065     for (int i = 0; i < length; i++) {
2066         ScopedLocalRef<jbyteArray> principal(env,
2067                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
2068         if (principal.get() == NULL) {
2069             jniThrowNullPointerException(env, "principals element == null");
2070             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
2071             return;
2072         }
2073
2074         ScopedByteArrayRO buf(env, principal.get());
2075         if (buf.get() == NULL) {
2076             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
2077             return;
2078         }
2079         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
2080         Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
2081
2082         if (principalX509Name.get() == NULL) {
2083             LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
2084             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
2085             SSL_clear(ssl);
2086             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
2087                       ssl);
2088             return;
2089         }
2090
2091         if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
2092             jniThrowOutOfMemoryError(env, "Unable to push principal");
2093             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
2094             return;
2095         }
2096     }
2097
2098     SSL_set_client_CA_list(ssl, principalsStack.release());
2099     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
2100 }
2101
2102 /**
2103  * public static native long SSL_get_mode(int ssl);
2104  */
2105 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jint ssl_address) {
2106     SSL* ssl = to_SSL(env, ssl_address, true);
2107     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
2108     if (ssl == NULL) {
2109       return 0;
2110     }
2111     long mode = SSL_get_mode(ssl);
2112     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
2113     return mode;
2114 }
2115
2116 /**
2117  * public static native long SSL_set_mode(int ssl, long mode);
2118  */
2119 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
2120         jint ssl_address, jlong mode) {
2121     SSL* ssl = to_SSL(env, ssl_address, true);
2122     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
2123     if (ssl == NULL) {
2124       return 0;
2125     }
2126     long result = SSL_set_mode(ssl, mode);
2127     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
2128     return result;
2129 }
2130
2131 /**
2132  * public static native long SSL_clear_mode(int ssl, long mode);
2133  */
2134 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
2135         jint ssl_address, jlong mode) {
2136     SSL* ssl = to_SSL(env, ssl_address, true);
2137     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
2138     if (ssl == NULL) {
2139       return 0;
2140     }
2141     long result = SSL_clear_mode(ssl, mode);
2142     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
2143     return result;
2144 }
2145
2146 /**
2147  * public static native long SSL_get_options(int ssl);
2148  */
2149 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
2150         jint ssl_address) {
2151     SSL* ssl = to_SSL(env, ssl_address, true);
2152     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
2153     if (ssl == NULL) {
2154       return 0;
2155     }
2156     long options = SSL_get_options(ssl);
2157     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
2158     return options;
2159 }
2160
2161 /**
2162  * public static native long SSL_set_options(int ssl, long options);
2163  */
2164 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
2165         jint ssl_address, jlong options) {
2166     SSL* ssl = to_SSL(env, ssl_address, true);
2167     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
2168     if (ssl == NULL) {
2169       return 0;
2170     }
2171     long result = SSL_set_options(ssl, options);
2172     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
2173     return result;
2174 }
2175
2176 /**
2177  * public static native long SSL_clear_options(int ssl, long options);
2178  */
2179 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
2180         jint ssl_address, jlong options) {
2181     SSL* ssl = to_SSL(env, ssl_address, true);
2182     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
2183     if (ssl == NULL) {
2184       return 0;
2185     }
2186     long result = SSL_clear_options(ssl, options);
2187     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
2188     return result;
2189 }
2190
2191 /**
2192  * Sets the ciphers suites that are enabled in the SSL
2193  */
2194 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
2195         jint ssl_address, jobjectArray cipherSuites)
2196 {
2197     SSL* ssl = to_SSL(env, ssl_address, true);
2198     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
2199     if (ssl == NULL) {
2200         return;
2201     }
2202     if (cipherSuites == NULL) {
2203         jniThrowNullPointerException(env, "cipherSuites == null");
2204         return;
2205     }
2206
2207     Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
2208     if (cipherstack.get() == NULL) {
2209         jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
2210         return;
2211     }
2212
2213     const SSL_METHOD* ssl_method = ssl->method;
2214     int num_ciphers = ssl_method->num_ciphers();
2215
2216     int length = env->GetArrayLength(cipherSuites);
2217     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
2218     for (int i = 0; i < length; i++) {
2219         ScopedLocalRef<jstring> cipherSuite(env,
2220                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
2221         ScopedUtfChars c(env, cipherSuite.get());
2222         if (c.c_str() == NULL) {
2223             return;
2224         }
2225         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
2226         bool found = false;
2227         for (int j = 0; j < num_ciphers; j++) {
2228             const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
2229             if ((strcmp(c.c_str(), cipher->name) == 0)
2230                     && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
2231                 if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
2232                     jniThrowOutOfMemoryError(env, "Unable to push cipher");
2233                     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
2234                     return;
2235                 }
2236                 found = true;
2237             }
2238         }
2239         if (!found) {
2240             jniThrowException(env, "java/lang/IllegalArgumentException",
2241                               "Could not find cipher suite.");
2242             return;
2243         }
2244     }
2245
2246     int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
2247     if (rc == 0) {
2248         freeSslErrorState();
2249         jniThrowException(env, "java/lang/IllegalArgumentException",
2250                           "Illegal cipher suite strings.");
2251     } else {
2252         cipherstack.release();
2253     }
2254 }
2255
2256 /**
2257  * Sets certificate expectations, especially for server to request client auth
2258  */
2259 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
2260         jclass, jint ssl_address, jint mode)
2261 {
2262     SSL* ssl = to_SSL(env, ssl_address, true);
2263     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
2264     if (ssl == NULL) {
2265       return;
2266     }
2267     SSL_set_verify(ssl, (int)mode, NULL);
2268 }
2269
2270 /**
2271  * Sets the ciphers suites that are enabled in the SSL
2272  */
2273 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
2274         jint ssl_address, jint ssl_session_address)
2275 {
2276     SSL* ssl = to_SSL(env, ssl_address, true);
2277     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
2278     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
2279     if (ssl == NULL) {
2280         return;
2281     }
2282
2283     int ret = SSL_set_session(ssl, ssl_session);
2284     if (ret != 1) {
2285         /*
2286          * Translate the error, and throw if it turns out to be a real
2287          * problem.
2288          */
2289         int sslErrorCode = SSL_get_error(ssl, ret);
2290         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
2291             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
2292             SSL_clear(ssl);
2293         }
2294     }
2295 }
2296
2297 /**
2298  * Sets the ciphers suites that are enabled in the SSL
2299  */
2300 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
2301         jint ssl_address, jboolean creation_enabled)
2302 {
2303     SSL* ssl = to_SSL(env, ssl_address, true);
2304     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
2305               ssl, creation_enabled);
2306     if (ssl == NULL) {
2307         return;
2308     }
2309     SSL_set_session_creation_enabled(ssl, creation_enabled);
2310 }
2311
2312 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
2313         jint ssl_address, jstring hostname)
2314 {
2315     SSL* ssl = to_SSL(env, ssl_address, true);
2316     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
2317               ssl, hostname);
2318     if (ssl == NULL) {
2319         return;
2320     }
2321
2322     ScopedUtfChars hostnameChars(env, hostname);
2323     if (hostnameChars.c_str() == NULL) {
2324         return;
2325     }
2326     JNI_TRACE("NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s", hostnameChars.c_str());
2327
2328     int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
2329     if (ret != 1) {
2330         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
2331         SSL_clear(ssl);
2332         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
2333         return;
2334     }
2335     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
2336 }
2337
2338 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jint ssl_address) {
2339     SSL* ssl = to_SSL(env, ssl_address, true);
2340     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
2341     if (ssl == NULL) {
2342         return NULL;
2343     }
2344     const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2345     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
2346     return env->NewStringUTF(servername);
2347 }
2348
2349 /**
2350  * Perform SSL handshake
2351  */
2352 static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass,
2353     jint ssl_address, jobject fdObject, jobject shc, jint timeout, jboolean client_mode)
2354 {
2355     SSL* ssl = to_SSL(env, ssl_address, true);
2356     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout=%d client_mode=%d",
2357               ssl, fdObject, shc, timeout, client_mode);
2358     if (ssl == NULL) {
2359       return 0;
2360     }
2361     if (fdObject == NULL) {
2362         jniThrowNullPointerException(env, "fd == null");
2363         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2364         return 0;
2365     }
2366     if (shc == NULL) {
2367         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
2368         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2369         return 0;
2370     }
2371
2372     NetFd fd(env, fdObject);
2373     if (fd.isClosed()) {
2374         // SocketException thrown by NetFd.isClosed
2375         SSL_clear(ssl);
2376         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2377         return 0;
2378     }
2379
2380     int ret = SSL_set_fd(ssl, fd.get());
2381     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
2382
2383     if (ret != 1) {
2384         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
2385                                        "Error setting the file descriptor");
2386         SSL_clear(ssl);
2387         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2388         return 0;
2389     }
2390
2391     /*
2392      * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
2393      * forever and we can use select() to find out if the socket is ready.
2394      */
2395     if (!setBlocking(fd.get(), false)) {
2396         throwSSLExceptionStr(env, "Unable to make socket non blocking");
2397         SSL_clear(ssl);
2398         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2399         return 0;
2400     }
2401
2402     /*
2403      * Create our special application data.
2404      */
2405     AppData* appData = AppData::create();
2406     if (appData == NULL) {
2407         throwSSLExceptionStr(env, "Unable to create application data");
2408         SSL_clear(ssl);
2409         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2410         return 0;
2411     }
2412     SSL_set_app_data(ssl, reinterpret_cast<char*>(appData));
2413     JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData);
2414
2415     if (client_mode) {
2416         SSL_set_connect_state(ssl);
2417     } else {
2418         SSL_set_accept_state(ssl);
2419     }
2420
2421     ret = 0;
2422     while (appData->aliveAndKicking) {
2423         errno = 0;
2424         if (!appData->setCallbackState(env, shc, fdObject)) {
2425             // SocketException thrown by NetFd.isClosed
2426             SSL_clear(ssl);
2427             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2428             return 0;
2429         }
2430         ret = SSL_do_handshake(ssl);
2431         appData->clearCallbackState();
2432         // cert_verify_callback threw exception
2433         if (env->ExceptionCheck()) {
2434             SSL_clear(ssl);
2435             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2436             return 0;
2437         }
2438         // success case
2439         if (ret == 1) {
2440             break;
2441         }
2442         // retry case
2443         if (errno == EINTR) {
2444             continue;
2445         }
2446         // error case
2447         int sslError = SSL_get_error(ssl, ret);
2448         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout=%d",
2449                   ssl, ret, errno, sslError, timeout);
2450
2451         /*
2452          * If SSL_do_handshake doesn't succeed due to the socket being
2453          * either unreadable or unwritable, we use sslSelect to
2454          * wait for it to become ready. If that doesn't happen
2455          * before the specified timeout or an error occurs, we
2456          * cancel the handshake. Otherwise we try the SSL_connect
2457          * again.
2458          */
2459         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
2460             appData->waitingThreads++;
2461             int selectResult = sslSelect(env, sslError, fdObject, appData, timeout);
2462
2463             if (selectResult == THROWN_SOCKETEXCEPTION) {
2464                 // SocketException thrown by NetFd.isClosed
2465                 SSL_clear(ssl);
2466                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2467                 return 0;
2468             }
2469             if (selectResult == -1) {
2470                 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error");
2471                 SSL_clear(ssl);
2472                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2473                 return 0;
2474             }
2475             if (selectResult == 0) {
2476                 throwSocketTimeoutException(env, "SSL handshake timed out");
2477                 SSL_clear(ssl);
2478                 freeSslErrorState();
2479                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2480                 return 0;
2481             }
2482         } else {
2483             // LOGE("Unknown error %d during handshake", error);
2484             break;
2485         }
2486     }
2487
2488     // clean error. See SSL_do_handshake(3SSL) man page.
2489     if (ret == 0) {
2490         /*
2491          * The other side closed the socket before the handshake could be
2492          * completed, but everything is within the bounds of the TLS protocol.
2493          * We still might want to find out the real reason of the failure.
2494          */
2495         int sslError = SSL_get_error(ssl, ret);
2496         if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) {
2497             throwSSLExceptionStr(env, "Connection closed by peer");
2498         } else {
2499             throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated");
2500         }
2501         SSL_clear(ssl);
2502         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2503         return 0;
2504     }
2505
2506     // unclean error. See SSL_do_handshake(3SSL) man page.
2507     if (ret < 0) {
2508         /*
2509          * Translate the error and throw exception. We are sure it is an error
2510          * at this point.
2511          */
2512         int sslError = SSL_get_error(ssl, ret);
2513         throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted");
2514         SSL_clear(ssl);
2515         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
2516         return 0;
2517     }
2518     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
2519     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
2520     return (jint) ssl_session;
2521 }
2522
2523 /**
2524  * Perform SSL renegotiation
2525  */
2526 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jint ssl_address)
2527 {
2528     SSL* ssl = to_SSL(env, ssl_address, true);
2529     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
2530     if (ssl == NULL) {
2531         return;
2532     }
2533     int result = SSL_renegotiate(ssl);
2534     if (result != 1) {
2535         throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
2536         return;
2537     }
2538     int ret = SSL_do_handshake(ssl);
2539     if (ret != 1) {
2540         int sslError = SSL_get_error(ssl, ret);
2541         throwSSLExceptionWithSslErrors(env, ssl, sslError,
2542                                        "Problem with SSL_do_handshake after SSL_renegotiate");
2543
2544         return;
2545     }
2546     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
2547 }
2548
2549 /**
2550  * public static native byte[][] SSL_get_certificate(int ssl);
2551  */
2552 static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jint ssl_address)
2553 {
2554     SSL* ssl = to_SSL(env, ssl_address, true);
2555     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
2556     if (ssl == NULL) {
2557         return NULL;
2558     }
2559     X509* certificate = SSL_get_certificate(ssl);
2560     if (certificate == NULL) {
2561         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
2562         return NULL;
2563     }
2564
2565     Unique_sk_X509 chain(sk_X509_new_null());
2566     if (chain.get() == NULL) {
2567         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
2568         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
2569         return NULL;
2570     }
2571     if (!sk_X509_push(chain.get(), certificate)) {
2572         jniThrowOutOfMemoryError(env, "Unable to push local certificate");
2573         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
2574         return NULL;
2575     }
2576     STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
2577     for (int i=0; i<sk_X509_num(cert_chain); i++) {
2578         if (!sk_X509_push(chain.get(), sk_X509_value(cert_chain, i))) {
2579             jniThrowOutOfMemoryError(env, "Unable to push local certificate chain");
2580             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
2581             return NULL;
2582         }
2583     }
2584
2585     jobjectArray objectArray = getCertificateBytes(env, chain.get());
2586     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray);
2587     return objectArray;
2588 }
2589
2590 // Fills a byte[][] with the peer certificates in the chain.
2591 static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jint ssl_address)
2592 {
2593     SSL* ssl = to_SSL(env, ssl_address, true);
2594     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
2595     if (ssl == NULL) {
2596         return NULL;
2597     }
2598     STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
2599     Unique_sk_X509 chain_copy(NULL);
2600     if (ssl->server) {
2601         X509* x509 = SSL_get_peer_certificate(ssl);
2602         if (x509 == NULL) {
2603             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
2604             return NULL;
2605         }
2606         chain_copy.reset(sk_X509_dup(chain));
2607         if (chain_copy.get() == NULL) {
2608             jniThrowOutOfMemoryError(env, "Unable to allocate peer certificate chain");
2609             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
2610             return NULL;
2611         }
2612         if (!sk_X509_push(chain_copy.get(), x509)) {
2613             jniThrowOutOfMemoryError(env, "Unable to push server's peer certificate");
2614             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
2615             return NULL;
2616         }
2617         chain = chain_copy.get();
2618     }
2619     jobjectArray objectArray = getCertificateBytes(env, chain);
2620     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray);
2621     return objectArray;
2622 }
2623
2624 /**
2625  * Helper function which does the actual reading. The Java layer guarantees that
2626  * at most one thread will enter this function at any given time.
2627  *
2628  * @param ssl non-null; the SSL context
2629  * @param buf non-null; buffer to read into
2630  * @param len length of the buffer, in bytes
2631  * @param sslReturnCode original SSL return code
2632  * @param sslErrorCode filled in with the SSL error code in case of error
2633  * @return number of bytes read on success, -1 if the connection was
2634  * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
2635  */
2636 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
2637                    int* sslReturnCode, int* sslErrorCode, int timeout) {
2638
2639     // LOGD("Entering sslRead, caller requests to read %d bytes...", len);
2640
2641     if (len == 0) {
2642         // Don't bother doing anything in this case.
2643         return 0;
2644     }
2645
2646     BIO* bio = SSL_get_rbio(ssl);
2647
2648     AppData* appData = toAppData(ssl);
2649     if (appData == NULL) {
2650         return THROW_EXCEPTION;
2651     }
2652
2653     while (appData->aliveAndKicking) {
2654         errno = 0;
2655
2656         // Lock
2657         if (MUTEX_LOCK(appData->mutex) == -1) {
2658             return -1;
2659         }
2660
2661         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
2662
2663         // LOGD("Doing SSL_Read()");
2664         if (!appData->setCallbackState(env, shc, fdObject)) {
2665             MUTEX_UNLOCK(appData->mutex);
2666             return THROWN_SOCKETEXCEPTION;
2667         }
2668         int result = SSL_read(ssl, buf, len);
2669         appData->clearCallbackState();
2670         int sslError = SSL_ERROR_NONE;
2671         if (result <= 0) {
2672             sslError = SSL_get_error(ssl, result);
2673             freeSslErrorState();
2674         }
2675         // LOGD("Returned from SSL_Read() with result %d, error code %d", result, sslError);
2676
2677         // If we have been successful in moving data around, check whether it
2678         // might make sense to wake up other blocked threads, so they can give
2679         // it a try, too.
2680         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
2681                 && appData->waitingThreads > 0) {
2682             sslNotify(appData);
2683         }
2684
2685         // If we are blocked by the underlying socket, tell the world that
2686         // there will be one more waiting thread now.
2687         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
2688             appData->waitingThreads++;
2689         }
2690
2691         // Unlock
2692         MUTEX_UNLOCK(appData->mutex);
2693
2694         switch (sslError) {
2695             // Successfully read at least one byte.
2696             case SSL_ERROR_NONE: {
2697                 return result;
2698             }
2699
2700             // Read zero bytes. End of stream reached.
2701             case SSL_ERROR_ZERO_RETURN: {
2702                 return -1;
2703             }
2704
2705             // Need to wait for availability of underlying layer, then retry.
2706             case SSL_ERROR_WANT_READ:
2707             case SSL_ERROR_WANT_WRITE: {
2708                 int selectResult = sslSelect(env, sslError, fdObject, appData, timeout);
2709                 if (selectResult == THROWN_SOCKETEXCEPTION) {
2710                     return THROWN_SOCKETEXCEPTION;
2711                 }
2712                 if (selectResult == -1) {
2713                     *sslReturnCode = -1;
2714                     *sslErrorCode = sslError;
2715                     return THROW_EXCEPTION;
2716                 }
2717                 if (selectResult == 0) {
2718                     return THROW_SOCKETTIMEOUTEXCEPTION;
2719                 }
2720
2721                 break;
2722             }
2723
2724             // A problem occurred during a system call, but this is not
2725             // necessarily an error.
2726             case SSL_ERROR_SYSCALL: {
2727                 // Connection closed without proper shutdown. Tell caller we
2728                 // have reached end-of-stream.
2729                 if (result == 0) {
2730                     return -1;
2731                 }
2732
2733                 // System call has been interrupted. Simply retry.
2734                 if (errno == EINTR) {
2735                     break;
2736                 }
2737
2738                 // Note that for all other system call errors we fall through
2739                 // to the default case, which results in an Exception.
2740             }
2741
2742             // Everything else is basically an error.
2743             default: {
2744                 *sslReturnCode = result;
2745                 *sslErrorCode = sslError;
2746                 return THROW_EXCEPTION;
2747             }
2748         }
2749     }
2750
2751     return -1;
2752 }
2753
2754 /**
2755  * OpenSSL read function (1): only one chunk is read (returned as jint).
2756  */
2757 static jint NativeCrypto_SSL_read_byte(JNIEnv* env, jclass, jint ssl_address,
2758                                        jobject fdObject, jobject shc, jint timeout)
2759 {
2760     SSL* ssl = to_SSL(env, ssl_address, true);
2761     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte fd=%p shc=%p timeout=%d",
2762               ssl, fdObject, shc, timeout);
2763     if (ssl == NULL) {
2764         return 0;
2765     }
2766     if (fdObject == NULL) {
2767         jniThrowNullPointerException(env, "fd == null");
2768         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte => 0", ssl);
2769         return 0;
2770     }
2771     if (shc == NULL) {
2772         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
2773         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte => 0", ssl);
2774         return 0;
2775     }
2776
2777     unsigned char byteRead;
2778     int returnCode = 0;
2779     int sslErrorCode = SSL_ERROR_NONE;
2780
2781     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(&byteRead), 1,
2782                       &returnCode, &sslErrorCode, timeout);
2783
2784     int result;
2785     switch (ret) {
2786         case THROW_EXCEPTION:
2787             // See sslRead() regarding improper failure to handle normal cases.
2788             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
2789             result = -1;
2790             break;
2791         case THROW_SOCKETTIMEOUTEXCEPTION:
2792             throwSocketTimeoutException(env, "Read timed out");
2793             result = -1;
2794             break;
2795         case THROWN_SOCKETEXCEPTION:
2796             // SocketException thrown by NetFd.isClosed
2797             result = -1;
2798             break;
2799         case -1:
2800             // Propagate EOF upwards.
2801             result = -1;
2802             break;
2803         default:
2804             // Return the actual char read, make sure it stays 8 bits wide.
2805             result = ((jint) byteRead) & 0xFF;
2806             break;
2807     }
2808     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte => %d", ssl, result);
2809     return result;
2810 }
2811
2812 /**
2813  * OpenSSL read function (2): read into buffer at offset n chunks.
2814  * Returns 1 (success) or value <= 0 (failure).
2815  */
2816 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
2817                                   jobject shc, jbyteArray b, jint offset, jint len, jint timeout)
2818 {
2819     SSL* ssl = to_SSL(env, ssl_address, true);
2820     JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d timeout=%d",
2821               ssl, fdObject, shc, b, offset, len, timeout);
2822     if (ssl == NULL) {
2823         return 0;
2824     }
2825     if (fdObject == NULL) {
2826         jniThrowNullPointerException(env, "fd == null");
2827         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
2828         return 0;
2829     }
2830     if (shc == NULL) {
2831         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
2832         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
2833         return 0;
2834     }
2835
2836     ScopedByteArrayRW bytes(env, b);
2837     if (bytes.get() == NULL) {
2838         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
2839         return 0;
2840     }
2841     int returnCode = 0;
2842     int sslErrorCode = SSL_ERROR_NONE;;
2843
2844     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
2845                       &returnCode, &sslErrorCode, timeout);
2846
2847     int result;
2848     switch (ret) {
2849         case THROW_EXCEPTION:
2850             // See sslRead() regarding improper failure to handle normal cases.
2851             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
2852             result = -1;
2853             break;
2854         case THROW_SOCKETTIMEOUTEXCEPTION:
2855             throwSocketTimeoutException(env, "Read timed out");
2856             result = -1;
2857             break;
2858         case THROWN_SOCKETEXCEPTION:
2859             // SocketException thrown by NetFd.isClosed
2860             result = -1;
2861             break;
2862         default:
2863             result = ret;
2864             break;
2865     }
2866
2867     JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
2868     return result;
2869 }
2870
2871 /**
2872  * Helper function which does the actual writing. The Java layer guarantees that
2873  * at most one thread will enter this function at any given time.
2874  *
2875  * @param ssl non-null; the SSL context
2876  * @param buf non-null; buffer to write
2877  * @param len length of the buffer, in bytes
2878  * @param sslReturnCode original SSL return code
2879  * @param sslErrorCode filled in with the SSL error code in case of error
2880  * @return number of bytes read on success, -1 if the connection was
2881  * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
2882  */
2883 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
2884                     int* sslReturnCode, int* sslErrorCode) {
2885
2886     // LOGD("Entering sslWrite(), caller requests to write %d bytes...", len);
2887
2888     if (len == 0) {
2889         // Don't bother doing anything in this case.
2890         return 0;
2891     }
2892
2893     BIO* bio = SSL_get_wbio(ssl);
2894
2895     AppData* appData = toAppData(ssl);
2896     if (appData == NULL) {
2897         return THROW_EXCEPTION;
2898     }
2899
2900     int count = len;
2901
2902     while (appData->aliveAndKicking && len > 0) {
2903         errno = 0;
2904         if (MUTEX_LOCK(appData->mutex) == -1) {
2905             return -1;
2906         }
2907
2908         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
2909
2910         // LOGD("Doing SSL_write() with %d bytes to go", len);
2911         if (!appData->setCallbackState(env, shc, fdObject)) {
2912             MUTEX_UNLOCK(appData->mutex);
2913             return THROWN_SOCKETEXCEPTION;
2914         }
2915         int result = SSL_write(ssl, buf, len);
2916         appData->clearCallbackState();
2917         int sslError = SSL_ERROR_NONE;
2918         if (result <= 0) {
2919             sslError = SSL_get_error(ssl, result);
2920             freeSslErrorState();
2921         }
2922         // LOGD("Returned from SSL_write() with result %d, error code %d", result, error);
2923
2924         // If we have been successful in moving data around, check whether it
2925         // might make sense to wake up other blocked threads, so they can give
2926         // it a try, too.
2927         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
2928                 && appData->waitingThreads > 0) {
2929             sslNotify(appData);
2930         }
2931
2932         // If we are blocked by the underlying socket, tell the world that
2933         // there will be one more waiting thread now.
2934         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
2935             appData->waitingThreads++;
2936         }
2937
2938         MUTEX_UNLOCK(appData->mutex);
2939
2940         switch (sslError) {
2941             // Successfully write at least one byte.
2942             case SSL_ERROR_NONE: {
2943                 buf += result;
2944                 len -= result;
2945                 break;
2946             }
2947
2948             // Wrote zero bytes. End of stream reached.
2949             case SSL_ERROR_ZERO_RETURN: {
2950                 return -1;
2951             }
2952
2953             // Need to wait for availability of underlying layer, then retry.
2954             // The concept of a write timeout doesn't really make sense, and
2955             // it's also not standard Java behavior, so we wait forever here.
2956             case SSL_ERROR_WANT_READ:
2957             case SSL_ERROR_WANT_WRITE: {
2958                 int selectResult = sslSelect(env, sslError, fdObject, appData, 0);
2959                 if (selectResult == THROWN_SOCKETEXCEPTION) {
2960                     return THROWN_SOCKETEXCEPTION;
2961                 }
2962                 if (selectResult == -1) {
2963                     *sslReturnCode = -1;
2964                     *sslErrorCode = sslError;
2965                     return THROW_EXCEPTION;
2966                 }
2967                 if (selectResult == 0) {
2968                     return THROW_SOCKETTIMEOUTEXCEPTION;
2969                 }
2970
2971                 break;
2972             }
2973
2974             // An problem occurred during a system call, but this is not
2975             // necessarily an error.
2976             case SSL_ERROR_SYSCALL: {
2977                 // Connection closed without proper shutdown. Tell caller we
2978                 // have reached end-of-stream.
2979                 if (result == 0) {
2980                     return -1;
2981                 }
2982
2983                 // System call has been interrupted. Simply retry.
2984                 if (errno == EINTR) {
2985                     break;
2986                 }
2987
2988                 // Note that for all other system call errors we fall through
2989                 // to the default case, which results in an Exception.
2990             }
2991
2992             // Everything else is basically an error.
2993             default: {
2994                 *sslReturnCode = result;
2995                 *sslErrorCode = sslError;
2996                 return THROW_EXCEPTION;
2997             }
2998         }
2999     }
3000     // LOGD("Successfully wrote %d bytes", count);
3001
3002     return count;
3003 }
3004
3005 /**
3006  * OpenSSL write function (1): only one chunk is written.
3007  */
3008 static void NativeCrypto_SSL_write_byte(JNIEnv* env, jclass, jint ssl_address,
3009                                         jobject fdObject, jobject shc, jint b)
3010 {
3011     SSL* ssl = to_SSL(env, ssl_address, true);
3012     JNI_TRACE("ssl=%p NativeCrypto_SSL_write_byte fd=%p shc=%p b=%d", ssl, fdObject, shc, b);
3013     if (ssl == NULL) {
3014         return;
3015     }
3016     if (fdObject == NULL) {
3017         jniThrowNullPointerException(env, "fd == null");
3018         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_byte => fd == null", ssl);
3019         return;
3020     }
3021     if (shc == NULL) {
3022         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
3023         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_byte => sslHandshakeCallbacks == null", ssl);
3024         return;
3025     }
3026
3027     int returnCode = 0;
3028     int sslErrorCode = SSL_ERROR_NONE;
3029     char buf[1] = { (char) b };
3030     int ret = sslWrite(env, ssl, fdObject, shc, buf, 1, &returnCode, &sslErrorCode);
3031
3032     switch (ret) {
3033         case THROW_EXCEPTION:
3034             // See sslWrite() regarding improper failure to handle normal cases.
3035             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
3036             break;
3037         case THROW_SOCKETTIMEOUTEXCEPTION:
3038             throwSocketTimeoutException(env, "Write timed out");
3039             break;
3040         case THROWN_SOCKETEXCEPTION:
3041             // SocketException thrown by NetFd.isClosed
3042             break;
3043         default:
3044             break;
3045     }
3046 }
3047
3048 /**
3049  * OpenSSL write function (2): write into buffer at offset n chunks.
3050  */
3051 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
3052                                    jobject shc, jbyteArray b, jint offset, jint len)
3053 {
3054     SSL* ssl = to_SSL(env, ssl_address, true);
3055     JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d",
3056               ssl, fdObject, shc, b, offset, len);
3057     if (ssl == NULL) {
3058         return;
3059     }
3060     if (fdObject == NULL) {
3061         jniThrowNullPointerException(env, "fd == null");
3062         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
3063         return;
3064     }
3065     if (shc == NULL) {
3066         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
3067         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
3068         return;
3069     }
3070
3071     ScopedByteArrayRO bytes(env, b);
3072     if (bytes.get() == NULL) {
3073         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
3074         return;
3075     }
3076     int returnCode = 0;
3077     int sslErrorCode = SSL_ERROR_NONE;
3078     int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
3079                        len, &returnCode, &sslErrorCode);
3080
3081     switch (ret) {
3082         case THROW_EXCEPTION:
3083             // See sslWrite() regarding improper failure to handle normal cases.
3084             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
3085             break;
3086         case THROW_SOCKETTIMEOUTEXCEPTION:
3087             throwSocketTimeoutException(env, "Write timed out");
3088             break;
3089         case THROWN_SOCKETEXCEPTION:
3090             // SocketException thrown by NetFd.isClosed
3091             break;
3092         default:
3093             break;
3094     }
3095 }
3096
3097 /**
3098  * Interrupt any pending IO before closing the socket.
3099  */
3100 static void NativeCrypto_SSL_interrupt(
3101         JNIEnv* env, jclass, jint ssl_address) {
3102     SSL* ssl = to_SSL(env, ssl_address, false);
3103     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
3104     if (ssl == NULL) {
3105         return;
3106     }
3107
3108     /*
3109      * Mark the connection as quasi-dead, then send something to the emergency
3110      * file descriptor, so any blocking select() calls are woken up.
3111      */
3112     AppData* appData = toAppData(ssl);
3113     if (appData != NULL) {
3114         appData->aliveAndKicking = 0;
3115
3116         // At most two threads can be waiting.
3117         sslNotify(appData);
3118         sslNotify(appData);
3119     }
3120 }
3121
3122 /**
3123  * OpenSSL close SSL socket function.
3124  */
3125 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jint ssl_address,
3126                                       jobject fdObject, jobject shc) {
3127     SSL* ssl = to_SSL(env, ssl_address, false);
3128     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
3129     if (ssl == NULL) {
3130         return;
3131     }
3132     if (fdObject == NULL) {
3133         jniThrowNullPointerException(env, "fd == null");
3134         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
3135         return;
3136     }
3137     if (shc == NULL) {
3138         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
3139         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
3140         return;
3141     }
3142
3143     AppData* appData = toAppData(ssl);
3144     if (appData != NULL) {
3145         if (!appData->setCallbackState(env, shc, fdObject)) {
3146             // SocketException thrown by NetFd.isClosed
3147             SSL_clear(ssl);
3148             freeSslErrorState();
3149             return;
3150         }
3151
3152         /*
3153          * Try to make socket blocking again. OpenSSL literature recommends this.
3154          */
3155         int fd = SSL_get_fd(ssl);
3156         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
3157         if (fd != -1) {
3158             setBlocking(fd, true);
3159         }
3160
3161         int ret = SSL_shutdown(ssl);
3162         switch (ret) {
3163             case 0:
3164                 /*
3165                  * Shutdown was not successful (yet), but there also
3166                  * is no error. Since we can't know whether the remote
3167                  * server is actually still there, and we don't want to
3168                  * get stuck forever in a second SSL_shutdown() call, we
3169                  * simply return. This is not security a problem as long
3170                  * as we close the underlying socket, which we actually
3171                  * do, because that's where we are just coming from.
3172                  */
3173                 break;
3174             case 1:
3175                 /*
3176                  * Shutdown was successful. We can safely return. Hooray!
3177                  */
3178                 break;
3179             default:
3180                 /*
3181                  * Everything else is a real error condition. We should
3182                  * let the Java layer know about this by throwing an
3183                  * exception.
3184                  */
3185                 int sslError = SSL_get_error(ssl, ret);
3186                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
3187                 break;
3188         }
3189         appData->clearCallbackState();
3190     }
3191
3192     SSL_clear(ssl);
3193     freeSslErrorState();
3194 }
3195
3196 /**
3197  * public static native void SSL_free(int ssl);
3198  */
3199 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jint ssl_address)
3200 {
3201     SSL* ssl = to_SSL(env, ssl_address, true);
3202     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
3203     if (ssl == NULL) {
3204         return;
3205     }
3206
3207     AppData* appData = toAppData(ssl);
3208     SSL_set_app_data(ssl, NULL);
3209     delete appData;
3210     SSL_free(ssl);
3211 }
3212
3213 /**
3214  * Gets and returns in a byte array the ID of the actual SSL session.
3215  */
3216 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
3217                                                       jint ssl_session_address) {
3218     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3219     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
3220     if (ssl_session == NULL) {
3221         return NULL;
3222     }
3223     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
3224     if (result != NULL) {
3225         jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
3226         env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
3227     }
3228     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
3229              ssl_session, result, ssl_session->session_id_length);
3230     return result;
3231 }
3232
3233 /**
3234  * Gets and returns in a long integer the creation's time of the
3235  * actual SSL session.
3236  */
3237 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jint ssl_session_address) {
3238     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3239     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
3240     if (ssl_session == NULL) {
3241         return 0;
3242     }
3243     // result must be jlong, not long or *1000 will overflow
3244     jlong result = SSL_SESSION_get_time(ssl_session);
3245     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
3246     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
3247     return result;
3248 }
3249
3250 /**
3251  * Our implementation of what might be considered
3252  * SSL_SESSION_get_version, based on SSL_get_version.
3253  * See get_ssl_version above.
3254  */
3255 // TODO move to jsse.patch
3256 static const char* SSL_SESSION_get_version(SSL_SESSION* ssl_session) {
3257   return get_ssl_version(ssl_session->ssl_version);
3258 }
3259
3260 /**
3261  * Gets and returns in a string the version of the SSL protocol. If it
3262  * returns the string "unknown" it means that no connection is established.
3263  */
3264 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jint ssl_session_address) {
3265     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3266     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
3267     if (ssl_session == NULL) {
3268         return NULL;
3269     }
3270     const char* protocol = SSL_SESSION_get_version(ssl_session);
3271     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
3272     return env->NewStringUTF(protocol);
3273 }
3274
3275 /**
3276  * Gets and returns in a string the cipher negotiated for the SSL session.
3277  */
3278 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jint ssl_session_address) {
3279     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3280     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
3281     if (ssl_session == NULL) {
3282         return NULL;
3283     }
3284     const SSL_CIPHER* cipher = ssl_session->cipher;
3285     const char* name = SSL_CIPHER_get_name(cipher);
3286     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
3287     return env->NewStringUTF(name);
3288 }
3289
3290 /**
3291  * Gets and returns in a string the compression method negotiated for the SSL session.
3292  */
3293 static jstring NativeCrypto_SSL_SESSION_compress_meth(JNIEnv* env, jclass,
3294                                                       jint ssl_ctx_address,
3295                                                       jint ssl_session_address) {
3296     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
3297     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3298     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth ssl_ctx=%p",
3299               ssl_session, ssl_ctx);
3300     if (ssl_ctx == NULL || ssl_session == NULL) {
3301         return NULL;
3302     }
3303
3304     int compress_meth = ssl_session->compress_meth;
3305     if (compress_meth == 0) {
3306         const char* name = "NULL";
3307         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
3308         return env->NewStringUTF(name);
3309     }
3310
3311     int num_comp_methods = sk_SSL_COMP_num(ssl_ctx->comp_methods);
3312     for (int i = 0; i < num_comp_methods; i++) {
3313         SSL_COMP* comp = sk_SSL_COMP_value(ssl_ctx->comp_methods, i);
3314         if (comp->id != compress_meth) {
3315             continue;
3316         }
3317         const char* name = ((comp->method && comp->method->type == NID_zlib_compression)
3318                             ? SN_zlib_compression
3319                             : (comp->name ? comp->name : "UNKNOWN"));
3320         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
3321         return env->NewStringUTF(name);
3322     }
3323     throwSSLExceptionStr(env, "Unknown compression method");
3324     return NULL;
3325 }
3326
3327 /**
3328  * Frees the SSL session.
3329  */
3330 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jint ssl_session_address) {
3331     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3332     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
3333     if (ssl_session == NULL) {
3334         return;
3335     }
3336     SSL_SESSION_free(ssl_session);
3337 }
3338
3339
3340 /**
3341  * Serializes the native state of the session (ID, cipher, and keys but
3342  * not certificates). Returns a byte[] containing the DER-encoded state.
3343  * See apache mod_ssl.
3344  */
3345 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jint ssl_session_address) {
3346     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
3347     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
3348     if (ssl_session == NULL) {
3349         return NULL;
3350     }
3351
3352     // Compute the size of the DER data
3353     int size = i2d_SSL_SESSION(ssl_session, NULL);
3354     if (size == 0) {
3355         JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => NULL", ssl_session);
3356         return NULL;
3357     }
3358
3359     jbyteArray javaBytes = env->NewByteArray(size);
3360     if (javaBytes != NULL) {
3361         ScopedByteArrayRW bytes(env, javaBytes);
3362         if (bytes.get() == NULL) {
3363             JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => threw exception",
3364                       ssl_session);
3365             return NULL;
3366         }
3367         unsigned char* ucp = reinterpret_cast<unsigned char*>(bytes.get());
3368         i2d_SSL_SESSION(ssl_session, &ucp);
3369     }
3370
3371     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => size=%d", ssl_session, size);
3372     return javaBytes;
3373 }
3374
3375 /**
3376  * Deserialize the session.
3377  */
3378 static jint NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
3379     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
3380
3381     ScopedByteArrayRO bytes(env, javaBytes);
3382     if (bytes.get() == NULL) {
3383         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
3384         return 0;
3385     }
3386     const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
3387     SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
3388
3389     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
3390     return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
3391 }
3392
3393 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
3394 #define SSL_CALLBACKS "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto$SSLHandshakeCallbacks;"
3395 static JNINativeMethod sNativeCryptoMethods[] = {
3396     NATIVE_METHOD(NativeCrypto, clinit, "()V"),
3397     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)I"),
3398     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B)I"),
3399     NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"),
3400     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()I"),
3401     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(I)V"),
3402     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(I)I"),
3403     NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(I[BI)I"),
3404     NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(ILjava/lang/String;)V"),
3405     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_block_size, "(I)I"),
3406     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_size, "(I)I"),
3407     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(I[BII)V"),
3408     NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(ILjava/lang/String;)V"),
3409     NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(I[BII)V"),
3410     NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(I[BIII)I"),
3411     NATIVE_METHOD(NativeCrypto, verifySignature, "([B[BLjava/lang/String;[B[B)I"),
3412     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
3413     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
3414     NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()I"),
3415     NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(I)V"),
3416     NATIVE_METHOD(NativeCrypto, SSL_new, "(I)I"),
3417     NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(I[B)V"),
3418     NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(I[[B)V"),
3419     NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(I)V"),
3420     NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(I[[B)V"),
3421     NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(I)J"),
3422     NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(IJ)J"),
3423     NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(IJ)J"),
3424     NATIVE_METHOD(NativeCrypto, SSL_get_options, "(I)J"),
3425     NATIVE_METHOD(NativeCrypto, SSL_set_options, "(IJ)J"),
3426     NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(IJ)J"),
3427     NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(I[Ljava/lang/String;)V"),
3428     NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(II)V"),
3429     NATIVE_METHOD(NativeCrypto, SSL_set_session, "(II)V"),
3430     NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(IZ)V"),
3431     NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(ILjava/lang/String;)V"),
3432     NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(I)Ljava/lang/String;"),
3433     NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "IZ)I"),
3434     NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(I)V"),
3435     NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(I)[[B"),
3436     NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(I)[[B"),
3437     NATIVE_METHOD(NativeCrypto, SSL_read_byte, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "I)I"),
3438     NATIVE_METHOD(NativeCrypto, SSL_read, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
3439     NATIVE_METHOD(NativeCrypto, SSL_write_byte, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "I)V"),
3440     NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BII)V"),
3441     NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(I)V"),
3442     NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(I" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
3443     NATIVE_METHOD(NativeCrypto, SSL_free, "(I)V"),
3444     NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(I)[B"),
3445     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(I)J"),
3446     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(I)Ljava/lang/String;"),
3447     NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(I)Ljava/lang/String;"),
3448     NATIVE_METHOD(NativeCrypto, SSL_SESSION_compress_meth, "(II)Ljava/lang/String;"),
3449     NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(I)V"),
3450     NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(I)[B"),
3451     NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)I"),
3452 };
3453
3454 int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
3455     JNI_TRACE("register_org_apache_harmony_xnet_provider_jsse_NativeCrypto");
3456     // Register org.apache.harmony.xnet.provider.jsse.NativeCrypto methods
3457     return jniRegisterNativeMethods(env,
3458                                     "org/apache/harmony/xnet/provider/jsse/NativeCrypto",
3459                                     sNativeCryptoMethods,
3460                                     NELEM(sNativeCryptoMethods));
3461 }