2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "OpenSSLSocketImpl"
20 #include "LocalArray.h"
21 #include "cutils/log.h"
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
29 #include <netinet/in.h>
34 #include <sys/select.h>
36 #include <openssl/err.h>
37 #include <openssl/rand.h>
38 #include <openssl/ssl.h>
40 #include "org_apache_harmony_xnet_provider_jsse_common.h"
43 * Module scope variables initialized during JNI registration.
45 static jfieldID field_ssl_ctx;
46 static jfieldID field_ssl;
47 static jfieldID field_descriptor;
48 static jfieldID field_mImpl;
49 static jfieldID field_mFD;
50 static jfieldID field_timeout;
53 * Gets the chars of a String object as a '\0'-terminated UTF-8 string,
54 * stored in a freshly-allocated BIO memory buffer.
56 static BIO *stringToMemBuf(JNIEnv* env, jstring string) {
57 jsize byteCount = env->GetStringUTFLength(string);
58 LocalArray<1024> buf(byteCount + 1);
59 env->GetStringUTFRegion(string, 0, env->GetStringLength(string), &buf[0]);
61 BIO* result = BIO_new(BIO_s_mem());
62 BIO_puts(result, &buf[0]);
67 * Throws an SocketTimeoutException with the given string as a message.
69 static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
70 if (jniThrowException(env, "java/net/SocketTimeoutException", message)) {
71 LOGE("Unable to throw");
76 * Throws an IOException with the given string as a message.
78 static void throwIOExceptionStr(JNIEnv* env, const char* message) {
79 if (jniThrowException(env, "java/io/IOException", message)) {
80 LOGE("Unable to throw");
85 * Frees the SSL error state.
87 * OpenSSL keeps an "error stack" per thread, and given that this code
88 * can be called from arbitrary threads that we don't keep track of,
89 * we err on the side of freeing the error state promptly (instead of,
90 * say, at thread death).
92 static void freeSslErrorState(void) {
98 * Throws an IOException with a message constructed from the current
99 * SSL errors. This will also log the errors.
101 * @param env the JNI environment
102 * @param sslReturnCode return code from failing SSL function
103 * @param sslErrorCode error code returned from SSL_get_error()
104 * @param message null-ok; general error message
106 static void throwIOExceptionWithSslErrors(JNIEnv* env, int sslReturnCode,
107 int sslErrorCode, const char* message) {
108 const char* messageStr = NULL;
112 // First consult the SSL error code for the general message.
113 switch (sslErrorCode) {
118 messageStr = "Failure in SSL library, usually a protocol error";
120 case SSL_ERROR_WANT_READ:
121 messageStr = "SSL_ERROR_WANT_READ occured. You should never see this.";
123 case SSL_ERROR_WANT_WRITE:
124 messageStr = "SSL_ERROR_WANT_WRITE occured. You should never see this.";
126 case SSL_ERROR_WANT_X509_LOOKUP:
127 messageStr = "SSL_ERROR_WANT_X509_LOOKUP occured. You should never see this.";
129 case SSL_ERROR_SYSCALL:
130 messageStr = "I/O error during system call";
132 case SSL_ERROR_ZERO_RETURN:
133 messageStr = "SSL_ERROR_ZERO_RETURN occured. You should never see this.";
135 case SSL_ERROR_WANT_CONNECT:
136 messageStr = "SSL_ERROR_WANT_CONNECT occured. You should never see this.";
138 case SSL_ERROR_WANT_ACCEPT:
139 messageStr = "SSL_ERROR_WANT_ACCEPT occured. You should never see this.";
142 messageStr = "Unknown SSL error";
145 // Prepend either our explicit message or a default one.
146 if (asprintf(&str, "%s: %s",
147 (message != NULL) ? message : "SSL error", messageStr) == 0) {
148 throwIOExceptionStr(env, messageStr);
149 LOGV("%s", messageStr);
154 char* allocStr = str;
156 // For SSL protocol errors, SSL might have more information.
157 if (sslErrorCode == SSL_ERROR_SSL) {
158 // Append each error as an additional line to the message.
166 ERR_get_error_line_data(&file, &line, &data, &flags);
172 ERR_error_string_n(err, errStr, sizeof(errStr));
174 ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
175 (allocStr == NULL) ? "" : allocStr,
189 // For errors during system calls, errno might be our friend.
190 } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
191 if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
195 // If the error code is invalid, print it.
196 } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
197 if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
203 throwIOExceptionStr(env, allocStr);
205 LOGV("%s", allocStr);
211 * Helper function that grabs the ssl pointer out of the given object.
212 * If this function returns NULL and <code>throwIfNull</code> is
213 * passed as <code>true</code>, then this function will call
214 * <code>throwIOExceptionStr</code> before returning, so in this case of
215 * NULL, a caller of this function should simply return and allow JNI
218 * @param env non-null; the JNI environment
219 * @param obj non-null; socket object
220 * @param throwIfNull whether to throw if the SSL pointer is NULL
221 * @returns the pointer, which may be NULL
223 static SSL *getSslPointer(JNIEnv* env, jobject obj, bool throwIfNull) {
224 SSL *ssl = (SSL *)env->GetIntField(obj, field_ssl);
226 if ((ssl == NULL) && throwIfNull) {
227 throwIOExceptionStr(env, "null SSL pointer");
233 // ============================================================================
234 // === OpenSSL-related helper stuff begins here. ==============================
235 // ============================================================================
238 * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
239 * suppose there are not many other ways to do this on a Linux system (modulo
242 #define MUTEX_TYPE pthread_mutex_t
243 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
244 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
245 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
246 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
247 #define THREAD_ID pthread_self()
248 #define THROW_EXCEPTION (-2)
249 #define THROW_SOCKETTIMEOUTEXCEPTION (-3)
251 static MUTEX_TYPE *mutex_buf = NULL;
253 static void locking_function(int mode, int n, const char * file, int line) {
254 if (mode & CRYPTO_LOCK) {
255 MUTEX_LOCK(mutex_buf[n]);
257 MUTEX_UNLOCK(mutex_buf[n]);
261 static unsigned long id_function(void) {
262 return ((unsigned long)THREAD_ID);
265 int THREAD_setup(void) {
268 mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE));
274 for (i = 0; i < CRYPTO_num_locks( ); i++) {
275 MUTEX_SETUP(mutex_buf[i]);
278 CRYPTO_set_id_callback(id_function);
279 CRYPTO_set_locking_callback(locking_function);
284 int THREAD_cleanup(void) {
291 CRYPTO_set_id_callback(NULL);
292 CRYPTO_set_locking_callback(NULL);
294 for (i = 0; i < CRYPTO_num_locks( ); i++) {
295 MUTEX_CLEANUP(mutex_buf[i]);
304 int get_socket_timeout(int type, int sd) {
306 socklen_t len = sizeof(tv);
307 if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
308 LOGE("getsockopt(%d, SOL_SOCKET): %s (%d)",
314 // LOGI("Current socket timeout (%d(s), %d(us))!",
315 // (int)tv.tv_sec, (int)tv.tv_usec);
316 int timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
320 #ifdef TIMEOUT_DEBUG_SSL
322 void print_socket_timeout(const char* name, int type, int sd) {
324 int len = sizeof(tv);
325 if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
326 LOGE("getsockopt(%d, SOL_SOCKET, %s): %s (%d)",
332 LOGI("Current socket %s is (%d(s), %d(us))!",
333 name, (int)tv.tv_sec, (int)tv.tv_usec);
336 void print_timeout(const char* method, SSL* ssl) {
337 LOGI("SSL_get_default_timeout %d in %s", SSL_get_default_timeout(ssl), method);
338 int fd = SSL_get_fd(ssl);
339 print_socket_timeout("SO_RCVTIMEO", SO_RCVTIMEO, fd);
340 print_socket_timeout("SO_SNDTIMEO", SO_SNDTIMEO, fd);
346 * Our additional application data needed for getting synchronization right.
347 * This maybe warrants a bit of lengthy prose:
349 * (1) We use a flag to reflect whether we consider the SSL connection alive.
350 * Any read or write attempt loops will be cancelled once this flag becomes 0.
352 * (2) We use an int to count the number of threads that are blocked by the
353 * underlying socket. This may be at most two (one reader and one writer), since
354 * the Java layer ensures that no more threads will enter the native code at the
357 * (3) The pipe is used primarily as a means of cancelling a blocking select()
358 * when we want to close the connection (aka "emergency button"). It is also
359 * necessary for dealing with a possible race condition situation: There might
360 * be cases where both threads see an SSL_ERROR_WANT_READ or
361 * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
362 * If one leaves the select() successfully before the other enters it, the
363 * "success" event is already consumed and the second thread will be blocked,
364 * possibly forever (depending on network conditions).
366 * The idea for solving the problem looks like this: Whenever a thread is
367 * successful in moving around data on the network, and it knows there is
368 * another thread stuck in a select(), it will write a byte to the pipe, waking
369 * up the other thread. A thread that returned from select(), on the other hand,
370 * knows whether it's been woken up by the pipe. If so, it will consume the
371 * byte, and the original state of affairs has been restored.
373 * The pipe may seem like a bit of overhead, but it fits in nicely with the
374 * other file descriptors of the select(), so there's only one condition to wait
377 * (4) Finally, a mutex is needed to make sure that at most one thread is in
378 * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
379 * requirement. We use the same mutex to guard the field for counting the
382 * Note: The current implementation assumes that we don't have to deal with
383 * problems induced by multiple cores or processors and their respective
384 * memory caches. One possible problem is that of inconsistent views on the
385 * "aliveAndKicking" field. This could be worked around by also enclosing all
386 * accesses to that field inside a lock/unlock sequence of our mutex, but
387 * currently this seems a bit like overkill.
389 typedef struct app_data {
397 * Creates our application data and attaches it to a given SSL connection.
399 * @param ssl The SSL connection to attach the data to.
400 * @return 0 on success, -1 on failure.
402 static int sslCreateAppData(SSL* ssl) {
403 APP_DATA* data = (APP_DATA*) malloc(sizeof(APP_DATA));
405 memset(data, 0, sizeof(APP_DATA));
407 data->aliveAndKicking = 1;
408 data->waitingThreads = 0;
409 data->fdsEmergency[0] = -1;
410 data->fdsEmergency[1] = -1;
412 if (pipe(data->fdsEmergency) == -1) {
416 if (MUTEX_SETUP(data->mutex) == -1) {
420 SSL_set_app_data(ssl, (char*) data);
426 * Destroys our application data, cleaning up everything in the process.
428 * @param ssl The SSL connection to take the data from.
430 static void sslDestroyAppData(SSL* ssl) {
431 APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
434 SSL_set_app_data(ssl, NULL);
436 data -> aliveAndKicking = 0;
438 if (data->fdsEmergency[0] != -1) {
439 close(data->fdsEmergency[0]);
442 if (data->fdsEmergency[1] != -1) {
443 close(data->fdsEmergency[1]);
446 MUTEX_CLEANUP(data->mutex);
454 * Frees the SSL_CTX struct for the given instance.
456 static void free_ssl_ctx(JNIEnv* env, jobject object) {
458 * Preserve and restore the exception state around this call, so
459 * that GetIntField and SetIntField will operate without complaint.
461 jthrowable exception = env->ExceptionOccurred();
463 if (exception != NULL) {
464 env->ExceptionClear();
467 SSL_CTX *ctx = (SSL_CTX *)env->GetIntField(object, field_ssl_ctx);
471 env->SetIntField(object, field_ssl_ctx, (int) NULL);
474 if (exception != NULL) {
475 env->Throw(exception);
480 * Frees the SSL struct for the given instance.
482 static void free_ssl(JNIEnv* env, jobject object) {
484 * Preserve and restore the exception state around this call, so
485 * that GetIntField and SetIntField will operate without complaint.
487 jthrowable exception = env->ExceptionOccurred();
489 if (exception != NULL) {
490 env->ExceptionClear();
493 SSL *ssl = (SSL *)env->GetIntField(object, field_ssl);
496 sslDestroyAppData(ssl);
498 env->SetIntField(object, field_ssl, (int) NULL);
501 if (exception != NULL) {
502 env->Throw(exception);
507 * Constructs the SSL struct for the given instance, replacing one
508 * that was already made, if any.
510 static SSL* create_ssl(JNIEnv* env, jobject object, SSL_CTX* ssl_ctx) {
511 free_ssl(env, object);
513 SSL *ssl = SSL_new(ssl_ctx);
514 env->SetIntField(object, field_ssl, (int) ssl);
519 * Dark magic helper function that checks, for a given SSL session, whether it
520 * can SSL_read() or SSL_write() without blocking. Takes into account any
521 * concurrent attempts to close the SSL session from the Java side. This is
522 * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
523 * while thread #2 is sitting in a blocking read or write. The type argument
524 * specifies whether we are waiting for readability or writability. It expects
525 * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
526 * only need to wait in case one of these problems occurs.
528 * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
529 * @param fd The file descriptor to wait for (the underlying socket)
530 * @param data The application data structure with mutex info etc.
531 * @param timeout The timeout value for select call, with the special value
532 * 0 meaning no timeout at all (wait indefinitely). Note: This is
533 * the Java semantics of the timeout value, not the usual
534 * select() semantics.
535 * @return The result of the inner select() call, -1 on additional errors
537 static int sslSelect(int type, int fd, APP_DATA *data, int timeout) {
544 if (type == SSL_ERROR_WANT_READ) {
550 FD_SET(data->fdsEmergency[0], &rfds);
552 int max = fd > data->fdsEmergency[0] ? fd : data->fdsEmergency[0];
554 // Build a struct for the timeout data if we actually want a timeout.
558 tv.tv_sec = timeout / 1000;
565 // LOGD("Doing select() for SSL_ERROR_WANT_%s...", type == SSL_ERROR_WANT_READ ? "READ" : "WRITE");
566 int result = select(max + 1, &rfds, &wfds, NULL, ptv);
567 // LOGD("Returned from select(), result is %d", result);
570 if (MUTEX_LOCK(data->mutex) == -1) {
574 // If we have been woken up by the emergency pipe, there must be a token in
575 // it. Thus we can safely read it (even in a blocking way).
576 if (FD_ISSET(data->fdsEmergency[0], &rfds)) {
579 read(data->fdsEmergency[0], &token, 1);
580 } while (errno == EINTR);
583 // Tell the world that there is now one thread less waiting for the
584 // underlying network.
585 data->waitingThreads--;
588 MUTEX_UNLOCK(data->mutex);
589 // LOGD("leave sslSelect");
594 * Helper function that wakes up a thread blocked in select(), in case there is
595 * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
596 * before closing the connection.
598 * @param data The application data structure with mutex info etc.
600 static void sslNotify(APP_DATA *data) {
601 // Write a byte to the emergency pipe, so a concurrent select() can return.
602 // Note we have to restore the errno of the original system call, since the
603 // caller relies on it for generating error messages.
604 int errnoBackup = errno;
608 write(data->fdsEmergency[1], &token, 1);
609 } while (errno == EINTR);
614 * Helper function which does the actual reading. The Java layer guarantees that
615 * at most one thread will enter this function at any given time.
617 * @param ssl non-null; the SSL context
618 * @param buf non-null; buffer to read into
619 * @param len length of the buffer, in bytes
620 * @param sslReturnCode original SSL return code
621 * @param sslErrorCode filled in with the SSL error code in case of error
622 * @return number of bytes read on success, -1 if the connection was
623 * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
625 static int sslRead(SSL* ssl, char* buf, jint len, int* sslReturnCode,
626 int* sslErrorCode, int timeout) {
628 // LOGD("Entering sslRead, caller requests to read %d bytes...", len);
631 // Don't bother doing anything in this case.
635 int fd = SSL_get_fd(ssl);
636 BIO *bio = SSL_get_rbio(ssl);
638 APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
640 while (data->aliveAndKicking) {
644 if (MUTEX_LOCK(data->mutex) == -1) {
648 unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
650 // LOGD("Doing SSL_Read()");
651 int result = SSL_read(ssl, buf, len);
652 int error = SSL_ERROR_NONE;
654 error = SSL_get_error(ssl, result);
657 // LOGD("Returned from SSL_Read() with result %d, error code %d", result, error);
659 // If we have been successful in moving data around, check whether it
660 // might make sense to wake up other blocked threads, so they can give
662 if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved && data->waitingThreads > 0) {
666 // If we are blocked by the underlying socket, tell the world that
667 // there will be one more waiting thread now.
668 if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
669 data->waitingThreads++;
673 MUTEX_UNLOCK(data->mutex);
676 // Sucessfully read at least one byte.
677 case SSL_ERROR_NONE: {
681 // Read zero bytes. End of stream reached.
682 case SSL_ERROR_ZERO_RETURN: {
686 // Need to wait for availability of underlying layer, then retry.
687 case SSL_ERROR_WANT_READ:
688 case SSL_ERROR_WANT_WRITE: {
689 int selectResult = sslSelect(error, fd, data, timeout);
690 if (selectResult == -1) {
692 *sslErrorCode = error;
693 return THROW_EXCEPTION;
694 } else if (selectResult == 0) {
695 return THROW_SOCKETTIMEOUTEXCEPTION;
701 // A problem occured during a system call, but this is not
702 // necessarily an error.
703 case SSL_ERROR_SYSCALL: {
704 // Connection closed without proper shutdown. Tell caller we
705 // have reached end-of-stream.
710 // System call has been interrupted. Simply retry.
711 if (errno == EINTR) {
715 // Note that for all other system call errors we fall through
716 // to the default case, which results in an Exception.
719 // Everything else is basically an error.
721 *sslReturnCode = result;
722 *sslErrorCode = error;
723 return THROW_EXCEPTION;
732 * Helper function which does the actual writing. The Java layer guarantees that
733 * at most one thread will enter this function at any given time.
735 * @param ssl non-null; the SSL context
736 * @param buf non-null; buffer to write
737 * @param len length of the buffer, in bytes
738 * @param sslReturnCode original SSL return code
739 * @param sslErrorCode filled in with the SSL error code in case of error
740 * @return number of bytes read on success, -1 if the connection was
741 * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
743 static int sslWrite(SSL* ssl, const char* buf, jint len, int* sslReturnCode,
746 // LOGD("Entering sslWrite(), caller requests to write %d bytes...", len);
749 // Don't bother doing anything in this case.
753 int fd = SSL_get_fd(ssl);
754 BIO *bio = SSL_get_wbio(ssl);
756 APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
760 while(data->aliveAndKicking && len > 0) {
762 if (MUTEX_LOCK(data->mutex) == -1) {
766 unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
768 // LOGD("Doing SSL_write() with %d bytes to go", len);
769 int result = SSL_write(ssl, buf, len);
770 int error = SSL_ERROR_NONE;
772 error = SSL_get_error(ssl, result);
775 // LOGD("Returned from SSL_write() with result %d, error code %d", result, error);
777 // If we have been successful in moving data around, check whether it
778 // might make sense to wake up other blocked threads, so they can give
780 if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved && data->waitingThreads > 0) {
784 // If we are blocked by the underlying socket, tell the world that
785 // there will be one more waiting thread now.
786 if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
787 data->waitingThreads++;
790 MUTEX_UNLOCK(data->mutex);
793 // Sucessfully write at least one byte.
794 case SSL_ERROR_NONE: {
800 // Wrote zero bytes. End of stream reached.
801 case SSL_ERROR_ZERO_RETURN: {
805 // Need to wait for availability of underlying layer, then retry.
806 // The concept of a write timeout doesn't really make sense, and
807 // it's also not standard Java behavior, so we wait forever here.
808 case SSL_ERROR_WANT_READ:
809 case SSL_ERROR_WANT_WRITE: {
810 int selectResult = sslSelect(error, fd, data, 0);
811 if (selectResult == -1) {
813 *sslErrorCode = error;
814 return THROW_EXCEPTION;
815 } else if (selectResult == 0) {
816 return THROW_SOCKETTIMEOUTEXCEPTION;
822 // An problem occured during a system call, but this is not
823 // necessarily an error.
824 case SSL_ERROR_SYSCALL: {
825 // Connection closed without proper shutdown. Tell caller we
826 // have reached end-of-stream.
831 // System call has been interrupted. Simply retry.
832 if (errno == EINTR) {
836 // Note that for all other system call errors we fall through
837 // to the default case, which results in an Exception.
840 // Everything else is basically an error.
842 *sslReturnCode = result;
843 *sslErrorCode = error;
844 return THROW_EXCEPTION;
848 // LOGD("Successfully wrote %d bytes", count);
854 * Helper function that creates an RSA public key from two buffers containing
855 * the big-endian bit representation of the modulus and the public exponent.
857 * @param mod The data of the modulus
858 * @param modLen The length of the modulus data
859 * @param exp The data of the exponent
860 * @param expLen The length of the exponent data
862 * @return A pointer to the new RSA structure, or NULL on error
864 static RSA* rsaCreateKey(unsigned char* mod, int modLen, unsigned char* exp, int expLen) {
865 // LOGD("Entering rsaCreateKey()");
867 RSA* rsa = RSA_new();
869 rsa->n = BN_bin2bn((unsigned char*) mod, modLen, NULL);
870 rsa->e = BN_bin2bn((unsigned char*) exp, expLen, NULL);
872 if (rsa->n == NULL || rsa->e == NULL) {
881 * Helper function that frees an RSA key. Just calls the corresponding OpenSSL
884 * @param rsa The pointer to the new RSA structure to free.
886 static void rsaFreeKey(RSA* rsa) {
887 // LOGD("Entering rsaFreeKey()");
895 * Helper function that verifies a given RSA signature for a given message.
897 * @param msg The message to verify
898 * @param msgLen The length of the message
899 * @param sig The signature to verify
900 * @param sigLen The length of the signature
901 * @param algorithm The name of the hash/sign algorithm to use, e.g. "RSA-SHA1"
902 * @param rsa The RSA public key to use
904 * @return 1 on success, 0 on failure, -1 on error (check SSL errors then)
907 static int rsaVerify(unsigned char* msg, unsigned int msgLen, unsigned char* sig,
908 unsigned int sigLen, char* algorithm, RSA* rsa) {
910 // LOGD("Entering rsaVerify(%x, %d, %x, %d, %s, %x)", msg, msgLen, sig, sigLen, algorithm, rsa);
914 EVP_PKEY* key = EVP_PKEY_new();
915 EVP_PKEY_set1_RSA(key, rsa);
917 const EVP_MD *type = EVP_get_digestbyname(algorithm);
924 EVP_MD_CTX_init(&ctx);
925 if (EVP_VerifyInit_ex(&ctx, type, NULL) == 0) {
929 EVP_VerifyUpdate(&ctx, msg, msgLen);
930 result = EVP_VerifyFinal(&ctx, sig, sigLen, key);
931 EVP_MD_CTX_cleanup(&ctx);
942 // ============================================================================
943 // === OpenSSL-related helper stuff ends here. JNI glue follows. ==============
944 // ============================================================================
947 * Initialization phase for every OpenSSL job: Loads the Error strings, the
948 * crypto algorithms and reset the OpenSSL library
950 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_initstatic(JNIEnv* env, jobject obj)
952 SSL_load_error_strings();
953 ERR_load_crypto_strings();
955 OpenSSL_add_all_algorithms();
960 * Initialization phase for a socket with OpenSSL. The server's private key
961 * and X509 certificate are read and the Linux /dev/urandom file is loaded
962 * as RNG for the session keys.
965 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_init(JNIEnv* env, jobject object,
966 jstring privatekey, jstring certificates, jbyteArray seed)
970 // 'seed == null' when no SecureRandom Object is set
971 // in the SSLContext.
973 jbyte* randseed = env->GetByteArrayElements(seed, NULL);
974 RAND_seed((unsigned char*) randseed, 1024);
975 env->ReleaseByteArrayElements(seed, randseed, 0);
977 RAND_load_file("/dev/urandom", 1024);
980 ssl_ctx = SSL_CTX_new(SSLv23_client_method());
982 // Note: We explicitly do not allow SSLv2 to be used. It
983 SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
985 /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
986 * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
987 * (by default disabled), the server will send a certificate which will
988 * be checked. The result of the certificate verification process can be
989 * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
990 * function. The handshake will be continued regardless of the
991 * verification result.
993 SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
995 int mode = SSL_CTX_get_mode(ssl_ctx);
997 * Turn on "partial write" mode. This means that SSL_write() will
998 * behave like Posix write() and possibly return after only
999 * writing a partial buffer. Note: The alternative, perhaps
1000 * surprisingly, is not that SSL_write() always does full writes
1001 * but that it will force you to retry write calls having
1002 * preserved the full state of the original call. (This is icky
1005 mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
1006 #if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
1007 mode |= SSL_MODE_SMALL_BUFFERS; /* lazily allocate record buffers; usually saves
1008 * 44k over the default */
1010 #if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) /* not all SSL versions have this */
1011 mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH; /* enable sending of client data as soon as
1012 * ClientCCS and ClientFinished are sent */
1015 SSL_CTX_set_mode(ssl_ctx, mode);
1017 if (privatekey != NULL) {
1018 BIO* privatekeybio = stringToMemBuf(env, (jstring) privatekey);
1019 EVP_PKEY* privatekeyevp =
1020 PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL);
1021 BIO_free(privatekeybio);
1023 if (privatekeyevp == NULL) {
1024 throwIOExceptionWithSslErrors(env, 0, 0,
1025 "Error parsing the private key");
1026 SSL_CTX_free(ssl_ctx);
1030 BIO* certificatesbio = stringToMemBuf(env, (jstring) certificates);
1031 X509* certificatesx509 =
1032 PEM_read_bio_X509(certificatesbio, NULL, 0, NULL);
1033 BIO_free(certificatesbio);
1035 if (certificatesx509 == NULL) {
1036 throwIOExceptionWithSslErrors(env, 0, 0,
1037 "Error parsing the certificates");
1038 EVP_PKEY_free(privatekeyevp);
1039 SSL_CTX_free(ssl_ctx);
1043 int ret = SSL_CTX_use_certificate(ssl_ctx, certificatesx509);
1045 throwIOExceptionWithSslErrors(env, ret, 0,
1046 "Error setting the certificates");
1047 X509_free(certificatesx509);
1048 EVP_PKEY_free(privatekeyevp);
1049 SSL_CTX_free(ssl_ctx);
1053 ret = SSL_CTX_use_PrivateKey(ssl_ctx, privatekeyevp);
1055 throwIOExceptionWithSslErrors(env, ret, 0,
1056 "Error setting the private key");
1057 X509_free(certificatesx509);
1058 EVP_PKEY_free(privatekeyevp);
1059 SSL_CTX_free(ssl_ctx);
1063 ret = SSL_CTX_check_private_key(ssl_ctx);
1065 throwIOExceptionWithSslErrors(env, ret, 0,
1066 "Error checking the private key");
1067 X509_free(certificatesx509);
1068 EVP_PKEY_free(privatekeyevp);
1069 SSL_CTX_free(ssl_ctx);
1074 env->SetIntField(object, field_ssl_ctx, (int)ssl_ctx);
1078 * A connection within an OpenSSL context is established. (1) A new socket is
1079 * constructed, (2) the TLS/SSL handshake with a server is initiated.
1081 static jboolean org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect(JNIEnv* env, jobject object,
1082 jint ctx, jobject socketObject, jboolean client_mode, jint session)
1084 // LOGD("ENTER connect");
1088 SSL_SESSION* ssl_session;
1090 ssl_ctx = (SSL_CTX*)env->GetIntField(object, field_ssl_ctx);
1092 ssl = create_ssl(env, object, ssl_ctx);
1094 throwIOExceptionWithSslErrors(env, 0, 0,
1095 "Unable to create SSL structure");
1096 free_ssl_ctx(env, object);
1097 return (jboolean) false;
1100 jobject socketImplObject = env->GetObjectField(socketObject, field_mImpl);
1101 if (socketImplObject == NULL) {
1102 free_ssl(env, object);
1103 free_ssl_ctx(env, object);
1104 throwIOExceptionStr(env,
1105 "couldn't get the socket impl from the socket");
1106 return (jboolean) false;
1109 jobject fdObject = env->GetObjectField(socketImplObject, field_mFD);
1110 if (fdObject == NULL) {
1111 free_ssl(env, object);
1112 free_ssl_ctx(env, object);
1113 throwIOExceptionStr(env,
1114 "couldn't get the file descriptor from the socket impl");
1115 return (jboolean) false;
1118 fd = jniGetFDFromFileDescriptor(env, fdObject);
1120 ssl_session = (SSL_SESSION *) session;
1122 ret = SSL_set_fd(ssl, fd);
1125 throwIOExceptionWithSslErrors(env, ret, 0,
1126 "Error setting the file descriptor");
1127 free_ssl(env, object);
1128 free_ssl_ctx(env, object);
1129 return (jboolean) false;
1132 if (ssl_session != NULL) {
1133 ret = SSL_set_session(ssl, ssl_session);
1137 * Translate the error, and throw if it turns out to be a real
1140 int sslErrorCode = SSL_get_error(ssl, ret);
1141 if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
1142 throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1144 free_ssl(env, object);
1145 free_ssl_ctx(env, object);
1146 return (jboolean) false;
1152 * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
1153 * forever and we can use select() to find out if the socket is ready.
1155 int mode = fcntl(fd, F_GETFL);
1156 if (mode == -1 || fcntl(fd, F_SETFL, mode | O_NONBLOCK) == -1) {
1157 throwIOExceptionStr(env, "Unable to make socket non blocking");
1158 free_ssl(env, object);
1159 free_ssl_ctx(env, object);
1160 return (jboolean) false;
1164 * Create our special application data.
1166 if (sslCreateAppData(ssl) == -1) {
1167 throwIOExceptionStr(env, "Unable to create application data");
1168 free_ssl(env, object);
1169 free_ssl_ctx(env, object);
1171 return (jboolean) false;
1174 APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
1175 env->SetIntField(object, field_ssl, (int)ssl);
1177 int timeout = (int)env->GetIntField(object, field_timeout);
1179 while (data->aliveAndKicking) {
1181 ret = SSL_connect(ssl);
1184 } else if (errno == EINTR) {
1187 // LOGD("SSL_connect: result %d, errno %d, timeout %d", ret, errno, timeout);
1188 int error = SSL_get_error(ssl, ret);
1191 * If SSL_connect doesn't succeed due to the socket being
1192 * either unreadable or unwritable, we use sslSelect to
1193 * wait for it to become ready. If that doesn't happen
1194 * before the specified timeout or an error occurs, we
1195 * cancel the handshake. Otherwise we try the SSL_connect
1198 if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
1199 data->waitingThreads++;
1200 int selectResult = sslSelect(error, fd, data, timeout);
1202 if (selectResult == -1) {
1203 throwIOExceptionWithSslErrors(env, -1, error,
1205 free_ssl(env, object);
1206 free_ssl_ctx(env, object);
1207 return (jboolean) false;
1208 } else if (selectResult == 0) {
1209 throwSocketTimeoutException(env, "SSL handshake timed out");
1210 freeSslErrorState();
1211 free_ssl(env, object);
1212 free_ssl_ctx(env, object);
1213 return (jboolean) false;
1216 LOGE("Unknown error %d during connect", error);
1224 * Translate the error, and throw if it turns out to be a real
1227 int sslErrorCode = SSL_get_error(ssl, ret);
1228 if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
1229 throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1230 "SSL handshake failure");
1231 free_ssl(env, object);
1232 free_ssl_ctx(env, object);
1233 return (jboolean) false;
1237 if (ssl_session != NULL) {
1238 ret = SSL_session_reused(ssl);
1239 // if (ret == 1) LOGD("A session was reused");
1240 // else LOGD("A new session was negotiated");
1241 return (jboolean) ret;
1243 // LOGD("A new session was negotiated");
1244 return (jboolean) 0;
1246 // LOGD("LEAVE connect");
1249 static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession(JNIEnv* env, jobject object,
1252 return (jint) SSL_get1_session((SSL *) jssl);
1255 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept(JNIEnv* env, jobject object,
1256 jobject socketObject, jint jssl_ctx, jboolean client_mode)
1264 ssl_ctx = (SSL_CTX *)jssl_ctx;
1266 ssl = create_ssl(env, object, ssl_ctx);
1268 throwIOExceptionWithSslErrors(env, 0, 0,
1269 "Unable to create SSL structure");
1273 jobject socketImplObject = env->GetObjectField(socketObject, field_mImpl);
1274 if (socketImplObject == NULL) {
1275 free_ssl(env, object);
1276 throwIOExceptionStr(env, "couldn't get the socket impl from the socket");
1280 jobject fdObject = env->GetObjectField(socketImplObject, field_mFD);
1281 if (fdObject == NULL) {
1282 free_ssl(env, object);
1283 throwIOExceptionStr(env, "couldn't get the file descriptor from the socket impl");
1288 sd = jniGetFDFromFileDescriptor(env, fdObject);
1290 bio = BIO_new_socket(sd, BIO_NOCLOSE);
1292 /* The parameter client_mode must be 1 */
1293 if (client_mode != 0)
1295 BIO_set_ssl_mode(bio, client_mode);
1297 SSL_set_bio(ssl, bio, bio);
1300 * Fill in the mydata structure needed for the certificate callback and
1301 * store this in the SSL application data slot.
1304 mydata.object = object;
1305 SSL_set_app_data(ssl, &mydata);
1308 * Do the actual SSL_accept(). It is possible this code is insufficient.
1309 * Maybe we need to deal with all the special SSL error cases (WANT_*),
1310 * just like we do for SSL_connect(). But currently it is looking ok.
1312 ret = SSL_accept(ssl);
1315 * Clear the SSL application data slot again, so we can safely use it for
1316 * our ordinary synchronization structure afterwards. Also, we don't want
1317 * sslDestroyAppData() to think that there is something that needs to be
1318 * freed right now (in case of an error).
1320 SSL_set_app_data(ssl, NULL);
1324 * The other side closed the socket before the handshake could be
1325 * completed, but everything is within the bounds of the TLS protocol.
1326 * We still might want to find out the real reason of the failure.
1328 int sslErrorCode = SSL_get_error(ssl, ret);
1329 if (sslErrorCode == SSL_ERROR_NONE ||
1330 sslErrorCode == SSL_ERROR_SYSCALL && errno == 0) {
1331 throwIOExceptionStr(env, "Connection closed by peer");
1333 throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1334 "Trouble accepting connection");
1336 free_ssl(env, object);
1338 } else if (ret < 0) {
1340 * Translate the error and throw exception. We are sure it is an error
1343 int sslErrorCode = SSL_get_error(ssl, ret);
1344 throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
1345 "Trouble accepting connection");
1346 free_ssl(env, object);
1351 * Make socket non-blocking, so SSL_read() and SSL_write() don't hang
1352 * forever and we can use select() to find out if the socket is ready.
1354 int fd = SSL_get_fd(ssl);
1355 int mode = fcntl(fd, F_GETFL);
1356 if (mode == -1 || fcntl(fd, F_SETFL, mode | O_NONBLOCK) == -1) {
1357 throwIOExceptionStr(env, "Unable to make socket non blocking");
1358 free_ssl(env, object);
1363 * Create our special application data.
1365 if (sslCreateAppData(ssl) == -1) {
1366 throwIOExceptionStr(env, "Unable to create application data");
1367 free_ssl(env, object);
1373 * Loads the desired protocol for the OpenSSL client and enables it.
1374 * For example SSL_OP_NO_TLSv1 means do not use TLS v. 1.
1376 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols(JNIEnv* env, jobject object,
1379 if (protocol != 0x00000000L) {
1380 if (protocol & SSL_OP_NO_SSLv3)
1381 LOGD("SSL_OP_NO_SSLv3 is set");
1382 if (protocol & SSL_OP_NO_TLSv1)
1383 LOGD("SSL_OP_NO_TLSv1 is set");
1385 SSL_CTX* ctx = (SSL_CTX*)env->GetIntField(object, field_ssl_ctx);
1386 int options = SSL_CTX_get_options(ctx);
1387 options |= protocol; // Note: SSLv2 disabled earlier.
1388 SSL_CTX_set_options(ctx, options);
1393 * Loads the ciphers suites that are supported by the OpenSSL client
1394 * and returns them in a string array.
1396 static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites(JNIEnv* env,
1399 SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
1400 if (ssl_ctx == NULL) {
1403 jobjectArray result = makeCipherList(env, ssl_ctx);
1404 SSL_CTX_free(ssl_ctx);
1409 * Loads the ciphers suites that are enabled in the OpenSSL client
1410 * and returns them in a string array.
1412 static jobjectArray OpenSSLSocketImpl_nativeGetEnabledCipherSuites(JNIEnv* env,
1413 jclass, jint ssl_ctx_address)
1416 reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
1417 return makeCipherList(env, ssl_ctx);
1421 * Sets the ciphers suites that are enabled in the OpenSSL client.
1423 static void OpenSSLSocketImpl_nativeSetEnabledCipherSuites(JNIEnv* env, jclass,
1424 jint ssl_ctx_address, jstring controlString)
1427 reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
1428 setEnabledCipherSuites(env, controlString, ssl_ctx);
1431 static jobjectArray makeCipherList(JNIEnv* env, SSL* ssl) {
1432 // Count the ciphers.
1433 int cipherCount = 0;
1434 while (SSL_get_cipher_list(ssl, cipherCount) != NULL) {
1438 // Create a String[].
1439 jclass stringClass = env->FindClass("java/lang/String");
1440 if (stringClass == NULL) {
1443 jobjectArray array = env->NewObjectArray(cipherCount, stringClass, NULL);
1444 if (array == NULL) {
1448 // Fill in the cipher names.
1449 for (int i = 0; i < cipherCount; ++i) {
1450 const char* c = SSL_get_cipher_list(ssl, i);
1451 env->SetObjectArrayElement(array, i, env->NewStringUTF(c));
1456 jobjectArray makeCipherList(JNIEnv* env, SSL_CTX* ssl_ctx) {
1457 SSL* ssl = SSL_new(ssl_ctx);
1461 jobjectArray result = makeCipherList(env, ssl);
1466 void setEnabledCipherSuites(JNIEnv* env, jstring controlString, SSL_CTX* ssl_ctx) {
1467 const char* str = env->GetStringUTFChars(controlString, NULL);
1468 int rc = SSL_CTX_set_cipher_list(ssl_ctx, str);
1469 env->ReleaseStringUTFChars(controlString, str);
1471 freeSslErrorState();
1472 jniThrowException(env, "java/lang/IllegalArgumentException",
1473 "Illegal cipher suite strings.");
1477 #define SSL_AUTH_MASK 0x00007F00L
1478 #define SSL_aRSA 0x00000100L /* Authenticate with RSA */
1479 #define SSL_aDSS 0x00000200L /* Authenticate with DSS */
1480 #define SSL_DSS SSL_aDSS
1481 #define SSL_aFZA 0x00000400L
1482 #define SSL_aNULL 0x00000800L /* no Authenticate, ADH */
1483 #define SSL_aDH 0x00001000L /* no Authenticate, ADH */
1484 #define SSL_aKRB5 0x00002000L /* Authenticate with KRB5 */
1485 #define SSL_aECDSA 0x00004000L /* Authenticate with ECDSA */
1488 * Sets the client's crypto algorithms and authentication methods.
1490 static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod(JNIEnv* env,
1500 ssl = getSslPointer(env, object, true);
1505 cipher = SSL_get_current_cipher(ssl);
1507 alg = cipher->algorithms;
1509 switch (alg&SSL_AUTH_MASK) {
1533 ret = env->NewStringUTF(au);
1539 * OpenSSL read function (1): only one chunk is read (returned as jint).
1541 static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read(JNIEnv* env, jobject object, jint timeout)
1543 SSL *ssl = getSslPointer(env, object, true);
1548 unsigned char byteRead;
1552 int ret = sslRead(ssl, (char *) &byteRead, 1, &returnCode, &errorCode, timeout);
1555 case THROW_EXCEPTION:
1556 // See sslRead() regarding improper failure to handle normal cases.
1557 throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1560 case THROW_SOCKETTIMEOUTEXCEPTION:
1561 throwSocketTimeoutException(env, "Read timed out");
1564 // Propagate EOF upwards.
1567 // Return the actual char read, make sure it stays 8 bits wide.
1568 return ((jint) byteRead) & 0xFF;
1573 * OpenSSL read function (2): read into buffer at offset n chunks.
1574 * Returns 1 (success) or value <= 0 (failure).
1576 static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba(JNIEnv* env, jobject obj, jbyteArray dest, jint offset, jint len, jint timeout)
1578 SSL *ssl = getSslPointer(env, obj, true);
1583 jbyte* bytes = env->GetByteArrayElements(dest, NULL);
1588 sslRead(ssl, (char*) (bytes + offset), len, &returnCode, &errorCode, timeout);
1590 env->ReleaseByteArrayElements(dest, bytes, 0);
1592 if (ret == THROW_EXCEPTION) {
1593 // See sslRead() regarding improper failure to handle normal cases.
1594 throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1597 } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) {
1598 throwSocketTimeoutException(env, "Read timed out");
1606 * OpenSSL write function (1): only one chunk is written.
1608 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write(JNIEnv* env, jobject object, jint b)
1610 SSL *ssl = getSslPointer(env, object, true);
1617 char buf[1] = { (char) b };
1618 int ret = sslWrite(ssl, buf, 1, &returnCode, &errorCode);
1620 if (ret == THROW_EXCEPTION) {
1621 // See sslWrite() regarding improper failure to handle normal cases.
1622 throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1624 } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) {
1625 throwSocketTimeoutException(env, "Write timed out");
1630 * OpenSSL write function (2): write into buffer at offset n chunks.
1632 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba(JNIEnv* env, jobject obj,
1633 jbyteArray dest, jint offset, jint len)
1635 SSL *ssl = getSslPointer(env, obj, true);
1640 jbyte* bytes = env->GetByteArrayElements(dest, NULL);
1643 int timeout = (int)env->GetIntField(obj, field_timeout);
1644 int ret = sslWrite(ssl, (const char *) (bytes + offset), len,
1645 &returnCode, &errorCode);
1647 env->ReleaseByteArrayElements(dest, bytes, 0);
1649 if (ret == THROW_EXCEPTION) {
1650 // See sslWrite() regarding improper failure to handle normal cases.
1651 throwIOExceptionWithSslErrors(env, returnCode, errorCode,
1653 } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) {
1654 throwSocketTimeoutException(env, "Write timed out");
1659 * Interrupt any pending IO before closing the socket.
1661 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt(
1662 JNIEnv* env, jobject object) {
1663 SSL *ssl = getSslPointer(env, object, false);
1669 * Mark the connection as quasi-dead, then send something to the emergency
1670 * file descriptor, so any blocking select() calls are woken up.
1672 APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
1674 data->aliveAndKicking = 0;
1676 // At most two threads can be waiting.
1683 * OpenSSL close SSL socket function.
1685 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close(
1686 JNIEnv* env, jobject object) {
1687 SSL *ssl = getSslPointer(env, object, false);
1693 * Try to make socket blocking again. OpenSSL literature recommends this.
1695 int fd = SSL_get_fd(ssl);
1697 int mode = fcntl(fd, F_GETFL);
1698 if (mode == -1 || fcntl(fd, F_SETFL, mode & ~O_NONBLOCK) == -1) {
1699 // throwIOExceptionStr(env, "Unable to make socket blocking again");
1700 // LOGW("Unable to make socket blocking again");
1704 int ret = SSL_shutdown(ssl);
1708 * Shutdown was not successful (yet), but there also
1709 * is no error. Since we can't know whether the remote
1710 * server is actually still there, and we don't want to
1711 * get stuck forever in a second SSL_shutdown() call, we
1712 * simply return. This is not security a problem as long
1713 * as we close the underlying socket, which we actually
1714 * do, because that's where we are just coming from.
1719 * Shutdown was sucessful. We can safely return. Hooray!
1724 * Everything else is a real error condition. We should
1725 * let the Java layer know about this by throwing an
1728 throwIOExceptionWithSslErrors(env, ret, 0, "SSL shutdown failed.");
1732 freeSslErrorState();
1733 free_ssl(env, object);
1734 free_ssl_ctx(env, object);
1738 * OpenSSL free SSL socket function.
1740 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_free(JNIEnv* env, jobject object)
1742 free_ssl(env, object);
1743 free_ssl_ctx(env, object);
1747 * Verifies an RSA signature.
1749 static int org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_verifysignature(JNIEnv* env, jclass clazz,
1750 jbyteArray msg, jbyteArray sig, jstring algorithm, jbyteArray mod, jbyteArray exp) {
1752 // LOGD("Entering verifysignature()");
1754 if (msg == NULL || sig == NULL || algorithm == NULL || mod == NULL || exp == NULL) {
1755 jniThrowNullPointerException(env, NULL);
1761 jbyte* msgBytes = env->GetByteArrayElements(msg, NULL);
1762 jint msgLength = env->GetArrayLength(msg);
1764 jbyte* sigBytes = env->GetByteArrayElements(sig, NULL);
1765 jint sigLength = env->GetArrayLength(sig);
1767 jbyte* modBytes = env->GetByteArrayElements(mod, NULL);
1768 jint modLength = env->GetArrayLength(mod);
1770 jbyte* expBytes = env->GetByteArrayElements(exp, NULL);
1771 jint expLength = env->GetArrayLength(exp);
1773 const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
1775 RSA* rsa = rsaCreateKey((unsigned char*) modBytes, modLength, (unsigned char*) expBytes, expLength);
1777 result = rsaVerify((unsigned char*) msgBytes, msgLength, (unsigned char*) sigBytes, sigLength,
1778 (char*) algorithmChars, rsa);
1782 env->ReleaseStringUTFChars(algorithm, algorithmChars);
1784 env->ReleaseByteArrayElements(exp, expBytes, JNI_ABORT);
1785 env->ReleaseByteArrayElements(mod, modBytes, JNI_ABORT);
1786 env->ReleaseByteArrayElements(sig, sigBytes, JNI_ABORT);
1787 env->ReleaseByteArrayElements(msg, msgBytes, JNI_ABORT);
1790 int error = ERR_get_error();
1793 ERR_error_string_n(error, message, sizeof(message));
1794 jniThrowRuntimeException(env, message);
1796 jniThrowRuntimeException(env, "Internal error during verification");
1798 freeSslErrorState();
1805 * The actual JNI methods' mapping table for the class OpenSSLSocketImpl.
1807 static JNINativeMethod sMethods[] =
1809 {"nativeinitstatic", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_initstatic},
1810 {"nativeinit", "(Ljava/lang/String;Ljava/lang/String;[B)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_init},
1811 {"nativeconnect", "(ILjava/net/Socket;ZI)Z", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect},
1812 {"nativegetsslsession", "(I)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession},
1813 {"nativeread", "(I)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read},
1814 {"nativeread", "([BIII)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba},
1815 {"nativewrite", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write},
1816 {"nativewrite", "([BII)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba},
1817 {"nativeaccept", "(Ljava/net/Socket;IZ)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept},
1818 {"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols},
1819 {"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites},
1820 {"nativeGetEnabledCipherSuites", "(I)[Ljava/lang/String;", (void*) OpenSSLSocketImpl_nativeGetEnabledCipherSuites},
1821 {"nativeSetEnabledCipherSuites", "(ILjava/lang/String;)V", (void*) OpenSSLSocketImpl_nativeSetEnabledCipherSuites},
1822 {"nativecipherauthenticationmethod", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod},
1823 {"nativeinterrupt", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt},
1824 {"nativeclose", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close},
1825 {"nativefree", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_free},
1826 {"nativeverifysignature", "([B[BLjava/lang/String;[B[B)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_verifysignature},
1830 * Register the native methods with JNI for the class OpenSSLSocketImpl.
1832 extern "C" int register_org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl(JNIEnv* env)
1834 jclass clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
1835 if (clazz == NULL) {
1836 LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
1840 jclass socketClass = env->FindClass("java/net/Socket");
1841 if (socketClass == NULL) {
1842 LOGE("Can't find class java.net.Socket");
1846 field_mImpl = env->GetFieldID(socketClass, "impl", "Ljava/net/SocketImpl;");
1847 if (field_mImpl == NULL) {
1848 LOGE("Can't find field impl in class java.net.Socket");
1852 jclass socketImplClass = env->FindClass("java/net/SocketImpl");
1853 if (socketImplClass == NULL) {
1854 LOGE("Can't find class java.net.SocketImpl");
1858 field_mFD = env->GetFieldID(socketImplClass, "fd", "Ljava/io/FileDescriptor;");
1859 if (field_mFD == NULL) {
1860 LOGE("Can't find field fd in java.net.SocketImpl");
1864 jclass fdclazz = env->FindClass("java/io/FileDescriptor");
1865 if (fdclazz == NULL) {
1866 LOGE("Can't find java/io/FileDescriptor");
1870 field_descriptor = env->GetFieldID(fdclazz, "descriptor", "I");
1871 if (field_descriptor == NULL) {
1872 LOGE("Can't find FileDescriptor.descriptor");
1876 int rc = jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl",
1877 sMethods, NELEM(sMethods));
1879 // Note: do these after the registration of native methods, because
1880 // there is a static method "initstatic" that's called when the
1881 // OpenSSLSocketImpl class is first loaded, and that required
1882 // a native method to be associated with it.
1883 field_ssl_ctx = env->GetFieldID(clazz, "ssl_ctx", "I");
1884 if (field_ssl_ctx == NULL) {
1885 LOGE("Can't find OpenSSLSocketImpl.ssl_ctx");
1889 field_ssl = env->GetFieldID(clazz, "ssl", "I");
1890 if (field_ssl == NULL) {
1891 LOGE("Can't find OpenSSLSocketImpl.ssl");
1895 field_timeout = env->GetFieldID(clazz, "timeout", "I");
1896 if (field_timeout == NULL) {
1897 LOGE("Can't find OpenSSLSocketImpl.timeout");