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 <JNIHelp.h>
30#include <LocalArray.h>
31
32#include <openssl/dsa.h>
33#include <openssl/err.h>
34#include <openssl/evp.h>
35#include <openssl/rand.h>
36#include <openssl/rsa.h>
37#include <openssl/ssl.h>
38
39/**
40 * Structure to hold JNI state for openssl callback
41 */
42struct jsse_ssl_app_data_t {
43    JNIEnv* env;
44    jobject object;
45};
46
47/**
48 * Frees the SSL error state.
49 *
50 * OpenSSL keeps an "error stack" per thread, and given that this code
51 * can be called from arbitrary threads that we don't keep track of,
52 * we err on the side of freeing the error state promptly (instead of,
53 * say, at thread death).
54 */
55static void freeSslErrorState(void) {
56    ERR_clear_error();
57    ERR_remove_state(0);
58}
59
60/*
61 * Checks this thread's OpenSSL error queue and throws a RuntimeException if
62 * necessary.
63 *
64 * @return 1 if an exception was thrown, 0 if not.
65 */
66static int throwExceptionIfNecessary(JNIEnv* env) {
67    int error = ERR_get_error();
68    int result = 0;
69
70    if (error != 0) {
71        char message[50];
72        ERR_error_string_n(error, message, sizeof(message));
73        LOGD("OpenSSL error %d: %s", error, message);
74        jniThrowRuntimeException(env, message);
75        result = 1;
76    }
77
78    freeSslErrorState();
79    return result;
80}
81
82/**
83 * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
84 * fly.
85 */
86static BIGNUM* arrayToBignum(JNIEnv* env, jbyteArray source) {
87    // LOGD("Entering arrayToBignum()");
88
89    jbyte* sourceBytes = env->GetByteArrayElements(source, NULL);
90    int sourceLength = env->GetArrayLength(source);
91    BIGNUM* bignum = BN_bin2bn((unsigned char*) sourceBytes, sourceLength, NULL);
92    env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
93    return bignum;
94}
95
96/**
97 * private static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g, byte[] pub_key, byte[] priv_key);
98 */
99static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass clazz, jbyteArray p, jbyteArray q, jbyteArray g, jbyteArray pub_key, jbyteArray priv_key) {
100    // LOGD("Entering EVP_PKEY_new_DSA()");
101
102    DSA* dsa = DSA_new();
103
104    dsa->p = arrayToBignum(env, p);
105    dsa->q = arrayToBignum(env, q);
106    dsa->g = arrayToBignum(env, g);
107    dsa->pub_key = arrayToBignum(env, pub_key);
108
109    if (priv_key != NULL) {
110        dsa->priv_key = arrayToBignum(env, priv_key);
111    }
112
113    if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) {
114        DSA_free(dsa);
115        jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
116        return NULL;
117    }
118
119    EVP_PKEY* pkey = EVP_PKEY_new();
120    EVP_PKEY_assign_DSA(pkey, dsa);
121
122    return pkey;
123}
124
125/**
126 * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
127 */
128static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass clazz, jbyteArray n, jbyteArray e, jbyteArray d, jbyteArray p, jbyteArray q) {
129    // LOGD("Entering EVP_PKEY_new_RSA()");
130
131    RSA* rsa = RSA_new();
132
133    rsa->n = arrayToBignum(env, n);
134    rsa->e = arrayToBignum(env, e);
135
136    if (d != NULL) {
137        rsa->d = arrayToBignum(env, d);
138    }
139
140    if (p != NULL) {
141        rsa->p = arrayToBignum(env, p);
142    }
143
144    if (q != NULL) {
145        rsa->q = arrayToBignum(env, q);
146    }
147
148    // int check = RSA_check_key(rsa);
149    // LOGI("RSA_check_key returns %d", check);
150
151    if (rsa->n == NULL || rsa->e == NULL) {
152        RSA_free(rsa);
153        jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
154        return NULL;
155    }
156
157    EVP_PKEY* pkey = EVP_PKEY_new();
158    EVP_PKEY_assign_RSA(pkey, rsa);
159
160    return pkey;
161}
162
163/**
164 * private static native void EVP_PKEY_free(int pkey);
165 */
166static void NativeCrypto_EVP_PKEY_free(JNIEnv* env, jclass clazz, EVP_PKEY* pkey) {
167    // LOGD("Entering EVP_PKEY_free()");
168
169    if (pkey != NULL) {
170        EVP_PKEY_free(pkey);
171    }
172}
173
174/*
175 * public static native int EVP_new()
176 */
177static jint NativeCrypto_EVP_new(JNIEnv* env, jclass clazz) {
178    // LOGI("NativeCrypto_EVP_DigestNew");
179
180    return (jint)EVP_MD_CTX_create();
181}
182
183/*
184 * public static native void EVP_free(int)
185 */
186static void NativeCrypto_EVP_free(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
187    // LOGI("NativeCrypto_EVP_DigestFree");
188
189    if (ctx != NULL) {
190        EVP_MD_CTX_destroy(ctx);
191    }
192}
193
194/*
195 * public static native int EVP_DigestFinal(int, byte[], int)
196 */
197static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray hash, jint offset) {
198    // LOGI("NativeCrypto_EVP_DigestFinal%x, %x, %d, %d", ctx, hash, offset);
199
200    if (ctx == NULL || hash == NULL) {
201        jniThrowNullPointerException(env, NULL);
202        return -1;
203    }
204
205    int result = -1;
206
207    jbyte* hashBytes = env->GetByteArrayElements(hash, NULL);
208    EVP_DigestFinal(ctx, (unsigned char*) (hashBytes + offset), (unsigned int*)&result);
209    env->ReleaseByteArrayElements(hash, hashBytes, 0);
210
211    throwExceptionIfNecessary(env);
212
213    return result;
214}
215
216/*
217 * public static native void EVP_DigestInit(int, java.lang.String)
218 */
219static void NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
220    // LOGI("NativeCrypto_EVP_DigestInit");
221
222    if (ctx == NULL || algorithm == NULL) {
223        jniThrowNullPointerException(env, NULL);
224        return;
225    }
226
227    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
228
229    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
230    env->ReleaseStringUTFChars(algorithm, algorithmChars);
231
232    if (digest == NULL) {
233        jniThrowRuntimeException(env, "Hash algorithm not found");
234        return;
235    }
236
237    EVP_DigestInit(ctx, digest);
238
239    throwExceptionIfNecessary(env);
240}
241
242/*
243 * public static native void EVP_DigestSize(int)
244 */
245static jint NativeCrypto_EVP_DigestSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
246    // LOGI("NativeCrypto_EVP_DigestSize");
247
248    if (ctx == NULL) {
249        jniThrowNullPointerException(env, NULL);
250        return -1;
251    }
252
253    int result = EVP_MD_CTX_size(ctx);
254
255    throwExceptionIfNecessary(env);
256
257    return result;
258}
259
260/*
261 * public static native void EVP_DigestBlockSize(int)
262 */
263static jint NativeCrypto_EVP_DigestBlockSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
264    // LOGI("NativeCrypto_EVP_DigestBlockSize");
265
266    if (ctx == NULL) {
267        jniThrowNullPointerException(env, NULL);
268        return -1;
269    }
270
271    int result = EVP_MD_CTX_block_size(ctx);
272
273    throwExceptionIfNecessary(env);
274
275    return result;
276}
277
278/*
279 * public static native void EVP_DigestUpdate(int, byte[], int, int)
280 */
281static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) {
282    // LOGI("NativeCrypto_EVP_DigestUpdate %x, %x, %d, %d", ctx, buffer, offset, length);
283
284    if (ctx == NULL || buffer == NULL) {
285        jniThrowNullPointerException(env, NULL);
286        return;
287    }
288
289    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
290    EVP_DigestUpdate(ctx, (unsigned char*) (bufferBytes + offset), length);
291    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
292
293    throwExceptionIfNecessary(env);
294}
295
296/*
297 * public static native void EVP_VerifyInit(int, java.lang.String)
298 */
299static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
300    // LOGI("NativeCrypto_EVP_VerifyInit");
301
302    if (ctx == NULL || algorithm == NULL) {
303        jniThrowNullPointerException(env, NULL);
304        return;
305    }
306
307    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
308
309    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
310    env->ReleaseStringUTFChars(algorithm, algorithmChars);
311
312    if (digest == NULL) {
313        jniThrowRuntimeException(env, "Hash algorithm not found");
314        return;
315    }
316
317    EVP_VerifyInit(ctx, digest);
318
319    throwExceptionIfNecessary(env);
320}
321
322/*
323 * public static native void EVP_VerifyUpdate(int, byte[], int, int)
324 */
325static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) {
326    // LOGI("NativeCrypto_EVP_VerifyUpdate %x, %x, %d, %d", ctx, buffer, offset, length);
327
328    if (ctx == NULL || buffer == NULL) {
329        jniThrowNullPointerException(env, NULL);
330        return;
331    }
332
333    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
334    EVP_VerifyUpdate(ctx, (unsigned char*) (bufferBytes + offset), length);
335    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
336
337    throwExceptionIfNecessary(env);
338}
339
340/*
341 * public static native void EVP_VerifyFinal(int, byte[], int, int, int)
342 */
343static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length, EVP_PKEY* pkey) {
344    // LOGI("NativeCrypto_EVP_VerifyFinal %x, %x, %d, %d %x", ctx, buffer, offset, length, pkey);
345
346    if (ctx == NULL || buffer == NULL || pkey == NULL) {
347        jniThrowNullPointerException(env, NULL);
348        return -1;
349    }
350
351    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
352    int result = EVP_VerifyFinal(ctx, (unsigned char*) (bufferBytes + offset), length, pkey);
353    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
354
355    throwExceptionIfNecessary(env);
356
357    return result;
358}
359
360/*
361 * Defines the mapping from Java methods and their signatures
362 * to native functions. Order is (1) Java name, (2) signature,
363 * (3) pointer to C function.
364 */
365static JNINativeMethod sNativeCryptoMethods[] = {
366    { "EVP_PKEY_new_DSA",    "([B[B[B[B[B)I", (void*)NativeCrypto_EVP_PKEY_new_DSA },
367    { "EVP_PKEY_new_RSA",    "([B[B[B[B[B)I", (void*)NativeCrypto_EVP_PKEY_new_RSA },
368    { "EVP_PKEY_free",       "(I)V",          (void*)NativeCrypto_EVP_PKEY_free },
369    { "EVP_new",             "()I",           (void*)NativeCrypto_EVP_new },
370    { "EVP_free",            "(I)V",          (void*)NativeCrypto_EVP_free },
371    { "EVP_DigestFinal",     "(I[BI)I",       (void*)NativeCrypto_EVP_DigestFinal },
372    { "EVP_DigestInit",      "(ILjava/lang/String;)V", (void*)NativeCrypto_EVP_DigestInit },
373    { "EVP_DigestBlockSize", "(I)I",          (void*)NativeCrypto_EVP_DigestBlockSize },
374    { "EVP_DigestSize",      "(I)I",          (void*)NativeCrypto_EVP_DigestSize },
375    { "EVP_DigestUpdate",    "(I[BII)V",      (void*)NativeCrypto_EVP_DigestUpdate },
376    { "EVP_VerifyInit",      "(ILjava/lang/String;)V", (void*)NativeCrypto_EVP_VerifyInit },
377    { "EVP_VerifyUpdate",    "(I[BII)V",      (void*)NativeCrypto_EVP_VerifyUpdate },
378    { "EVP_VerifyFinal",     "(I[BIII)I",     (void*)NativeCrypto_EVP_VerifyFinal }
379};
380
381/**
382 * Module scope variables initialized during JNI registration.
383 */
384static jfieldID field_Socket_ssl_ctx;
385static jfieldID field_Socket_ssl;
386static jfieldID field_FileDescriptor_descriptor;
387static jfieldID field_Socket_mImpl;
388static jfieldID field_Socket_mFD;
389static jfieldID field_Socket_timeout;
390
391/**
392 * Gets the chars of a String object as a '\0'-terminated UTF-8 string,
393 * stored in a freshly-allocated BIO memory buffer.
394 */
395static BIO *stringToMemBuf(JNIEnv* env, jstring string) {
396    jsize byteCount = env->GetStringUTFLength(string);
397    LocalArray<1024> buf(byteCount + 1);
398    env->GetStringUTFRegion(string, 0, env->GetStringLength(string), &buf[0]);
399
400    BIO* result = BIO_new(BIO_s_mem());
401    BIO_puts(result, &buf[0]);
402    return result;
403}
404
405/**
406 * Throws an SocketTimeoutException with the given string as a message.
407 */
408static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
409    if (jniThrowException(env, "java/net/SocketTimeoutException", message)) {
410        LOGE("Unable to throw");
411    }
412}
413
414/**
415 * Throws a java.io.IOException with the given string as a message.
416 */
417static void throwIOExceptionStr(JNIEnv* env, const char* message) {
418    if (jniThrowException(env, "java/io/IOException", message)) {
419        LOGE("Unable to throw");
420    }
421}
422
423/**
424 * Throws an IOException with a message constructed from the current
425 * SSL errors. This will also log the errors.
426 *
427 * @param env the JNI environment
428 * @param sslReturnCode return code from failing SSL function
429 * @param sslErrorCode error code returned from SSL_get_error()
430 * @param message null-ok; general error message
431 */
432static void throwIOExceptionWithSslErrors(JNIEnv* env, int sslReturnCode,
433        int sslErrorCode, const char* message) {
434    const char* messageStr = NULL;
435    char* str;
436    int ret;
437
438    // First consult the SSL error code for the general message.
439    switch (sslErrorCode) {
440        case SSL_ERROR_NONE:
441            messageStr = "Ok";
442            break;
443        case SSL_ERROR_SSL:
444            messageStr = "Failure in SSL library, usually a protocol error";
445            break;
446        case SSL_ERROR_WANT_READ:
447            messageStr = "SSL_ERROR_WANT_READ occured. You should never see this.";
448            break;
449        case SSL_ERROR_WANT_WRITE:
450            messageStr = "SSL_ERROR_WANT_WRITE occured. You should never see this.";
451            break;
452        case SSL_ERROR_WANT_X509_LOOKUP:
453            messageStr = "SSL_ERROR_WANT_X509_LOOKUP occured. You should never see this.";
454            break;
455        case SSL_ERROR_SYSCALL:
456            messageStr = "I/O error during system call";
457            break;
458        case SSL_ERROR_ZERO_RETURN:
459            messageStr = "SSL_ERROR_ZERO_RETURN occured. You should never see this.";
460            break;
461        case SSL_ERROR_WANT_CONNECT:
462            messageStr = "SSL_ERROR_WANT_CONNECT occured. You should never see this.";
463            break;
464        case SSL_ERROR_WANT_ACCEPT:
465            messageStr = "SSL_ERROR_WANT_ACCEPT occured. You should never see this.";
466            break;
467        default:
468            messageStr = "Unknown SSL error";
469    }
470
471    // Prepend either our explicit message or a default one.
472    if (asprintf(&str, "%s: %s",
473            (message != NULL) ? message : "SSL error", messageStr) == 0) {
474        throwIOExceptionStr(env, messageStr);
475        LOGV("%s", messageStr);
476        freeSslErrorState();
477        return;
478    }
479
480    char* allocStr = str;
481
482    // For SSL protocol errors, SSL might have more information.
483    if (sslErrorCode == SSL_ERROR_SSL) {
484        // Append each error as an additional line to the message.
485        for (;;) {
486            char errStr[256];
487            const char* file;
488            int line;
489            const char* data;
490            int flags;
491            unsigned long err =
492                ERR_get_error_line_data(&file, &line, &data, &flags);
493            if (err == 0) {
494                break;
495            }
496
497            ERR_error_string_n(err, errStr, sizeof(errStr));
498
499            ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
500                    (allocStr == NULL) ? "" : allocStr,
501                    errStr,
502                    file,
503                    line,
504                    data,
505                    flags);
506
507            if (ret < 0) {
508                break;
509            }
510
511            free(allocStr);
512            allocStr = str;
513        }
514    // For errors during system calls, errno might be our friend.
515    } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
516        if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
517            free(allocStr);
518            allocStr = str;
519        }
520    // If the error code is invalid, print it.
521    } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
522        if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
523            free(allocStr);
524            allocStr = str;
525        }
526    }
527
528    throwIOExceptionStr(env, allocStr);
529
530    LOGV("%s", allocStr);
531    free(allocStr);
532    freeSslErrorState();
533}
534
535/**
536 * Helper function that grabs the ssl pointer out of the given object.
537 * If this function returns NULL and <code>throwIfNull</code> is
538 * passed as <code>true</code>, then this function will call
539 * <code>throwIOExceptionStr</code> before returning, so in this case of
540 * NULL, a caller of this function should simply return and allow JNI
541 * to do its thing.
542 *
543 * @param env non-null; the JNI environment
544 * @param obj non-null; socket object
545 * @param throwIfNull whether to throw if the SSL pointer is NULL
546 * @returns the pointer, which may be NULL
547 */
548static SSL *getSslPointer(JNIEnv* env, jobject obj, bool throwIfNull) {
549    SSL *ssl = (SSL *)env->GetIntField(obj, field_Socket_ssl);
550
551    if ((ssl == NULL) && throwIfNull) {
552        throwIOExceptionStr(env, "null SSL pointer");
553    }
554
555    return ssl;
556}
557
558// ============================================================================
559// === OpenSSL-related helper stuff begins here. ==============================
560// ============================================================================
561
562/**
563 * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
564 * suppose there are not many other ways to do this on a Linux system (modulo
565 * isomorphism).
566 */
567#define MUTEX_TYPE pthread_mutex_t
568#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
569#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
570#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
571#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
572#define THREAD_ID pthread_self()
573#define THROW_EXCEPTION (-2)
574#define THROW_SOCKETTIMEOUTEXCEPTION (-3)
575
576static MUTEX_TYPE *mutex_buf = NULL;
577
578static void locking_function(int mode, int n, const char * file, int line) {
579    if (mode & CRYPTO_LOCK) {
580        MUTEX_LOCK(mutex_buf[n]);
581    } else {
582        MUTEX_UNLOCK(mutex_buf[n]);
583    }
584}
585
586static unsigned long id_function(void) {
587    return ((unsigned long)THREAD_ID);
588}
589
590int THREAD_setup(void) {
591    int i;
592
593    mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE));
594
595    if(!mutex_buf) {
596        return 0;
597    }
598
599    for (i = 0; i < CRYPTO_num_locks( ); i++) {
600        MUTEX_SETUP(mutex_buf[i]);
601    }
602
603    CRYPTO_set_id_callback(id_function);
604    CRYPTO_set_locking_callback(locking_function);
605
606    return 1;
607}
608
609int THREAD_cleanup(void) {
610    int i;
611
612    if (!mutex_buf) {
613      return 0;
614    }
615
616    CRYPTO_set_id_callback(NULL);
617    CRYPTO_set_locking_callback(NULL);
618
619    for (i = 0; i < CRYPTO_num_locks( ); i++) {
620        MUTEX_CLEANUP(mutex_buf[i]);
621    }
622
623    free(mutex_buf);
624    mutex_buf = NULL;
625
626    return 1;
627}
628
629int get_socket_timeout(int type, int sd) {
630    struct timeval tv;
631    socklen_t len = sizeof(tv);
632    if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
633         LOGE("getsockopt(%d, SOL_SOCKET): %s (%d)",
634              sd,
635              strerror(errno),
636              errno);
637        return 0;
638    }
639    // LOGI("Current socket timeout (%d(s), %d(us))!",
640    //      (int)tv.tv_sec, (int)tv.tv_usec);
641    int timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
642    return timeout;
643}
644
645#ifdef TIMEOUT_DEBUG_SSL
646
647void print_socket_timeout(const char* name, int type, int sd) {
648    struct timeval tv;
649    int len = sizeof(tv);
650    if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
651         LOGE("getsockopt(%d, SOL_SOCKET, %s): %s (%d)",
652              sd,
653              name,
654              strerror(errno),
655              errno);
656    }
657    LOGI("Current socket %s is (%d(s), %d(us))!",
658          name, (int)tv.tv_sec, (int)tv.tv_usec);
659}
660
661void print_timeout(const char* method, SSL* ssl) {
662    LOGI("SSL_get_default_timeout %d in %s", SSL_get_default_timeout(ssl), method);
663    int fd = SSL_get_fd(ssl);
664    print_socket_timeout("SO_RCVTIMEO", SO_RCVTIMEO, fd);
665    print_socket_timeout("SO_SNDTIMEO", SO_SNDTIMEO, fd);
666}
667
668#endif
669
670/**
671 * Our additional application data needed for getting synchronization right.
672 * This maybe warrants a bit of lengthy prose:
673 *
674 * (1) We use a flag to reflect whether we consider the SSL connection alive.
675 * Any read or write attempt loops will be cancelled once this flag becomes 0.
676 *
677 * (2) We use an int to count the number of threads that are blocked by the
678 * underlying socket. This may be at most two (one reader and one writer), since
679 * the Java layer ensures that no more threads will enter the native code at the
680 * same time.
681 *
682 * (3) The pipe is used primarily as a means of cancelling a blocking select()
683 * when we want to close the connection (aka "emergency button"). It is also
684 * necessary for dealing with a possible race condition situation: There might
685 * be cases where both threads see an SSL_ERROR_WANT_READ or
686 * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
687 * If one leaves the select() successfully before the other enters it, the
688 * "success" event is already consumed and the second thread will be blocked,
689 * possibly forever (depending on network conditions).
690 *
691 * The idea for solving the problem looks like this: Whenever a thread is
692 * successful in moving around data on the network, and it knows there is
693 * another thread stuck in a select(), it will write a byte to the pipe, waking
694 * up the other thread. A thread that returned from select(), on the other hand,
695 * knows whether it's been woken up by the pipe. If so, it will consume the
696 * byte, and the original state of affairs has been restored.
697 *
698 * The pipe may seem like a bit of overhead, but it fits in nicely with the
699 * other file descriptors of the select(), so there's only one condition to wait
700 * for.
701 *
702 * (4) Finally, a mutex is needed to make sure that at most one thread is in
703 * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
704 * requirement. We use the same mutex to guard the field for counting the
705 * waiting threads.
706 *
707 * Note: The current implementation assumes that we don't have to deal with
708 * problems induced by multiple cores or processors and their respective
709 * memory caches. One possible problem is that of inconsistent views on the
710 * "aliveAndKicking" field. This could be worked around by also enclosing all
711 * accesses to that field inside a lock/unlock sequence of our mutex, but
712 * currently this seems a bit like overkill.
713 */
714typedef struct app_data {
715    int aliveAndKicking;
716    int waitingThreads;
717    int fdsEmergency[2];
718    MUTEX_TYPE mutex;
719} APP_DATA;
720
721/**
722 * Creates our application data and attaches it to a given SSL connection.
723 *
724 * @param ssl The SSL connection to attach the data to.
725 * @return 0 on success, -1 on failure.
726 */
727static int sslCreateAppData(SSL* ssl) {
728    APP_DATA* data = (APP_DATA*) malloc(sizeof(APP_DATA));
729
730    memset(data, 0, sizeof(APP_DATA));
731
732    data->aliveAndKicking = 1;
733    data->waitingThreads = 0;
734    data->fdsEmergency[0] = -1;
735    data->fdsEmergency[1] = -1;
736
737    if (pipe(data->fdsEmergency) == -1) {
738        free(data);
739        return -1;
740    }
741
742    if (MUTEX_SETUP(data->mutex) == -1) {
743        free(data);
744        return -1;
745    }
746
747    SSL_set_app_data(ssl, (char*) data);
748
749    return 0;
750}
751
752/**
753 * Destroys our application data, cleaning up everything in the process.
754 *
755 * @param ssl The SSL connection to take the data from.
756 */
757static void sslDestroyAppData(SSL* ssl) {
758    APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
759
760    if (data != NULL) {
761        SSL_set_app_data(ssl, NULL);
762
763        data -> aliveAndKicking = 0;
764
765        if (data->fdsEmergency[0] != -1) {
766            close(data->fdsEmergency[0]);
767        }
768
769        if (data->fdsEmergency[1] != -1) {
770            close(data->fdsEmergency[1]);
771        }
772
773        MUTEX_CLEANUP(data->mutex);
774
775        free(data);
776    }
777}
778
779
780/**
781 * Frees the SSL_CTX struct for the given instance.
782 */
783static void free_ssl_ctx(JNIEnv* env, jobject object) {
784    /*
785     * Preserve and restore the exception state around this call, so
786     * that GetIntField and SetIntField will operate without complaint.
787     */
788    jthrowable exception = env->ExceptionOccurred();
789
790    if (exception != NULL) {
791        env->ExceptionClear();
792    }
793
794    SSL_CTX *ctx = (SSL_CTX *)env->GetIntField(object, field_Socket_ssl_ctx);
795
796    if (ctx != NULL) {
797        SSL_CTX_free(ctx);
798        env->SetIntField(object, field_Socket_ssl_ctx, (int) NULL);
799    }
800
801    if (exception != NULL) {
802        env->Throw(exception);
803    }
804}
805
806/**
807 * Frees the SSL struct for the given instance.
808 */
809static void free_ssl(JNIEnv* env, jobject object) {
810    /*
811     * Preserve and restore the exception state around this call, so
812     * that GetIntField and SetIntField will operate without complaint.
813     */
814    jthrowable exception = env->ExceptionOccurred();
815
816    if (exception != NULL) {
817        env->ExceptionClear();
818    }
819
820    SSL *ssl = (SSL *)env->GetIntField(object, field_Socket_ssl);
821
822    if (ssl != NULL) {
823        sslDestroyAppData(ssl);
824        SSL_free(ssl);
825        env->SetIntField(object, field_Socket_ssl, (int) NULL);
826    }
827
828    if (exception != NULL) {
829        env->Throw(exception);
830    }
831}
832
833/**
834 * Constructs the SSL struct for the given instance, replacing one
835 * that was already made, if any.
836 */
837static SSL* create_ssl(JNIEnv* env, jobject object, SSL_CTX*  ssl_ctx) {
838    free_ssl(env, object);
839
840    SSL *ssl = SSL_new(ssl_ctx);
841    env->SetIntField(object, field_Socket_ssl, (int) ssl);
842    return ssl;
843}
844
845/**
846 * Dark magic helper function that checks, for a given SSL session, whether it
847 * can SSL_read() or SSL_write() without blocking. Takes into account any
848 * concurrent attempts to close the SSL session from the Java side. This is
849 * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
850 * while thread #2 is sitting in a blocking read or write. The type argument
851 * specifies whether we are waiting for readability or writability. It expects
852 * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
853 * only need to wait in case one of these problems occurs.
854 *
855 * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
856 * @param fd The file descriptor to wait for (the underlying socket)
857 * @param data The application data structure with mutex info etc.
858 * @param timeout The timeout value for select call, with the special value
859 *                0 meaning no timeout at all (wait indefinitely). Note: This is
860 *                the Java semantics of the timeout value, not the usual
861 *                select() semantics.
862 * @return The result of the inner select() call, -1 on additional errors
863 */
864static int sslSelect(int type, int fd, APP_DATA *data, int timeout) {
865    fd_set rfds;
866    fd_set wfds;
867
868    FD_ZERO(&rfds);
869    FD_ZERO(&wfds);
870
871    if (type == SSL_ERROR_WANT_READ) {
872        FD_SET(fd, &rfds);
873    } else {
874        FD_SET(fd, &wfds);
875    }
876
877    FD_SET(data->fdsEmergency[0], &rfds);
878
879    int max = fd > data->fdsEmergency[0] ? fd : data->fdsEmergency[0];
880
881    // Build a struct for the timeout data if we actually want a timeout.
882    struct timeval tv;
883    struct timeval *ptv;
884    if (timeout > 0) {
885        tv.tv_sec = timeout / 1000;
886        tv.tv_usec = 0;
887        ptv = &tv;
888    } else {
889        ptv = NULL;
890    }
891
892    // LOGD("Doing select() for SSL_ERROR_WANT_%s...", type == SSL_ERROR_WANT_READ ? "READ" : "WRITE");
893    int result = select(max + 1, &rfds, &wfds, NULL, ptv);
894    // LOGD("Returned from select(), result is %d", result);
895
896    // Lock
897    if (MUTEX_LOCK(data->mutex) == -1) {
898        return -1;
899    }
900
901    // If we have been woken up by the emergency pipe, there must be a token in
902    // it. Thus we can safely read it (even in a blocking way).
903    if (FD_ISSET(data->fdsEmergency[0], &rfds)) {
904        char token;
905        do {
906            read(data->fdsEmergency[0], &token, 1);
907        } while (errno == EINTR);
908    }
909
910    // Tell the world that there is now one thread less waiting for the
911    // underlying network.
912    data->waitingThreads--;
913
914    // Unlock
915    MUTEX_UNLOCK(data->mutex);
916    // LOGD("leave sslSelect");
917    return result;
918}
919
920/**
921 * Helper function that wakes up a thread blocked in select(), in case there is
922 * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
923 * before closing the connection.
924 *
925 * @param data The application data structure with mutex info etc.
926 */
927static void sslNotify(APP_DATA *data) {
928    // Write a byte to the emergency pipe, so a concurrent select() can return.
929    // Note we have to restore the errno of the original system call, since the
930    // caller relies on it for generating error messages.
931    int errnoBackup = errno;
932    char token = '*';
933    do {
934        errno = 0;
935        write(data->fdsEmergency[1], &token, 1);
936    } while (errno == EINTR);
937    errno = errnoBackup;
938}
939
940/**
941 * Helper function which does the actual reading. The Java layer guarantees that
942 * at most one thread will enter this function at any given time.
943 *
944 * @param ssl non-null; the SSL context
945 * @param buf non-null; buffer to read into
946 * @param len length of the buffer, in bytes
947 * @param sslReturnCode original SSL return code
948 * @param sslErrorCode filled in with the SSL error code in case of error
949 * @return number of bytes read on success, -1 if the connection was
950 * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
951 */
952static int sslRead(SSL* ssl, char* buf, jint len, int* sslReturnCode,
953        int* sslErrorCode, int timeout) {
954
955    // LOGD("Entering sslRead, caller requests to read %d bytes...", len);
956
957    if (len == 0) {
958        // Don't bother doing anything in this case.
959        return 0;
960    }
961
962    int fd = SSL_get_fd(ssl);
963    BIO *bio = SSL_get_rbio(ssl);
964
965    APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
966
967    while (data->aliveAndKicking) {
968        errno = 0;
969
970        // Lock
971        if (MUTEX_LOCK(data->mutex) == -1) {
972            return -1;
973        }
974
975        unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
976
977        // LOGD("Doing SSL_Read()");
978        int result = SSL_read(ssl, buf, len);
979        int error = SSL_ERROR_NONE;
980        if (result <= 0) {
981            error = SSL_get_error(ssl, result);
982            freeSslErrorState();
983        }
984        // LOGD("Returned from SSL_Read() with result %d, error code %d", result, error);
985
986        // If we have been successful in moving data around, check whether it
987        // might make sense to wake up other blocked threads, so they can give
988        // it a try, too.
989        if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved && data->waitingThreads > 0) {
990            sslNotify(data);
991        }
992
993        // If we are blocked by the underlying socket, tell the world that
994        // there will be one more waiting thread now.
995        if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
996            data->waitingThreads++;
997        }
998
999        // Unlock
1000        MUTEX_UNLOCK(data->mutex);
1001
1002        switch (error) {
1003             // Sucessfully read at least one byte.
1004            case SSL_ERROR_NONE: {
1005                return result;
1006            }
1007
1008            // Read zero bytes. End of stream reached.
1009            case SSL_ERROR_ZERO_RETURN: {
1010                return -1;
1011            }
1012
1013            // Need to wait for availability of underlying layer, then retry.
1014            case SSL_ERROR_WANT_READ:
1015            case SSL_ERROR_WANT_WRITE: {
1016                int selectResult = sslSelect(error, fd, data, timeout);
1017                if (selectResult == -1) {
1018                    *sslReturnCode = -1;
1019                    *sslErrorCode = error;
1020                    return THROW_EXCEPTION;
1021                } else if (selectResult == 0) {
1022                    return THROW_SOCKETTIMEOUTEXCEPTION;
1023                }
1024
1025                break;
1026            }
1027
1028            // A problem occured during a system call, but this is not
1029            // necessarily an error.
1030            case SSL_ERROR_SYSCALL: {
1031                // Connection closed without proper shutdown. Tell caller we
1032                // have reached end-of-stream.
1033                if (result == 0) {
1034                    return -1;
1035                }
1036
1037                // System call has been interrupted. Simply retry.
1038                if (errno == EINTR) {
1039                    break;
1040                }
1041
1042                // Note that for all other system call errors we fall through
1043                // to the default case, which results in an Exception.
1044            }
1045
1046            // Everything else is basically an error.
1047            default: {
1048                *sslReturnCode = result;
1049                *sslErrorCode = error;
1050                return THROW_EXCEPTION;
1051            }
1052        }
1053    }
1054
1055    return -1;
1056}
1057
1058/**
1059 * Helper function which does the actual writing. The Java layer guarantees that
1060 * at most one thread will enter this function at any given time.
1061 *
1062 * @param ssl non-null; the SSL context
1063 * @param buf non-null; buffer to write
1064 * @param len length of the buffer, in bytes
1065 * @param sslReturnCode original SSL return code
1066 * @param sslErrorCode filled in with the SSL error code in case of error
1067 * @return number of bytes read on success, -1 if the connection was
1068 * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
1069 */
1070static int sslWrite(SSL* ssl, const char* buf, jint len, int* sslReturnCode,
1071        int* sslErrorCode) {
1072
1073    // LOGD("Entering sslWrite(), caller requests to write %d bytes...", len);
1074
1075    if (len == 0) {
1076        // Don't bother doing anything in this case.
1077        return 0;
1078    }
1079
1080    int fd = SSL_get_fd(ssl);
1081    BIO *bio = SSL_get_wbio(ssl);
1082
1083    APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
1084
1085    int count = len;
1086
1087    while(data->aliveAndKicking && len > 0) {
1088        errno = 0;
1089        if (MUTEX_LOCK(data->mutex) == -1) {
1090            return -1;
1091        }
1092
1093        unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
1094
1095        // LOGD("Doing SSL_write() with %d bytes to go", len);
1096        int result = SSL_write(ssl, buf, len);
1097        int error = SSL_ERROR_NONE;
1098        if (result <= 0) {
1099            error = SSL_get_error(ssl, result);
1100            freeSslErrorState();
1101        }
1102        // LOGD("Returned from SSL_write() with result %d, error code %d", result, error);
1103
1104        // If we have been successful in moving data around, check whether it
1105        // might make sense to wake up other blocked threads, so they can give
1106        // it a try, too.
1107        if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved && data->waitingThreads > 0) {
1108            sslNotify(data);
1109        }
1110
1111        // If we are blocked by the underlying socket, tell the world that
1112        // there will be one more waiting thread now.
1113        if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
1114            data->waitingThreads++;
1115        }
1116
1117        MUTEX_UNLOCK(data->mutex);
1118
1119        switch (error) {
1120             // Sucessfully write at least one byte.
1121            case SSL_ERROR_NONE: {
1122                buf += result;
1123                len -= result;
1124                break;
1125            }
1126
1127            // Wrote zero bytes. End of stream reached.
1128            case SSL_ERROR_ZERO_RETURN: {
1129                return -1;
1130            }
1131
1132            // Need to wait for availability of underlying layer, then retry.
1133            // The concept of a write timeout doesn't really make sense, and
1134            // it's also not standard Java behavior, so we wait forever here.
1135            case SSL_ERROR_WANT_READ:
1136            case SSL_ERROR_WANT_WRITE: {
1137                int selectResult = sslSelect(error, fd, data, 0);
1138                if (selectResult == -1) {
1139                    *sslReturnCode = -1;
1140                    *sslErrorCode = error;
1141                    return THROW_EXCEPTION;
1142                } else if (selectResult == 0) {
1143                    return THROW_SOCKETTIMEOUTEXCEPTION;
1144                }
1145
1146                break;
1147            }
1148
1149            // An problem occured during a system call, but this is not
1150            // necessarily an error.
1151            case SSL_ERROR_SYSCALL: {
1152                // Connection closed without proper shutdown. Tell caller we
1153                // have reached end-of-stream.
1154                if (result == 0) {
1155                    return -1;
1156                }
1157
1158                // System call has been interrupted. Simply retry.
1159                if (errno == EINTR) {
1160                    break;
1161                }
1162
1163                // Note that for all other system call errors we fall through
1164                // to the default case, which results in an Exception.
1165            }
1166
1167            // Everything else is basically an error.
1168            default: {
1169                *sslReturnCode = result;
1170                *sslErrorCode = error;
1171                return THROW_EXCEPTION;
1172            }
1173        }
1174    }
1175    // LOGD("Successfully wrote %d bytes", count);
1176
1177    return count;
1178}
1179
1180/**
1181 * Helper function that creates an RSA public key from two buffers containing
1182 * the big-endian bit representation of the modulus and the public exponent.
1183 *
1184 * @param mod The data of the modulus
1185 * @param modLen The length of the modulus data
1186 * @param exp The data of the exponent
1187 * @param expLen The length of the exponent data
1188 *
1189 * @return A pointer to the new RSA structure, or NULL on error
1190 */
1191static RSA* rsaCreateKey(unsigned char* mod, int modLen, unsigned char* exp, int expLen) {
1192    // LOGD("Entering rsaCreateKey()");
1193
1194    RSA* rsa = RSA_new();
1195
1196    rsa->n = BN_bin2bn((unsigned char*) mod, modLen, NULL);
1197    rsa->e = BN_bin2bn((unsigned char*) exp, expLen, NULL);
1198
1199    if (rsa->n == NULL || rsa->e == NULL) {
1200        RSA_free(rsa);
1201        return NULL;
1202    }
1203
1204    return rsa;
1205}
1206
1207/**
1208 * Helper function that frees an RSA key. Just calls the corresponding OpenSSL
1209 * function.
1210 *
1211 * @param rsa The pointer to the new RSA structure to free.
1212 */
1213static void rsaFreeKey(RSA* rsa) {
1214    // LOGD("Entering rsaFreeKey()");
1215
1216    if (rsa != NULL) {
1217        RSA_free(rsa);
1218    }
1219}
1220
1221/**
1222 * Helper function that verifies a given RSA signature for a given message.
1223 *
1224 * @param msg The message to verify
1225 * @param msgLen The length of the message
1226 * @param sig The signature to verify
1227 * @param sigLen The length of the signature
1228 * @param algorithm The name of the hash/sign algorithm to use, e.g. "RSA-SHA1"
1229 * @param rsa The RSA public key to use
1230 *
1231 * @return 1 on success, 0 on failure, -1 on error (check SSL errors then)
1232 *
1233 */
1234static int rsaVerify(unsigned char* msg, unsigned int msgLen, unsigned char* sig,
1235                     unsigned int sigLen, char* algorithm, RSA* rsa) {
1236
1237    // LOGD("Entering rsaVerify(%x, %d, %x, %d, %s, %x)", msg, msgLen, sig, sigLen, algorithm, rsa);
1238
1239    int result = -1;
1240
1241    EVP_PKEY* key = EVP_PKEY_new();
1242    EVP_PKEY_set1_RSA(key, rsa);
1243
1244    const EVP_MD *type = EVP_get_digestbyname(algorithm);
1245    if (type == NULL) {
1246        goto cleanup;
1247    }
1248
1249    EVP_MD_CTX ctx;
1250
1251    EVP_MD_CTX_init(&ctx);
1252    if (EVP_VerifyInit_ex(&ctx, type, NULL) == 0) {
1253        goto cleanup;
1254    }
1255
1256    EVP_VerifyUpdate(&ctx, msg, msgLen);
1257    result = EVP_VerifyFinal(&ctx, sig, sigLen, key);
1258    EVP_MD_CTX_cleanup(&ctx);
1259
1260    cleanup:
1261
1262    if (key != NULL) {
1263        EVP_PKEY_free(key);
1264    }
1265
1266    return result;
1267}
1268
1269// ============================================================================
1270// === OpenSSL-related helper stuff ends here. JNI glue follows. ==============
1271// ============================================================================
1272
1273/**
1274 * Initialization phase for every OpenSSL job: Loads the Error strings, the
1275 * crypto algorithms and reset the OpenSSL library
1276 */
1277static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_initstatic(JNIEnv* env, jobject obj)
1278{
1279    SSL_load_error_strings();
1280    ERR_load_crypto_strings();
1281    SSL_library_init();
1282    OpenSSL_add_all_algorithms();
1283    THREAD_setup();
1284}
1285
1286/**
1287 * Initialization phase for a socket with OpenSSL.  The server's private key
1288 * and X509 certificate are read and the Linux /dev/urandom file is loaded
1289 * as RNG for the session keys.
1290 *
1291 */
1292static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_init(JNIEnv* env, jobject object,
1293        jstring privatekey, jstring certificates, jbyteArray seed)
1294{
1295    SSL_CTX* ssl_ctx;
1296
1297    // 'seed == null' when no SecureRandom Object is set
1298    // in the SSLContext.
1299    if (seed != NULL) {
1300        jbyte* randseed = env->GetByteArrayElements(seed, NULL);
1301        RAND_seed((unsigned char*) randseed, 1024);
1302        env->ReleaseByteArrayElements(seed, randseed, 0);
1303    } else {
1304        RAND_load_file("/dev/urandom", 1024);
1305    }
1306
1307    ssl_ctx = SSL_CTX_new(SSLv23_client_method());
1308
1309    // Note: We explicitly do not allow SSLv2 to be used.
1310    // We also disable session tickets for better compatability b/2682876
1311    SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET);
1312
1313    /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
1314     * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
1315     * (by default disabled), the server will send a certificate which will
1316     * be checked. The result of the certificate verification process can be
1317     * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
1318     * function. The handshake will be continued regardless of the
1319     * verification result.
1320     */
1321    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
1322
1323    int mode = SSL_CTX_get_mode(ssl_ctx);
1324    /*
1325     * Turn on "partial write" mode. This means that SSL_write() will
1326     * behave like Posix write() and possibly return after only
1327     * writing a partial buffer. Note: The alternative, perhaps
1328     * surprisingly, is not that SSL_write() always does full writes
1329     * but that it will force you to retry write calls having
1330     * preserved the full state of the original call. (This is icky
1331     * and undesirable.)
1332     */
1333    mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
1334#if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
1335    mode |= SSL_MODE_SMALL_BUFFERS;  /* lazily allocate record buffers; usually saves
1336                                      * 44k over the default */
1337#endif
1338#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) /* not all SSL versions have this */
1339    mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;  /* enable sending of client data as soon as
1340                                             * ClientCCS and ClientFinished are sent */
1341#endif
1342
1343    SSL_CTX_set_mode(ssl_ctx, mode);
1344
1345    if (privatekey != NULL) {
1346        BIO* privatekeybio = stringToMemBuf(env, (jstring) privatekey);
1347        EVP_PKEY* privatekeyevp =
1348          PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL);
1349        BIO_free(privatekeybio);
1350
1351        if (privatekeyevp == NULL) {
1352            throwIOExceptionWithSslErrors(env, 0, 0,
1353                    "Error parsing the private key");
1354            SSL_CTX_free(ssl_ctx);
1355            return;
1356        }
1357
1358        BIO* certificatesbio = stringToMemBuf(env, (jstring) certificates);
1359        X509* certificatesx509 =
1360          PEM_read_bio_X509(certificatesbio, NULL, 0, NULL);
1361        BIO_free(certificatesbio);
1362
1363        if (certificatesx509 == NULL) {
1364            throwIOExceptionWithSslErrors(env, 0, 0,
1365                    "Error parsing the certificates");
1366            EVP_PKEY_free(privatekeyevp);
1367            SSL_CTX_free(ssl_ctx);
1368            return;
1369        }
1370
1371        int ret = SSL_CTX_use_certificate(ssl_ctx, certificatesx509);
1372        if (ret != 1) {
1373            throwIOExceptionWithSslErrors(env, ret, 0,
1374                    "Error setting the certificates");
1375            X509_free(certificatesx509);
1376            EVP_PKEY_free(privatekeyevp);
1377            SSL_CTX_free(ssl_ctx);
1378            return;
1379        }
1380
1381        ret = SSL_CTX_use_PrivateKey(ssl_ctx, privatekeyevp);
1382        if (ret != 1) {
1383            throwIOExceptionWithSslErrors(env, ret, 0,
1384                    "Error setting the private key");
1385            X509_free(certificatesx509);
1386            EVP_PKEY_free(privatekeyevp);
1387            SSL_CTX_free(ssl_ctx);
1388            return;
1389        }
1390
1391        ret = SSL_CTX_check_private_key(ssl_ctx);
1392        if (ret != 1) {
1393            throwIOExceptionWithSslErrors(env, ret, 0,
1394                    "Error checking the private key");
1395            X509_free(certificatesx509);
1396            EVP_PKEY_free(privatekeyevp);
1397            SSL_CTX_free(ssl_ctx);
1398            return;
1399        }
1400    }
1401
1402    env->SetIntField(object, field_Socket_ssl_ctx, (int)ssl_ctx);
1403}
1404
1405/**
1406 * A connection within an OpenSSL context is established. (1) A new socket is
1407 * constructed, (2) the TLS/SSL handshake with a server is initiated.
1408 */
1409static jboolean org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect(JNIEnv* env, jobject object,
1410        jint ctx, jobject socketObject, jboolean client_mode, jint session)
1411{
1412    // LOGD("ENTER connect");
1413    int ret, fd;
1414    SSL_CTX* ssl_ctx;
1415    SSL* ssl;
1416    SSL_SESSION* ssl_session;
1417
1418    ssl_ctx = (SSL_CTX*)env->GetIntField(object, field_Socket_ssl_ctx);
1419
1420    ssl = create_ssl(env, object, ssl_ctx);
1421    if (ssl == NULL) {
1422        throwIOExceptionWithSslErrors(env, 0, 0,
1423                "Unable to create SSL structure");
1424        free_ssl_ctx(env, object);
1425        return (jboolean) false;
1426    }
1427
1428    jobject socketImplObject = env->GetObjectField(socketObject, field_Socket_mImpl);
1429    if (socketImplObject == NULL) {
1430        free_ssl(env, object);
1431        free_ssl_ctx(env, object);
1432        throwIOExceptionStr(env,
1433            "couldn't get the socket impl from the socket");
1434        return (jboolean) false;
1435    }
1436
1437    jobject fdObject = env->GetObjectField(socketImplObject, field_Socket_mFD);
1438    if (fdObject == NULL) {
1439        free_ssl(env, object);
1440        free_ssl_ctx(env, object);
1441        throwIOExceptionStr(env,
1442            "couldn't get the file descriptor from the socket impl");
1443        return (jboolean) false;
1444    }
1445
1446    fd = jniGetFDFromFileDescriptor(env, fdObject);
1447
1448    ssl_session = (SSL_SESSION *) session;
1449
1450    ret = SSL_set_fd(ssl, fd);
1451
1452    if (ret != 1) {
1453        throwIOExceptionWithSslErrors(env, ret, 0,
1454                "Error setting the file descriptor");
1455        free_ssl(env, object);
1456        free_ssl_ctx(env, object);
1457        return (jboolean) false;
1458    }
1459
1460    if (ssl_session != NULL) {
1461        ret = SSL_set_session(ssl, ssl_session);
1462
1463        if (ret != 1) {
1464            /*
1465             * Translate the error, and throw if it turns out to be a real
1466             * problem.
1467             */
1468            int sslErrorCode = SSL_get_error(ssl, ret);
1469            if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
1470                throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1471                        "SSL session set");
1472                free_ssl(env, object);
1473                free_ssl_ctx(env, object);
1474                return (jboolean) false;
1475            }
1476        }
1477    }
1478
1479    /*
1480     * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
1481     * forever and we can use select() to find out if the socket is ready.
1482     */
1483    int mode = fcntl(fd, F_GETFL);
1484    if (mode == -1 || fcntl(fd, F_SETFL, mode | O_NONBLOCK) == -1) {
1485        throwIOExceptionStr(env, "Unable to make socket non blocking");
1486        free_ssl(env, object);
1487        free_ssl_ctx(env, object);
1488        return (jboolean) false;
1489    }
1490
1491    /*
1492     * Create our special application data.
1493     */
1494    if (sslCreateAppData(ssl) == -1) {
1495        throwIOExceptionStr(env, "Unable to create application data");
1496        free_ssl(env, object);
1497        free_ssl_ctx(env, object);
1498        // TODO
1499        return (jboolean) false;
1500    }
1501
1502    APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
1503    env->SetIntField(object, field_Socket_ssl, (int)ssl);
1504
1505    int timeout = (int)env->GetIntField(object, field_Socket_timeout);
1506
1507    while (data->aliveAndKicking) {
1508        errno = 0;
1509        ret = SSL_connect(ssl);
1510        if (ret == 1) {
1511            break;
1512        } else if (errno == EINTR) {
1513            continue;
1514        } else {
1515            // LOGD("SSL_connect: result %d, errno %d, timeout %d", ret, errno, timeout);
1516            int error = SSL_get_error(ssl, ret);
1517
1518            /*
1519             * If SSL_connect doesn't succeed due to the socket being
1520             * either unreadable or unwritable, we use sslSelect to
1521             * wait for it to become ready. If that doesn't happen
1522             * before the specified timeout or an error occurs, we
1523             * cancel the handshake. Otherwise we try the SSL_connect
1524             * again.
1525             */
1526            if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
1527                data->waitingThreads++;
1528                int selectResult = sslSelect(error, fd, data, timeout);
1529
1530                if (selectResult == -1) {
1531                    throwIOExceptionWithSslErrors(env, -1, error,
1532                        "Connect error");
1533                    free_ssl(env, object);
1534                    free_ssl_ctx(env, object);
1535                    return (jboolean) false;
1536                } else if (selectResult == 0) {
1537                    throwSocketTimeoutException(env, "SSL handshake timed out");
1538                    freeSslErrorState();
1539                    free_ssl(env, object);
1540                    free_ssl_ctx(env, object);
1541                    return (jboolean) false;
1542                }
1543            } else {
1544                LOGE("Unknown error %d during connect", error);
1545                break;
1546            }
1547        }
1548    }
1549
1550    if (ret != 1) {
1551        /*
1552         * Translate the error, and throw if it turns out to be a real
1553         * problem.
1554         */
1555        int sslErrorCode = SSL_get_error(ssl, ret);
1556        if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
1557            throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1558                    "SSL handshake failure");
1559            free_ssl(env, object);
1560            free_ssl_ctx(env, object);
1561            return (jboolean) false;
1562        }
1563    }
1564
1565    if (ssl_session != NULL) {
1566        ret = SSL_session_reused(ssl);
1567        // if (ret == 1) LOGD("A session was reused");
1568        // else LOGD("A new session was negotiated");
1569        return (jboolean) ret;
1570    } else {
1571        // LOGD("A new session was negotiated");
1572        return (jboolean) 0;
1573    }
1574    // LOGD("LEAVE connect");
1575}
1576
1577static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession(JNIEnv* env, jobject object,
1578        jint jssl)
1579{
1580    return (jint) SSL_get1_session((SSL *) jssl);
1581}
1582
1583static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept(JNIEnv* env, jobject object,
1584        jobject socketObject, jint jssl_ctx, jboolean client_mode)
1585{
1586    int sd, ret;
1587    BIO *bio;
1588    SSL *ssl;
1589    SSL_CTX *ssl_ctx;
1590    jsse_ssl_app_data_t appdata;
1591
1592    ssl_ctx = (SSL_CTX *)jssl_ctx;
1593
1594    ssl = create_ssl(env, object, ssl_ctx);
1595    if (ssl == NULL) {
1596        throwIOExceptionWithSslErrors(env, 0, 0,
1597                "Unable to create SSL structure");
1598        return;
1599    }
1600
1601    jobject socketImplObject = env->GetObjectField(socketObject, field_Socket_mImpl);
1602    if (socketImplObject == NULL) {
1603        free_ssl(env, object);
1604        throwIOExceptionStr(env, "couldn't get the socket impl from the socket");
1605        return;
1606    }
1607
1608    jobject fdObject = env->GetObjectField(socketImplObject, field_Socket_mFD);
1609    if (fdObject == NULL) {
1610        free_ssl(env, object);
1611        throwIOExceptionStr(env, "couldn't get the file descriptor from the socket impl");
1612        return;
1613    }
1614
1615
1616    sd = jniGetFDFromFileDescriptor(env, fdObject);
1617
1618    bio = BIO_new_socket(sd, BIO_NOCLOSE);
1619
1620    /* The parameter client_mode must be 1 */
1621    if (client_mode != 0)
1622        client_mode = 1;
1623    BIO_set_ssl_mode(bio, client_mode);
1624
1625    SSL_set_bio(ssl, bio, bio);
1626
1627    /*
1628     * Fill in the appdata structure needed for the certificate callback and
1629     * store this in the SSL application data slot.
1630     */
1631    appdata.env = env;
1632    appdata.object = object;
1633    SSL_set_app_data(ssl, &appdata);
1634
1635    /*
1636     * Do the actual SSL_accept(). It is possible this code is insufficient.
1637     * Maybe we need to deal with all the special SSL error cases (WANT_*),
1638     * just like we do for SSL_connect(). But currently it is looking ok.
1639     */
1640    ret = SSL_accept(ssl);
1641
1642    /*
1643     * Clear the SSL application data slot again, so we can safely use it for
1644     * our ordinary synchronization structure afterwards. Also, we don't want
1645     * sslDestroyAppData() to think that there is something that needs to be
1646     * freed right now (in case of an error).
1647     */
1648    SSL_set_app_data(ssl, NULL);
1649
1650    if (ret == 0) {
1651        /*
1652         * The other side closed the socket before the handshake could be
1653         * completed, but everything is within the bounds of the TLS protocol.
1654         * We still might want to find out the real reason of the failure.
1655         */
1656        int sslErrorCode = SSL_get_error(ssl, ret);
1657        if (sslErrorCode == SSL_ERROR_NONE ||
1658            (sslErrorCode == SSL_ERROR_SYSCALL && errno == 0)) {
1659          throwIOExceptionStr(env, "Connection closed by peer");
1660        } else {
1661          throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1662              "Trouble accepting connection");
1663    	}
1664        free_ssl(env, object);
1665        return;
1666    } else if (ret < 0) {
1667        /*
1668         * Translate the error and throw exception. We are sure it is an error
1669         * at this point.
1670         */
1671        int sslErrorCode = SSL_get_error(ssl, ret);
1672        throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1673                "Trouble accepting connection");
1674        free_ssl(env, object);
1675        return;
1676    }
1677
1678    /*
1679     * Make socket non-blocking, so SSL_read() and SSL_write() don't hang
1680     * forever and we can use select() to find out if the socket is ready.
1681     */
1682    int fd = SSL_get_fd(ssl);
1683    int mode = fcntl(fd, F_GETFL);
1684    if (mode == -1 || fcntl(fd, F_SETFL, mode | O_NONBLOCK) == -1) {
1685        throwIOExceptionStr(env, "Unable to make socket non blocking");
1686        free_ssl(env, object);
1687        return;
1688    }
1689
1690    /*
1691     * Create our special application data.
1692     */
1693    if (sslCreateAppData(ssl) == -1) {
1694        throwIOExceptionStr(env, "Unable to create application data");
1695        free_ssl(env, object);
1696        return;
1697    }
1698}
1699
1700/**
1701 * Loads the desired protocol for the OpenSSL client and enables it.
1702 * For example SSL_OP_NO_TLSv1 means do not use TLS v. 1.
1703 */
1704static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols(JNIEnv* env, jobject object,
1705        jlong protocol)
1706{
1707    if (protocol != 0x00000000L) {
1708        if (protocol & SSL_OP_NO_SSLv3)
1709            LOGD("SSL_OP_NO_SSLv3 is set");
1710        if (protocol & SSL_OP_NO_TLSv1)
1711            LOGD("SSL_OP_NO_TLSv1 is set");
1712
1713        SSL_CTX* ctx = (SSL_CTX*)env->GetIntField(object, field_Socket_ssl_ctx);
1714        int options = SSL_CTX_get_options(ctx);
1715        options |= protocol; // Note: SSLv2 disabled earlier.
1716        SSL_CTX_set_options(ctx, options);
1717    }
1718}
1719
1720static jobjectArray makeCipherList(JNIEnv* env, SSL* ssl) {
1721    // Count the ciphers.
1722    int cipherCount = 0;
1723    while (SSL_get_cipher_list(ssl, cipherCount) != NULL) {
1724        ++cipherCount;
1725    }
1726
1727    // Create a String[].
1728    jclass stringClass = env->FindClass("java/lang/String");
1729    if (stringClass == NULL) {
1730        return NULL;
1731    }
1732    jobjectArray array = env->NewObjectArray(cipherCount, stringClass, NULL);
1733    if (array == NULL) {
1734        return NULL;
1735    }
1736
1737    // Fill in the cipher names.
1738    for (int i = 0; i < cipherCount; ++i) {
1739        const char* c = SSL_get_cipher_list(ssl, i);
1740        env->SetObjectArrayElement(array, i, env->NewStringUTF(c));
1741    }
1742    return array;
1743}
1744
1745jobjectArray makeCipherList(JNIEnv* env, SSL_CTX* ssl_ctx) {
1746    SSL* ssl = SSL_new(ssl_ctx);
1747    if (ssl == NULL) {
1748        return NULL;
1749    }
1750    jobjectArray result = makeCipherList(env, ssl);
1751    SSL_free(ssl);
1752    return result;
1753}
1754
1755/**
1756 * Loads the ciphers suites that are supported by the OpenSSL client
1757 * and returns them in a string array.
1758 */
1759static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites(JNIEnv* env,
1760        jobject object)
1761{
1762    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
1763    if (ssl_ctx == NULL) {
1764        return NULL;
1765    }
1766    jobjectArray result = makeCipherList(env, ssl_ctx);
1767    SSL_CTX_free(ssl_ctx);
1768    return result;
1769}
1770
1771/**
1772 * Loads the ciphers suites that are enabled in the OpenSSL client
1773 * and returns them in a string array.
1774 */
1775static jobjectArray OpenSSLSocketImpl_nativeGetEnabledCipherSuites(JNIEnv* env,
1776        jclass, jint ssl_ctx_address)
1777{
1778    SSL_CTX* ssl_ctx =
1779            reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
1780    return makeCipherList(env, ssl_ctx);
1781}
1782
1783void setEnabledCipherSuites(JNIEnv* env, jstring controlString, SSL_CTX* ssl_ctx) {
1784    const char* str = env->GetStringUTFChars(controlString, NULL);
1785    int rc = SSL_CTX_set_cipher_list(ssl_ctx, str);
1786    env->ReleaseStringUTFChars(controlString, str);
1787    if (rc == 0) {
1788        freeSslErrorState();
1789        jniThrowException(env, "java/lang/IllegalArgumentException",
1790                          "Illegal cipher suite strings.");
1791    }
1792}
1793
1794/**
1795 * Sets the ciphers suites that are enabled in the OpenSSL client.
1796 */
1797static void OpenSSLSocketImpl_nativeSetEnabledCipherSuites(JNIEnv* env, jclass,
1798        jint ssl_ctx_address, jstring controlString)
1799{
1800    SSL_CTX* ssl_ctx =
1801            reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
1802    setEnabledCipherSuites(env, controlString, ssl_ctx);
1803}
1804
1805#define SSL_AUTH_MASK           0x00007F00L
1806#define SSL_aRSA                0x00000100L /* Authenticate with RSA */
1807#define SSL_aDSS                0x00000200L /* Authenticate with DSS */
1808#define SSL_DSS                 SSL_aDSS
1809#define SSL_aFZA                0x00000400L
1810#define SSL_aNULL               0x00000800L /* no Authenticate, ADH */
1811#define SSL_aDH                 0x00001000L /* no Authenticate, ADH */
1812#define SSL_aKRB5               0x00002000L /* Authenticate with KRB5 */
1813#define SSL_aECDSA              0x00004000L /* Authenticate with ECDSA */
1814
1815/**
1816 * Sets  the client's crypto algorithms and authentication methods.
1817 */
1818static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod(JNIEnv* env,
1819        jobject object)
1820{
1821    SSL* ssl;
1822    SSL_CIPHER *cipher;
1823    jstring ret;
1824    char buf[512];
1825    unsigned long alg;
1826    const char *au;
1827
1828    ssl = getSslPointer(env, object, true);
1829    if (ssl == NULL) {
1830        return NULL;
1831    }
1832
1833    cipher = SSL_get_current_cipher(ssl);
1834
1835    alg = cipher->algorithms;
1836
1837    switch (alg&SSL_AUTH_MASK) {
1838        case SSL_aRSA:
1839            au="RSA";
1840            break;
1841        case SSL_aDSS:
1842            au="DSS";
1843            break;
1844        case SSL_aDH:
1845            au="DH";
1846            break;
1847        case SSL_aFZA:
1848            au = "FZA";
1849            break;
1850        case SSL_aNULL:
1851            au="None";
1852            break;
1853        case SSL_aECDSA:
1854            au="ECDSA";
1855            break;
1856        default:
1857            au="unknown";
1858            break;
1859    }
1860
1861    ret = env->NewStringUTF(au);
1862
1863    return ret;
1864}
1865
1866/**
1867 * OpenSSL read function (1): only one chunk is read (returned as jint).
1868 */
1869static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read(JNIEnv* env, jobject object, jint timeout)
1870{
1871    SSL *ssl = getSslPointer(env, object, true);
1872    if (ssl == NULL) {
1873        return 0;
1874    }
1875
1876    unsigned char byteRead;
1877    int returnCode = 0;
1878    int errorCode = 0;
1879
1880    int ret = sslRead(ssl, (char *) &byteRead, 1, &returnCode, &errorCode, timeout);
1881
1882    switch (ret) {
1883        case THROW_EXCEPTION:
1884            // See sslRead() regarding improper failure to handle normal cases.
1885            throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1886                    "Read error");
1887            return -1;
1888        case THROW_SOCKETTIMEOUTEXCEPTION:
1889            throwSocketTimeoutException(env, "Read timed out");
1890            return -1;
1891        case -1:
1892            // Propagate EOF upwards.
1893            return -1;
1894        default:
1895            // Return the actual char read, make sure it stays 8 bits wide.
1896            return ((jint) byteRead) & 0xFF;
1897    }
1898}
1899
1900/**
1901 * OpenSSL read function (2): read into buffer at offset n chunks.
1902 * Returns 1 (success) or value <= 0 (failure).
1903 */
1904static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba(JNIEnv* env, jobject obj, jbyteArray dest, jint offset, jint len, jint timeout)
1905{
1906    SSL *ssl = getSslPointer(env, obj, true);
1907    if (ssl == NULL) {
1908        return 0;
1909    }
1910
1911    jbyte* bytes = env->GetByteArrayElements(dest, NULL);
1912    int returnCode = 0;
1913    int errorCode = 0;
1914
1915    int ret =
1916        sslRead(ssl, (char*) (bytes + offset), len, &returnCode, &errorCode, timeout);
1917
1918    env->ReleaseByteArrayElements(dest, bytes, 0);
1919
1920    if (ret == THROW_EXCEPTION) {
1921        // See sslRead() regarding improper failure to handle normal cases.
1922        throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1923                "Read error");
1924        return -1;
1925    } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) {
1926        throwSocketTimeoutException(env, "Read timed out");
1927        return -1;
1928    }
1929
1930    return ret;
1931}
1932
1933/**
1934 * OpenSSL write function (1): only one chunk is written.
1935 */
1936static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write(JNIEnv* env, jobject object, jint b)
1937{
1938    SSL *ssl = getSslPointer(env, object, true);
1939    if (ssl == NULL) {
1940        return;
1941    }
1942
1943    int returnCode = 0;
1944    int errorCode = 0;
1945    char buf[1] = { (char) b };
1946    int ret = sslWrite(ssl, buf, 1, &returnCode, &errorCode);
1947
1948    if (ret == THROW_EXCEPTION) {
1949        // See sslWrite() regarding improper failure to handle normal cases.
1950        throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1951                "Write error");
1952    } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) {
1953        throwSocketTimeoutException(env, "Write timed out");
1954    }
1955}
1956
1957/**
1958 * OpenSSL write function (2): write into buffer at offset n chunks.
1959 */
1960static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba(JNIEnv* env, jobject obj,
1961        jbyteArray dest, jint offset, jint len)
1962{
1963    SSL *ssl = getSslPointer(env, obj, true);
1964    if (ssl == NULL) {
1965        return;
1966    }
1967
1968    jbyte* bytes = env->GetByteArrayElements(dest, NULL);
1969    int returnCode = 0;
1970    int errorCode = 0;
1971    int timeout = (int)env->GetIntField(obj, field_Socket_timeout);
1972    int ret = sslWrite(ssl, (const char *) (bytes + offset), len,
1973            &returnCode, &errorCode);
1974
1975    env->ReleaseByteArrayElements(dest, bytes, 0);
1976
1977    if (ret == THROW_EXCEPTION) {
1978        // See sslWrite() regarding improper failure to handle normal cases.
1979        throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1980                "Write error");
1981    } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) {
1982        throwSocketTimeoutException(env, "Write timed out");
1983    }
1984}
1985
1986/**
1987 * Interrupt any pending IO before closing the socket.
1988 */
1989static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt(
1990        JNIEnv* env, jobject object) {
1991    SSL *ssl = getSslPointer(env, object, false);
1992    if (ssl == NULL) {
1993        return;
1994    }
1995
1996    /*
1997     * Mark the connection as quasi-dead, then send something to the emergency
1998     * file descriptor, so any blocking select() calls are woken up.
1999     */
2000    APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
2001    if (data != NULL) {
2002        data->aliveAndKicking = 0;
2003
2004        // At most two threads can be waiting.
2005        sslNotify(data);
2006        sslNotify(data);
2007    }
2008}
2009
2010/**
2011 * OpenSSL close SSL socket function.
2012 */
2013static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close(
2014        JNIEnv* env, jobject object) {
2015    SSL *ssl = getSslPointer(env, object, false);
2016    if (ssl == NULL) {
2017        return;
2018    }
2019
2020    /*
2021     * Try to make socket blocking again. OpenSSL literature recommends this.
2022     */
2023    int fd = SSL_get_fd(ssl);
2024    if (fd != -1) {
2025        int mode = fcntl(fd, F_GETFL);
2026        if (mode == -1 || fcntl(fd, F_SETFL, mode & ~O_NONBLOCK) == -1) {
2027//            throwIOExceptionStr(env, "Unable to make socket blocking again");
2028//            LOGW("Unable to make socket blocking again");
2029        }
2030    }
2031
2032    int ret = SSL_shutdown(ssl);
2033    switch (ret) {
2034        case 0:
2035            /*
2036             * Shutdown was not successful (yet), but there also
2037             * is no error. Since we can't know whether the remote
2038             * server is actually still there, and we don't want to
2039             * get stuck forever in a second SSL_shutdown() call, we
2040             * simply return. This is not security a problem as long
2041             * as we close the underlying socket, which we actually
2042             * do, because that's where we are just coming from.
2043             */
2044            break;
2045        case 1:
2046            /*
2047             * Shutdown was sucessful. We can safely return. Hooray!
2048             */
2049            break;
2050        default:
2051            /*
2052             * Everything else is a real error condition. We should
2053             * let the Java layer know about this by throwing an
2054             * exception.
2055             */
2056            int sslErrorCode = SSL_get_error(ssl, ret);
2057            throwIOExceptionWithSslErrors(env, ret, sslErrorCode, "SSL shutdown failed");
2058            break;
2059    }
2060
2061    freeSslErrorState();
2062    free_ssl(env, object);
2063    free_ssl_ctx(env, object);
2064}
2065
2066/**
2067 * OpenSSL free SSL socket function.
2068 */
2069static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_free(JNIEnv* env, jobject object)
2070{
2071    free_ssl(env, object);
2072    free_ssl_ctx(env, object);
2073}
2074
2075/**
2076 * Verifies an RSA signature.
2077 */
2078static int org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_verifysignature(JNIEnv* env, jclass clazz,
2079        jbyteArray msg, jbyteArray sig, jstring algorithm, jbyteArray mod, jbyteArray exp) {
2080
2081    // LOGD("Entering verifysignature()");
2082
2083    if (msg == NULL || sig == NULL || algorithm == NULL || mod == NULL || exp == NULL) {
2084        jniThrowNullPointerException(env, NULL);
2085        return -1;
2086    }
2087
2088    int result = -1;
2089
2090    jbyte* msgBytes = env->GetByteArrayElements(msg, NULL);
2091    jint msgLength = env->GetArrayLength(msg);
2092
2093    jbyte* sigBytes = env->GetByteArrayElements(sig, NULL);
2094    jint sigLength = env->GetArrayLength(sig);
2095
2096    jbyte* modBytes = env->GetByteArrayElements(mod, NULL);
2097    jint modLength = env->GetArrayLength(mod);
2098
2099    jbyte* expBytes = env->GetByteArrayElements(exp, NULL);
2100    jint expLength = env->GetArrayLength(exp);
2101
2102    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
2103
2104    RSA* rsa = rsaCreateKey((unsigned char*) modBytes, modLength, (unsigned char*) expBytes, expLength);
2105    if (rsa != NULL) {
2106        result = rsaVerify((unsigned char*) msgBytes, msgLength, (unsigned char*) sigBytes, sigLength,
2107                (char*) algorithmChars, rsa);
2108        rsaFreeKey(rsa);
2109    }
2110
2111    env->ReleaseStringUTFChars(algorithm, algorithmChars);
2112
2113    env->ReleaseByteArrayElements(exp, expBytes, JNI_ABORT);
2114    env->ReleaseByteArrayElements(mod, modBytes, JNI_ABORT);
2115    env->ReleaseByteArrayElements(sig, sigBytes, JNI_ABORT);
2116    env->ReleaseByteArrayElements(msg, msgBytes, JNI_ABORT);
2117
2118    if (result == -1) {
2119        int error = ERR_get_error();
2120        if (error != 0) {
2121            char message[50];
2122            ERR_error_string_n(error, message, sizeof(message));
2123            jniThrowRuntimeException(env, message);
2124        } else {
2125            jniThrowRuntimeException(env, "Internal error during verification");
2126        }
2127        freeSslErrorState();
2128    }
2129
2130    return result;
2131}
2132
2133static JNINativeMethod sSocketImplMethods[] =
2134{
2135    {"nativeinitstatic", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_initstatic},
2136    {"nativeinit", "(Ljava/lang/String;Ljava/lang/String;[B)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_init},
2137    {"nativeconnect", "(ILjava/net/Socket;ZI)Z", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect},
2138    {"nativegetsslsession", "(I)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession},
2139    {"nativeread", "(I)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read},
2140    {"nativeread", "([BIII)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba},
2141    {"nativewrite", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write},
2142    {"nativewrite", "([BII)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba},
2143    {"nativeaccept", "(Ljava/net/Socket;IZ)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept},
2144    {"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols},
2145    {"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites},
2146    {"nativeGetEnabledCipherSuites", "(I)[Ljava/lang/String;", (void*) OpenSSLSocketImpl_nativeGetEnabledCipherSuites},
2147    {"nativeSetEnabledCipherSuites", "(ILjava/lang/String;)V", (void*) OpenSSLSocketImpl_nativeSetEnabledCipherSuites},
2148    {"nativecipherauthenticationmethod", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod},
2149    {"nativeinterrupt", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt},
2150    {"nativeclose", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close},
2151    {"nativefree", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_free},
2152    {"nativeverifysignature", "([B[BLjava/lang/String;[B[B)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_verifysignature},
2153};
2154
2155/**
2156 * Module scope variables initialized during JNI registration.
2157 */
2158static jfieldID field_ServerSocket_ssl_ctx;
2159
2160/**
2161 * Initialization phase of OpenSSL: Loads the Error strings, the crypto algorithms and reset the OpenSSL library
2162 */
2163static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_initstatic(JNIEnv* env, jobject obj)
2164{
2165    SSL_load_error_strings();
2166    ERR_load_crypto_strings();
2167    SSL_library_init();
2168    OpenSSL_add_all_algorithms();
2169}
2170
2171/**
2172 * Initialization phase for a server socket with OpenSSL.  The server's private key and X509 certificate are read and
2173 * the Linux /dev/random file is loaded as RNG for the session keys.
2174 *
2175 */
2176static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_init(JNIEnv* env, jobject object,
2177        jstring privatekey, jstring certificates, jbyteArray seed)
2178{
2179    SSL_CTX *ssl_ctx;
2180    const char *privatekeychar;
2181    const char *certificateschar;
2182    EVP_PKEY * privatekeyevp;
2183
2184    BIO *privatekeybio;
2185    BIO *certificatesbio;
2186
2187    // 'seed == null' when no SecureRandom Object is set
2188    // in the SSLContext.
2189    if (seed != NULL) {
2190        jbyte* randseed = env->GetByteArrayElements(seed, NULL);
2191        RAND_seed((unsigned char*) randseed, 1024);
2192        env->ReleaseByteArrayElements(seed, randseed, 0);
2193    } else {
2194        RAND_load_file("/dev/urandom", 1024);
2195    }
2196
2197    ssl_ctx = SSL_CTX_new(SSLv23_server_method());
2198    SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2);
2199
2200    privatekeychar = env->GetStringUTFChars((jstring)privatekey, NULL);
2201    privatekeybio = BIO_new_mem_buf((void*)privatekeychar, -1);
2202
2203    privatekeyevp = PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL);
2204    env->ReleaseStringUTFChars(privatekey, privatekeychar);
2205
2206    if (privatekeyevp == NULL) {
2207        LOGE(ERR_error_string(ERR_get_error(), NULL));
2208        throwIOExceptionStr(env, "Error parsing the private key");
2209        return;
2210    }
2211
2212    certificateschar = env->GetStringUTFChars((jstring)certificates, NULL);
2213    certificatesbio = BIO_new_mem_buf((void*)certificateschar, -1);
2214
2215    X509 * certificatesx509 = PEM_read_bio_X509(certificatesbio, NULL, 0, NULL);
2216    env->ReleaseStringUTFChars(certificates, certificateschar);
2217
2218    if (certificatesx509 == NULL) {
2219        LOGE(ERR_error_string(ERR_get_error(), NULL));
2220        throwIOExceptionStr(env, "Error parsing the certificates");
2221        return;
2222    }
2223
2224    if (!SSL_CTX_use_certificate(ssl_ctx, certificatesx509)) {
2225        LOGE(ERR_error_string(ERR_get_error(), NULL));
2226        throwIOExceptionStr(env, "Error setting the certificates");
2227        return;
2228    }
2229
2230    if (!SSL_CTX_use_PrivateKey(ssl_ctx, privatekeyevp)) {
2231        LOGE(ERR_error_string(ERR_get_error(), NULL));
2232        throwIOExceptionStr(env, "Error setting the private key");
2233        return;
2234    }
2235
2236    if (!SSL_CTX_check_private_key(ssl_ctx)) {
2237        LOGE(ERR_error_string(ERR_get_error(), NULL));
2238        throwIOExceptionStr(env, "Error checking private key");
2239        return;
2240    }
2241
2242    env->SetIntField(object, field_ServerSocket_ssl_ctx, (int)ssl_ctx);
2243}
2244
2245/**
2246 * Loads the desired protocol for the OpenSSL server and enables it.
2247 * For example SSL_OP_NO_TLSv1 means do not use TLS v. 1.
2248 */
2249static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledprotocols(JNIEnv* env,
2250        jobject object, jlong protocol)
2251{
2252    if (protocol != 0x00000000L) {
2253        if (protocol & SSL_OP_NO_SSLv3)
2254            LOGD("SSL_OP_NO_SSLv3 is set");
2255        if (protocol & SSL_OP_NO_TLSv1)
2256            LOGD("SSL_OP_NO_TLSv1 is set");
2257
2258        SSL_CTX* ctx = (SSL_CTX*)env->GetIntField(object, field_ServerSocket_ssl_ctx);
2259        SSL_CTX_set_options((SSL_CTX*)ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2|(long)protocol);
2260    }
2261}
2262
2263/**
2264 * Loads the ciphers suites that are supported by the OpenSSL server
2265 * and returns them in a string array.
2266 */
2267static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getsupportedciphersuites(JNIEnv* env,
2268        jobject object)
2269{
2270    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_server_method());
2271    if (ssl_ctx == NULL) {
2272        return NULL;
2273    }
2274    jobjectArray result = makeCipherList(env, ssl_ctx);
2275    SSL_CTX_free(ssl_ctx);
2276    return result;
2277}
2278
2279/**
2280 * Gives an array back containing all the X509 certificate's bytes.
2281 */
2282static jobjectArray getcertificatebytes(JNIEnv* env,
2283        const STACK_OF(X509) *chain)
2284{
2285    BUF_MEM *bptr;
2286    int count, i;
2287    jbyteArray bytes;
2288    jobjectArray joa;
2289
2290    if (chain == NULL) {
2291        // Chain can be NULL if the associated cipher doesn't do certs.
2292        return NULL;
2293    }
2294
2295    count = sk_X509_num(chain);
2296
2297    if (count > 0) {
2298        joa = env->NewObjectArray(count, env->FindClass("[B"), NULL);
2299
2300        if (joa == NULL) {
2301            return NULL;
2302        }
2303
2304        BIO *bio = BIO_new(BIO_s_mem());
2305
2306        // LOGD("Start fetching the certificates");
2307        for (i = 0; i < count; i++) {
2308            X509 *cert = sk_X509_value(chain, i);
2309
2310            BIO_reset(bio);
2311            PEM_write_bio_X509(bio, cert);
2312
2313            BIO_get_mem_ptr(bio, &bptr);
2314            bytes = env->NewByteArray(bptr->length);
2315
2316            if (bytes == NULL) {
2317                /*
2318                 * Indicate an error by resetting joa to NULL. It will
2319                 * eventually get gc'ed.
2320                 */
2321                joa = NULL;
2322                break;
2323            } else {
2324                jbyte* src = reinterpret_cast<jbyte*>(bptr->data);
2325                env->SetByteArrayRegion(bytes, 0, bptr->length, src);
2326                env->SetObjectArrayElement(joa, i, bytes);
2327            }
2328        }
2329
2330        // LOGD("Certificate fetching complete");
2331        BIO_free(bio);
2332        return joa;
2333    } else {
2334        return NULL;
2335    }
2336}
2337
2338/**
2339 * Verify the X509 certificate.
2340 */
2341static int verify_callback(int preverify_ok, X509_STORE_CTX *x509_store_ctx)
2342{
2343    SSL *ssl;
2344    jsse_ssl_app_data_t *appdata;
2345    jclass cls;
2346
2347    jobjectArray objectArray;
2348
2349    /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
2350    ssl = (SSL*)X509_STORE_CTX_get_ex_data(x509_store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2351
2352    appdata = (jsse_ssl_app_data_t*)SSL_get_app_data(ssl);
2353
2354    cls = appdata->env->GetObjectClass(appdata->object);
2355
2356    jmethodID methodID = appdata->env->GetMethodID(cls, "verify_callback", "([[B)I");
2357
2358    objectArray = getcertificatebytes(appdata->env, x509_store_ctx->untrusted);
2359
2360    appdata->env->CallIntMethod(appdata->object, methodID, objectArray);
2361
2362    return 1;
2363}
2364
2365/**
2366 * Sets  the client's credentials and the depth of theirs verification.
2367 */
2368static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativesetclientauth(JNIEnv* env,
2369        jobject object, jint value)
2370{
2371    SSL_CTX *ssl_ctx = (SSL_CTX *)env->GetIntField(object, field_ServerSocket_ssl_ctx);
2372    SSL_CTX_set_verify(ssl_ctx, (int)value, verify_callback);
2373}
2374
2375/**
2376 * The actual SSL context is reset.
2377 */
2378static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativefree(JNIEnv* env, jobject object)
2379{
2380    SSL_CTX *ctx = (SSL_CTX *)env->GetIntField(object, field_ServerSocket_ssl_ctx);
2381    SSL_CTX_free(ctx);
2382    env->SetIntField(object, field_ServerSocket_ssl_ctx, 0);
2383}
2384
2385static JNINativeMethod sServerSocketImplMethods[] =
2386{
2387    {"nativeinitstatic", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_initstatic},
2388    {"nativeinit", "(Ljava/lang/String;Ljava/lang/String;[B)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_init},
2389    {"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledprotocols},
2390    {"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getsupportedciphersuites},
2391    {"nativesetclientauth", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativesetclientauth},
2392    {"nativefree", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativefree}
2393};
2394
2395static jfieldID field_Session_session;
2396
2397static SSL_SESSION* getSslSessionPointer(JNIEnv* env, jobject object) {
2398    return reinterpret_cast<SSL_SESSION*>(env->GetIntField(object, field_Session_session));
2399}
2400
2401// Fills a byte[][] with the peer certificates in the chain.
2402static jobjectArray OpenSSLSessionImpl_getPeerCertificatesImpl(JNIEnv* env,
2403        jobject object, jint jssl)
2404{
2405    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
2406    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
2407    SSL* ssl = SSL_new(ssl_ctx);
2408
2409    SSL_set_session(ssl, ssl_session);
2410
2411    STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
2412    jobjectArray objectArray = getcertificatebytes(env, chain);
2413
2414    SSL_free(ssl);
2415    SSL_CTX_free(ssl_ctx);
2416    return objectArray;
2417}
2418
2419/**
2420 * Serializes the native state of the session (ID, cipher, and keys but
2421 * not certificates). Returns a byte[] containing the DER-encoded state.
2422 * See apache mod_ssl.
2423 */
2424static jbyteArray OpenSSLSessionImpl_getEncoded(JNIEnv* env, jobject object) {
2425    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
2426    if (ssl_session == NULL) {
2427        return NULL;
2428    }
2429
2430    // Compute the size of the DER data
2431    int size = i2d_SSL_SESSION(ssl_session, NULL);
2432    if (size == 0) {
2433        return NULL;
2434    }
2435
2436    jbyteArray bytes = env->NewByteArray(size);
2437    if (bytes != NULL) {
2438        jbyte* tmp = env->GetByteArrayElements(bytes, NULL);
2439        unsigned char* ucp = reinterpret_cast<unsigned char*>(tmp);
2440        i2d_SSL_SESSION(ssl_session, &ucp);
2441        env->ReleaseByteArrayElements(bytes, tmp, 0);
2442    }
2443
2444    return bytes;
2445}
2446
2447/**
2448 * Deserialize the session.
2449 */
2450static jint OpenSSLSessionImpl_initializeNativeImpl(JNIEnv* env, jobject object, jbyteArray bytes, jint size) {
2451    if (bytes == NULL) {
2452        return 0;
2453    }
2454
2455    jbyte* tmp = env->GetByteArrayElements(bytes, NULL);
2456    const unsigned char* ucp = reinterpret_cast<const unsigned char*>(tmp);
2457    SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, size);
2458    env->ReleaseByteArrayElements(bytes, tmp, 0);
2459
2460    return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
2461}
2462
2463/**
2464 * Gets and returns in a byte array the ID of the actual SSL session.
2465 */
2466static jbyteArray OpenSSLSessionImpl_getId(JNIEnv* env, jobject object) {
2467    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
2468
2469    jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
2470    if (result != NULL) {
2471        jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
2472        env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
2473    }
2474
2475    return result;
2476}
2477
2478/**
2479 * Gets and returns in a long integer the creation's time of the
2480 * actual SSL session.
2481 */
2482static jlong OpenSSLSessionImpl_getCreationTime(JNIEnv* env, jobject object) {
2483    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
2484    jlong result = SSL_SESSION_get_time(ssl_session);
2485    result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
2486    return result;
2487}
2488
2489/**
2490 * Gets and returns in a string the version of the SSL protocol. If it
2491 * returns the string "unknown" it means that no connection is established.
2492 */
2493static jstring OpenSSLSessionImpl_getProtocol(JNIEnv* env, jobject object) {
2494    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
2495    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
2496    SSL* ssl = SSL_new(ssl_ctx);
2497
2498    SSL_set_session(ssl, ssl_session);
2499
2500    const char* protocol = SSL_get_version(ssl);
2501    jstring result = env->NewStringUTF(protocol);
2502
2503    SSL_free(ssl);
2504    SSL_CTX_free(ssl_ctx);
2505    return result;
2506}
2507
2508/**
2509 * Gets and returns in a string the set of ciphers the actual SSL session uses.
2510 */
2511static jstring OpenSSLSessionImpl_getCipherSuite(JNIEnv* env, jobject object) {
2512    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
2513    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
2514    SSL* ssl = SSL_new(ssl_ctx);
2515
2516    SSL_set_session(ssl, ssl_session);
2517
2518    SSL_CIPHER* cipher = SSL_get_current_cipher(ssl);
2519    jstring result = env->NewStringUTF(SSL_CIPHER_get_name(cipher));
2520
2521    SSL_free(ssl);
2522    SSL_CTX_free(ssl_ctx);
2523    return result;
2524}
2525
2526/**
2527 * Frees the SSL session.
2528 */
2529static void OpenSSLSessionImpl_freeImpl(JNIEnv* env, jobject object, jint session) {
2530    LOGD("Freeing OpenSSL session");
2531    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(session);
2532    SSL_SESSION_free(ssl_session);
2533}
2534
2535static JNINativeMethod sSessionImplMethods[] = {
2536    { "freeImpl", "(I)V", (void*) OpenSSLSessionImpl_freeImpl },
2537    { "getCipherSuite", "()Ljava/lang/String;", (void*) OpenSSLSessionImpl_getCipherSuite },
2538    { "getCreationTime", "()J", (void*) OpenSSLSessionImpl_getCreationTime },
2539    { "getEncoded", "()[B", (void*) OpenSSLSessionImpl_getEncoded },
2540    { "getId", "()[B", (void*) OpenSSLSessionImpl_getId },
2541    { "getPeerCertificatesImpl", "()[[B", (void*) OpenSSLSessionImpl_getPeerCertificatesImpl },
2542    { "getProtocol", "()Ljava/lang/String;", (void*) OpenSSLSessionImpl_getProtocol },
2543    { "initializeNativeImpl", "([BI)I", (void*) OpenSSLSessionImpl_initializeNativeImpl }
2544};
2545
2546typedef struct {
2547    const char*            name;
2548    const JNINativeMethod* methods;
2549    jint                   nMethods;
2550} JNINativeClass;
2551
2552static JNINativeClass sClasses[] = {
2553    { "org/apache/harmony/xnet/provider/jsse/NativeCrypto", sNativeCryptoMethods, NELEM(sNativeCryptoMethods) },
2554    { "org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl", sSocketImplMethods, NELEM(sSocketImplMethods) },
2555    { "org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl", sServerSocketImplMethods, NELEM(sServerSocketImplMethods) },
2556    { "org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl", sSessionImplMethods, NELEM(sSessionImplMethods) },
2557};
2558
2559/*
2560 * Peforms the actual registration of the native methods.
2561 * Also looks up the fields that belong to the class (if
2562 * any) and stores the field IDs. Simply remove what you
2563 * don't need.
2564 */
2565extern "C" int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
2566
2567    // Register org.apache.harmony.xnet.provider.jsse.* methods
2568    for (int i = 0; i < NELEM(sClasses); i++) {
2569        int result = jniRegisterNativeMethods(env,
2570                                              sClasses[i].name,
2571                                              sClasses[i].methods,
2572                                              sClasses[i].nMethods);
2573        if (result == -1) {
2574          return -1;
2575        }
2576    }
2577
2578    // java.io.FileDescriptor
2579    jclass fileDescriptor = env->FindClass("java/io/FileDescriptor");
2580    if (fileDescriptor == NULL) {
2581        LOGE("Can't find java/io/FileDescriptor");
2582        return -1;
2583    }
2584    field_FileDescriptor_descriptor = env->GetFieldID(fileDescriptor, "descriptor", "I");
2585    if (field_FileDescriptor_descriptor == NULL) {
2586        LOGE("Can't find FileDescriptor.descriptor");
2587        return -1;
2588    }
2589
2590    // java.net.Socket
2591    jclass socket = env->FindClass("java/net/Socket");
2592    if (socket == NULL) {
2593        LOGE("Can't find class java.net.Socket");
2594        return -1;
2595    }
2596    field_Socket_mImpl = env->GetFieldID(socket, "impl", "Ljava/net/SocketImpl;");
2597    if (field_Socket_mImpl == NULL) {
2598        LOGE("Can't find field impl in class java.net.Socket");
2599        return -1;
2600    }
2601
2602    // java.net.SocketImpl
2603    jclass socketImplClass = env->FindClass("java/net/SocketImpl");
2604    if (socketImplClass == NULL) {
2605        LOGE("Can't find class java.net.SocketImpl");
2606        return -1;
2607    }
2608    field_Socket_mFD = env->GetFieldID(socketImplClass, "fd", "Ljava/io/FileDescriptor;");
2609    if (field_Socket_mFD == NULL) {
2610        LOGE("Can't find field fd in java.net.SocketImpl");
2611        return -1;
2612    }
2613
2614    // org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
2615    jclass socketImpl = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
2616    if (socketImpl == NULL) {
2617        LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
2618        return -1;
2619    }
2620    // Note: do these after the registration of native methods, because
2621    // there is a static method "initstatic" that's called when the
2622    // OpenSSLSocketImpl class is first loaded, and that required
2623    // a native method to be associated with it.
2624    field_Socket_ssl_ctx = env->GetFieldID(socketImpl, "ssl_ctx", "I");
2625    if (field_Socket_ssl_ctx == NULL) {
2626      LOGE("Can't find OpenSSLSocketImpl.ssl_ctx");
2627      return -1;
2628    }
2629    field_Socket_ssl = env->GetFieldID(socketImpl, "ssl", "I");
2630    if (field_Socket_ssl == NULL) {
2631      LOGE("Can't find OpenSSLSocketImpl.ssl");
2632      return -1;
2633    }
2634    field_Socket_timeout = env->GetFieldID(socketImpl, "timeout", "I");
2635    if (field_Socket_timeout == NULL) {
2636      LOGE("Can't find OpenSSLSocketImpl.timeout");
2637      return -1;
2638    }
2639
2640    // org.apache.harmony.xnet.provider.jsse.OpenSSLServerSocketImpl
2641    jclass serverSocketImpl = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
2642    if (serverSocketImpl == NULL) {
2643        LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
2644        return -1;
2645    }
2646    // Note: do these after the registration of native methods, because
2647    // there is a static method "initstatic" that's called when the
2648    // OpenSSLServerSocketImpl class is first loaded, and that required
2649    // a native method to be associated with it.
2650    field_ServerSocket_ssl_ctx = env->GetFieldID(serverSocketImpl, "ssl_ctx", "I");
2651    if (field_ServerSocket_ssl_ctx == NULL) {
2652      LOGE("Can't find OpenSSLServerSocketImpl.ssl_ctx");
2653      return -1;
2654    }
2655
2656    // org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl
2657    jclass sessionImpl = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl");
2658    if (sessionImpl == NULL) {
2659        return -1;
2660    }
2661    field_Session_session = env->GetFieldID(sessionImpl, "session", "I");
2662    if (field_Session_session == NULL) {
2663      LOGE("Can't find OpenSSLSessionImpl.session");
2664      return -1;
2665    }
2666
2667    return 0;
2668}
2669