diff options
-rw-r--r-- | Source/WebKit/android/jni/WebCoreFrameBridge.cpp | 94 |
1 files changed, 56 insertions, 38 deletions
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<WebUrlLoaderClient*>(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_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8; - const unsigned char* pkeyChars = reinterpret_cast<const unsigned char*>(pkeyBytes.get()); - pkcs8.reset(d2i_PKCS8_PRIV_KEY_INFO(NULL, &pkeyChars, pkeyBytes.size())); - if (!pkcs8.get()) { - client->sslClientCert(NULL, NULL); - return; - } - base::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> 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<X509, X509_free> first; @@ -1865,20 +1838,17 @@ static void SslClientCert(JNIEnv *env, jobject obj, int handle, jbyteArray pkey, ScopedLocalRef<jbyteArray> cert(env, reinterpret_cast<jbyteArray>(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<const char*>(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<WebUrlLoaderClient*>(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_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8; + const unsigned char* pkeyChars = reinterpret_cast<const unsigned char*>(pkeyBytes.get()); + pkcs8.reset(d2i_PKCS8_PRIV_KEY_INFO(NULL, &pkeyChars, pkeyBytes.size())); + if (!pkcs8.get()) { + client->sslClientCert(NULL, NULL); + return; + } + base::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> 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<WebUrlLoaderClient*>(handle); + EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(static_cast<uintptr_t>(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 }, }; |