Fix OpenSSLSessionImpl.getCreationTime and getLastAccessedTime.
This addresses one part of this abandoned change from ursg:
https://android-git.corp.google.com/g/4743
I've also tidied up the native method names to use the harmony "-Impl"
convention, removed useless methods that just forward to a native method,
and removed dead code. I've canonicalized some of the duplication too,
but I want to go through the rest of out OpenSSL code before I really start
trying to remove the duplication.
When this is submitted, I'll fix the other (unrelated) bug the abandoned
change addressed.
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
index b218271..9aa4b86 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
@@ -89,47 +89,18 @@
this.sessionContext = sessionContext;
initializeNative(derData);
}
-
- /**
- * Returns the identifier of the actual OpenSSL session.
- */
- private native byte[] nativegetid();
/**
* Gets the identifier of the actual SSL session
* @return array of sessions' identifiers.
*/
- public byte[] getId() {
- return nativegetid();
- }
-
- /**
- * Gets the creation time of the OpenSSL session.
- * @return the session's creation time in milli seconds since January
- * 1st, 1970
- */
- private native long nativegetcreationtime();
-
- /**
- * Serialize the native state of the session ( ID, cypher, keys - but
- * not certs ), using openSSL i2d_SSL_SESSION()
- *
- * @return the DER encoding of the session.
- */
- private native byte[] nativeserialize();
-
- /**
- * Create a SSL_SESSION object using d2i_SSL_SESSION.
- */
- private native int nativedeserialize(byte[] data, int size);
+ public native byte[] getId();
/**
* Get the session object in DER format. This allows saving the session
* data or sharing it with other processes.
*/
- byte[] getEncoded() {
- return nativeserialize();
- }
+ native byte[] getEncoded();
/**
* Init the underlying native object from DER data. This
@@ -137,35 +108,28 @@
* @throws IOException
*/
private void initializeNative(byte[] derData) throws IOException {
- this.session = nativedeserialize(derData, derData.length);
- if (this.session == 0) {
- throw new IOException("Invalid session data");
- }
+ this.session = initializeNativeImpl(derData, derData.length);
+ if (this.session == 0) {
+ throw new IOException("Invalid session data");
+ }
}
-
+ private native int initializeNativeImpl(byte[] data, int size);
/**
* Gets the creation time of the SSL session.
- * @return the session's creation time in milli seconds since 12.00 PM,
- * January 1st, 1970
+ * @return the session's creation time in milliseconds since the epoch
*/
- public long getCreationTime(){
- return nativegetcreationtime();
- }
+ public native long getCreationTime();
/**
* Gives the last time this concrete SSL session was accessed. Accessing
* here is to mean that a new connection with the same SSL context data was
* established.
*
- * @return the session's accessing time in milli seconds since 12.00 PM,
- * January 1st, 1970
+ * @return the session's last access time in milliseconds since the epoch
*/
public long getLastAccessedTime() {
- if (lastAccessedTime == 0)
- return nativegetcreationtime();
- else
- return lastAccessedTime;
+ return (lastAccessedTime == 0) ? getCreationTime() : lastAccessedTime;
}
/**
@@ -220,7 +184,7 @@
/**
* Returns the X509 certificates of the peer in the PEM format.
*/
- private native byte[][] nativegetpeercertificates();
+ private native byte[][] getPeerCertificatesImpl();
/**
* Gives the certificate(s) of the peer in this SSL session
@@ -230,14 +194,14 @@
* @return an array of X509 certificates (the peer's one first and then
* eventually that of the certification authority) or null if no
* certificate were used during the SSL connection.
- * @throws <code>SSLPeerUnverifiedcertificateException</code> if either a
+ * @throws <code>SSLPeerUnverifiedCertificateException</code> if either a
* not X509 certificate was used (i.e. Kerberos certificates) or the
* peer could not be verified.
*/
public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
if (peerCertificateChain == null) {
try {
- byte[][] bytes = nativegetpeercertificates();
+ byte[][] bytes = getPeerCertificatesImpl();
if (bytes == null) throw new SSLPeerUnverifiedException("No certificate available");
peerCertificateChain = new javax.security.cert.X509Certificate[bytes.length];
@@ -306,11 +270,6 @@
}
/**
- * Returns via OpenSSL call the actual peer host name.
- */
- private native String nativegetpeerhost();
-
- /**
* The peer's host name used in this SSL session is returned. It is the host
* name of the client for the server; and that of the server for the client.
* It is not a reliable way to get a fully qualified host name: it is mainly
@@ -322,15 +281,9 @@
*/
public String getPeerHost() {
return peerHost;
- //return nativegetpeerhost();
}
/**
- * Returns via OpenSSL call the actual peer port number.
- */
- private native String nativegetpeerport();
-
- /**
* Gives the peer's port number for the actual SSL session. It is the port
* number of the client for the server; and that of the server for the
* client. It is not a reliable way to get a peer's port number: it is
@@ -341,29 +294,16 @@
*/
public int getPeerPort() {
return peerPort;
- //return Integer.parseInt(nativegetpeerport());
}
/**
- * Returns via OpenSSL call the actual cipher suite in use.
- */
- private native String nativegetciphersuite();
-
- /**
* Gives back a string identifier of the crypto tools used in the actual SSL
* session. For example AES_256_WITH_MD5.
*
* @return an identifier for all the cryptographic algorithms used in the
* actual SSL session.
*/
- public String getCipherSuite() {
- return nativegetciphersuite();
- }
-
- /**
- * Returns via OpenSSL call the actual version of the SSL protocol.
- */
- private native String nativegetprotocol();
+ public native String getCipherSuite();
/**
* Gives back the standard version name of the SSL protocol used in all
@@ -373,9 +313,7 @@
* connections pertaining to this SSL session.
*
*/
- public String getProtocol() {
- return nativegetprotocol();
- }
+ public native String getProtocol();
/**
* Gives back the context to which the actual SSL session is bound. A SSL
@@ -406,8 +344,7 @@
if (isValid
&& context != null
&& context.getSessionTimeout() != 0
- && lastAccessedTime + context.getSessionTimeout() > System
- .currentTimeMillis()) {
+ && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) {
isValid = false;
}
return isValid;
@@ -510,14 +447,11 @@
values.remove(name, AccessController.getContext());
}
- private native void nativefree(int session);
-
- /**
- * Frees the OpenSSL session in the memory.
- */
protected void finalize() {
synchronized (OpenSSLSocketImpl.class) {
- nativefree(session);
+ freeImpl(session);
}
}
+
+ private native void freeImpl(int session);
}
diff --git a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
index 324dacf..e0ea0b8 100644
--- a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
+++ b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
@@ -16,8 +16,10 @@
#define LOG_TAG "OpenSSLSessionImpl"
+#include "AndroidSystemNatives.h"
+#include "JNIHelp.h"
+
#include <jni.h>
-#include <JNIHelp.h>
#include <stdio.h>
#include <string.h>
@@ -35,107 +37,78 @@
#include "org_apache_harmony_xnet_provider_jsse_common.h"
-/**
- * Module scope variables initialized during JNI registration.
- */
static jfieldID field_session;
-static SSL_SESSION *getSslSessionPointer(JNIEnv* env, jobject object) {
- SSL_SESSION* session = (SSL_SESSION *)env->GetIntField(object, field_session);
-
- return session;
+static SSL_SESSION* getSslSessionPointer(JNIEnv* env, jobject object) {
+ return reinterpret_cast<SSL_SESSION*>(env->GetIntField(object, field_session));
}
-/**
- * Gets the peer certificate in the chain and fills a byte array with the
- * information therein.
- */
-static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeercertificates(JNIEnv* env,
+// Fills a byte[][] with the peer certificates in the chain.
+static jobjectArray OpenSSLSessionImpl_getPeerCertificatesImpl(JNIEnv* env,
jobject object, jint jssl)
{
- SSL_SESSION *ssl_session;
- SSL_CTX* ssl_ctx;
- SSL* ssl;
- STACK_OF(X509) *chain;
- jobjectArray objectArray;
-
- ssl_session = getSslSessionPointer(env, object);
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ssl_ctx);
+ SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+ SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+ SSL* ssl = SSL_new(ssl_ctx);
SSL_set_session(ssl, ssl_session);
- chain = SSL_get_peer_cert_chain(ssl);
-
- objectArray = getcertificatebytes(env, chain);
+ STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
+ jobjectArray objectArray = getcertificatebytes(env, chain);
SSL_free(ssl);
SSL_CTX_free(ssl_ctx);
-
return objectArray;
}
/**
- * Serialize the session.
- * See apache mod_ssl
+ * Serializes the native state of the session (ID, cipher, and keys but
+ * not certificates). Returns a byte[] containing the DER-encoded state.
+ * See apache mod_ssl.
*/
-static jbyteArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_serialize(JNIEnv* env, jobject object)
-{
- SSL_SESSION * ssl_session;
- jbyteArray bytes = NULL;
- jbyte *tmp;
- int size;
- unsigned char *ucp;
+static jbyteArray OpenSSLSessionImpl_getEncoded(JNIEnv* env, jobject object) {
+ SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+ if (ssl_session == NULL) {
+ return NULL;
+ }
- ssl_session = getSslSessionPointer(env, object);
- if (ssl_session == NULL) {
- return NULL;
- }
+ // Compute the size of the DER data
+ int size = i2d_SSL_SESSION(ssl_session, NULL);
+ if (size == 0) {
+ return NULL;
+ }
- // Compute the size of the DER data
- size = i2d_SSL_SESSION(ssl_session, NULL);
- if (size == 0) {
- return NULL;
- }
-
- bytes = env->NewByteArray(size);
- if (bytes != NULL) {
- tmp = env->GetByteArrayElements(bytes, NULL);
- ucp = (unsigned char *) tmp;
+ jbyteArray bytes = env->NewByteArray(size);
+ if (bytes != NULL) {
+ jbyte* tmp = env->GetByteArrayElements(bytes, NULL);
+ unsigned char* ucp = reinterpret_cast<unsigned char*>(tmp);
i2d_SSL_SESSION(ssl_session, &ucp);
env->ReleaseByteArrayElements(bytes, tmp, 0);
- }
+ }
- return bytes;
-
+ return bytes;
}
/**
* Deserialize the session.
*/
-static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_deserialize(JNIEnv* env, jobject object, jbyteArray bytes, jint size)
-{
- const unsigned char *ucp;
- jbyte *tmp;
- SSL_SESSION *ssl_session;
+static jint OpenSSLSessionImpl_initializeNativeImpl(JNIEnv* env, jobject object, jbyteArray bytes, jint size) {
+ if (bytes == NULL) {
+ return 0;
+ }
- if (bytes != NULL) {
- tmp = env->GetByteArrayElements(bytes, NULL);
- ucp = (const unsigned char *) tmp;
- ssl_session = d2i_SSL_SESSION(NULL, &ucp, (long) size);
- env->ReleaseByteArrayElements(bytes, tmp, 0);
+ jbyte* tmp = env->GetByteArrayElements(bytes, NULL);
+ const unsigned char* ucp = reinterpret_cast<const unsigned char*>(tmp);
+ SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, size);
+ env->ReleaseByteArrayElements(bytes, tmp, 0);
- return (jint) ssl_session;
- }
- return 0;
+ return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
}
/**
* Gets and returns in a byte array the ID of the actual SSL session.
*/
-static jbyteArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getid(JNIEnv* env, jobject object)
-{
+static jbyteArray OpenSSLSessionImpl_getId(JNIEnv* env, jobject object) {
SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
@@ -151,76 +124,10 @@
* Gets and returns in a long integer the creation's time of the
* actual SSL session.
*/
-static jlong org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getcreationtime(JNIEnv* env, jobject object)
-{
- SSL_SESSION * ssl_session;
-
- ssl_session = getSslSessionPointer(env, object);
-
- // convert the creation time from seconds to milliseconds
- return (jlong)(1000L * ssl_session->time);
-}
-
-/**
- * Gets and returns in a string the peer's host's name.
- */
-static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerhost(JNIEnv* env, jobject object)
-{
- SSL_CTX *ssl_ctx;
- SSL *ssl;
- SSL_SESSION *ssl_session;
- BIO *bio;
- char* hostname;
- jstring result;
-
- ssl_session = getSslSessionPointer(env, object);
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ssl_ctx);
-
- SSL_set_session(ssl, ssl_session);
-
- bio = SSL_get_rbio(ssl);
-
- hostname = BIO_get_conn_hostname(bio);
-
- /* Notice: hostname can be NULL */
- result = env->NewStringUTF(hostname);
-
- SSL_free(ssl);
- SSL_CTX_free(ssl_ctx);
-
- return result;
-}
-
-/**
- * Gets and returns in a string the peer's port name (https, ftp, etc.).
- */
-static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerport(JNIEnv* env, jobject object)
-{
- SSL_CTX *ssl_ctx;
- SSL *ssl;
- SSL_SESSION *ssl_session;
- BIO *bio;
- char *port;
- jstring result;
-
- ssl_session = getSslSessionPointer(env, object);
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ssl_ctx);
-
- SSL_set_session(ssl, ssl_session);
-
- bio = SSL_get_rbio(ssl);
- port = BIO_get_conn_port(bio);
-
- /* Notice: port name can be NULL */
- result = env->NewStringUTF(port);
-
- SSL_free(ssl);
- SSL_CTX_free(ssl_ctx);
-
+static jlong OpenSSLSessionImpl_getCreationTime(JNIEnv* env, jobject object) {
+ SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+ jlong result = SSL_SESSION_get_time(ssl_session);
+ result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
return result;
}
@@ -228,48 +135,32 @@
* Gets and returns in a string the version of the SSL protocol. If it
* returns the string "unknown" it means that no connection is established.
*/
-static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getprotocol(JNIEnv* env, jobject object)
-{
- SSL_CTX *ssl_ctx;
- SSL *ssl;
- SSL_SESSION *ssl_session;
- const char* protocol;
- jstring result;
-
- ssl_session = getSslSessionPointer(env, object);
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ssl_ctx);
+static jstring OpenSSLSessionImpl_getProtocol(JNIEnv* env, jobject object) {
+ SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+ SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+ SSL* ssl = SSL_new(ssl_ctx);
SSL_set_session(ssl, ssl_session);
- protocol = SSL_get_version(ssl);
-
- result = env->NewStringUTF(protocol);
+ const char* protocol = SSL_get_version(ssl);
+ jstring result = env->NewStringUTF(protocol);
SSL_free(ssl);
SSL_CTX_free(ssl_ctx);
-
return result;
}
/**
* Gets and returns in a string the set of ciphers the actual SSL session uses.
*/
-static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getciphersuite(JNIEnv* env, jobject object)
-{
- SSL_CTX *ssl_ctx;
- SSL *ssl;
- SSL_SESSION *ssl_session;
-
- ssl_session = getSslSessionPointer(env, object);
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ssl_ctx);
+static jstring OpenSSLSessionImpl_getCipherSuite(JNIEnv* env, jobject object) {
+ SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+ SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+ SSL* ssl = SSL_new(ssl_ctx);
SSL_set_session(ssl, ssl_session);
- SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
+ SSL_CIPHER* cipher = SSL_get_current_cipher(ssl);
jstring result = env->NewStringUTF(SSL_CIPHER_get_name(cipher));
SSL_free(ssl);
@@ -280,50 +171,31 @@
/**
* Frees the SSL session.
*/
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_free(JNIEnv* env, jobject object, jint session)
-{
+static void OpenSSLSessionImpl_freeImpl(JNIEnv* env, jobject object, jint session) {
LOGD("Freeing OpenSSL session");
- SSL_SESSION* ssl_session;
- ssl_session = (SSL_SESSION*) session;
+ SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(session);
SSL_SESSION_free(ssl_session);
}
-/**
- * The actual JNI methods' mapping table for the class OpenSSLSessionImpl.
- */
-static JNINativeMethod sMethods[] =
-{
- {"nativegetid", "()[B", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getid},
- {"nativegetcreationtime", "()J", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getcreationtime},
- {"nativegetpeerhost", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerhost},
- {"nativegetpeerport", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerport},
- {"nativegetprotocol", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getprotocol},
- {"nativegetciphersuite", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getciphersuite},
- {"nativegetpeercertificates", "()[[B", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeercertificates},
- {"nativefree", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_free},
- {"nativeserialize", "()[B", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_serialize},
- {"nativedeserialize", "([BI)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_deserialize}
+static JNINativeMethod sMethods[] = {
+ { "freeImpl", "(I)V", (void*) OpenSSLSessionImpl_freeImpl },
+ { "getCipherSuite", "()Ljava/lang/String;", (void*) OpenSSLSessionImpl_getCipherSuite },
+ { "getCreationTime", "()J", (void*) OpenSSLSessionImpl_getCreationTime },
+ { "getEncoded", "()[B", (void*) OpenSSLSessionImpl_getEncoded },
+ { "getId", "()[B", (void*) OpenSSLSessionImpl_getId },
+ { "getPeerCertificatesImpl", "()[[B", (void*) OpenSSLSessionImpl_getPeerCertificatesImpl },
+ { "getProtocol", "()Ljava/lang/String;", (void*) OpenSSLSessionImpl_getProtocol },
+ { "initializeNativeImpl", "([BI)I", (void*) OpenSSLSessionImpl_initializeNativeImpl }
};
-/**
- * Register the native methods with JNI for the class OpenSSLSessionImpl.
- */
-extern "C" int register_org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl(JNIEnv* env)
-{
- int ret;
- jclass clazz;
-
- clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl");
-
+int register_org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl(JNIEnv* env) {
+ jclass clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl");
if (clazz == NULL) {
- LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl");
return -1;
}
field_session = env->GetFieldID(clazz, "session", "I");
- ret = jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl",
+ return jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl",
sMethods, NELEM(sMethods));
-
- return ret;
}
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
index 6eca114..430d117 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
@@ -193,7 +193,6 @@
method = "getCreationTime",
args = {}
)
- @KnownFailure("Time returned is corrupted")
@AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI")
public void test_getCreationTime() {
try {
@@ -235,7 +234,6 @@
method = "getLastAccessedTime",
args = {}
)
- @KnownFailure("Time returned is corrupted")
@AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI")
public void test_getLastAccessedTime() {
try {