From 1e836a3d15278de9346a7b162edc7147266f7432 Mon Sep 17 00:00:00 2001 From: Selim Gurun Date: Fri, 4 May 2012 13:29:37 -0700 Subject: Fix ssl client certs to use the private key ctx Bug: 6249185 Change-Id: Id9d57dc9adcbb37d1a39d33c6abd8e896ced1785 --- Source/WebKit/android/jni/WebCoreFrameBridge.cpp | 94 ++++++++++++++---------- 1 file changed, 56 insertions(+), 38 deletions(-) (limited to 'Source/WebKit') diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp index 7a2971a..af582fa 100644 --- a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -1824,39 +1824,12 @@ static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_er client->cancelSslCertError(cert_error); } -static void SslClientCert(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, jobjectArray chain) +static net::X509Certificate* getX509Cert(JNIEnv *env, jobjectArray chain) { - WebUrlLoaderClient* client = reinterpret_cast(handle); - if (pkey == NULL || chain == NULL) { - client->sslClientCert(NULL, NULL); - return; - } - - // Based on Android's NativeCrypto_SSL_use_PrivateKey - ScopedByteArrayRO pkeyBytes(env, pkey); - if (pkeyBytes.get() == NULL) { - client->sslClientCert(NULL, NULL); - return; - } - - base::ScopedOpenSSL pkcs8; - const unsigned char* pkeyChars = reinterpret_cast(pkeyBytes.get()); - pkcs8.reset(d2i_PKCS8_PRIV_KEY_INFO(NULL, &pkeyChars, pkeyBytes.size())); - if (!pkcs8.get()) { - client->sslClientCert(NULL, NULL); - return; - } - base::ScopedOpenSSL privateKey(EVP_PKCS82PKEY(pkcs8.get())); - if (!privateKey.get()) { - client->sslClientCert(NULL, NULL); - return; - } - // Based on Android's NativeCrypto_SSL_use_certificate int length = env->GetArrayLength(chain); if (length == 0) { - client->sslClientCert(NULL, NULL); - return; + return NULL; } base::ScopedOpenSSL first; @@ -1865,20 +1838,17 @@ static void SslClientCert(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, ScopedLocalRef cert(env, reinterpret_cast(env->GetObjectArrayElement(chain, i))); if (cert.get() == NULL) { - client->sslClientCert(NULL, NULL); - return; + return NULL; } ScopedByteArrayRO certBytes(env, cert.get()); if (certBytes.get() == NULL) { - client->sslClientCert(NULL, NULL); - return; + return NULL; } const char* data = reinterpret_cast(certBytes.get()); int length = certBytes.size(); X509* x509 = net::X509Certificate::CreateOSCertHandleFromBytes(data, length); if (x509 == NULL) { - client->sslClientCert(NULL, NULL); - return; + return NULL; } if (i == 0) { first.reset(x509); @@ -1891,10 +1861,39 @@ static void SslClientCert(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, for (size_t i = 0; i < rest.size(); i++) { certChain[i] = rest[i]->get(); } - net::X509Certificate* certificate - = net::X509Certificate::CreateFromHandle(first.get(), + return net::X509Certificate::CreateFromHandle(first.get(), net::X509Certificate::SOURCE_FROM_NETWORK, certChain); +} + +static void SslClientCertPKCS8(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, jobjectArray chain) +{ + WebUrlLoaderClient* client = reinterpret_cast(handle); + if (pkey == NULL || chain == NULL) { + client->sslClientCert(NULL, NULL); + return; + } + + // Based on Android's NativeCrypto_SSL_use_PrivateKey + ScopedByteArrayRO pkeyBytes(env, pkey); + if (pkeyBytes.get() == NULL) { + client->sslClientCert(NULL, NULL); + return; + } + + base::ScopedOpenSSL pkcs8; + const unsigned char* pkeyChars = reinterpret_cast(pkeyBytes.get()); + pkcs8.reset(d2i_PKCS8_PRIV_KEY_INFO(NULL, &pkeyChars, pkeyBytes.size())); + if (!pkcs8.get()) { + client->sslClientCert(NULL, NULL); + return; + } + base::ScopedOpenSSL privateKey(EVP_PKCS82PKEY(pkcs8.get())); + if (!privateKey.get()) { + client->sslClientCert(NULL, NULL); + return; + } + net::X509Certificate* certificate = getX509Cert(env, chain); if (certificate == NULL) { client->sslClientCert(NULL, NULL); return; @@ -1902,6 +1901,23 @@ static void SslClientCert(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, client->sslClientCert(privateKey.release(), certificate); } +static void SslClientCertCtx(JNIEnv *env, jobject obj, int handle, jint ctx, jobjectArray chain) +{ + WebUrlLoaderClient* client = reinterpret_cast(handle); + EVP_PKEY* pkey = reinterpret_cast(static_cast(ctx)); + if (pkey == NULL || chain == NULL) { + client->sslClientCert(NULL, NULL); + return; + } + net::X509Certificate* certificate = getX509Cert(env, chain); + if (certificate == NULL) { + client->sslClientCert(NULL, NULL); + return; + } + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + client->sslClientCert(pkey, certificate); +} + // ---------------------------------------------------------------------------- /* @@ -1960,8 +1976,10 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = { (void*) SslCertErrorProceed }, { "nativeSslCertErrorCancel", "(II)V", (void*) SslCertErrorCancel }, + { "nativeSslClientCert", "(II[[B)V", + (void*) SslClientCertCtx }, { "nativeSslClientCert", "(I[B[[B)V", - (void*) SslClientCert }, + (void*) SslClientCertPKCS8 }, { "nativeGetShouldStartScrolledRight", "(I)Z", (void*) GetShouldStartScrolledRight }, }; -- cgit v1.1