Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Unified Diff: net/android/keystore.cc

Issue 11571059: Add net/android/keystore.h (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: new version with simpler signing support Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/android/keystore.cc
diff --git a/net/android/keystore.cc b/net/android/keystore.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e7fc3ee0854742489367a50a67769f0699117532
--- /dev/null
+++ b/net/android/keystore.cc
@@ -0,0 +1,180 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/android/keystore.h"
+
+#include <vector>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/logging.h"
+
+#include "jni/AndroidKeyStore_jni.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ConvertJavaStringToUTF8;
+using base::android::GetApplicationContext;
+using base::android::HasException;
+using base::android::JavaByteArrayToByteVector;
+using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaByteArray;
+using base::android::ToJavaArrayOfByteArray;
+using base::android::ToJavaArrayOfStrings;
+using base::android::JavaArrayOfByteArrayToStringVector;
+
+namespace net {
+namespace android {
+
+namespace {
+
+typedef std::vector<ClientCertRequest*> ClientCertRequestList;
+
+// Global list of active client certificate requests.
+//
+// Note: There is no locking because all functions related to
+// ClientCertRequestList should run on the UI thread.
+ClientCertRequestList g_client_cert_requests;
+
+// Return a new unique request id. Can't be 0.
+int GetNewRequestId() {
+ static int s_last_id;
+
+ int id = ++s_last_id;
+ if (id == INT_MAX)
+ s_last_id = 0;
+ DCHECK(id != 0);
+ return id;
+}
+
+} // namespace
+
+void OnRequestCompletion(
+ JNIEnv* env,
+ jclass /* clazz */,
+ jint request_id,
+ jstring private_key_alias_ref,
+ jobjectArray encoded_chain_ref,
+ jobject private_key_ref) {
+ // Find the certificate request in the active list.
+ // If none found, it was cancelled so return immediately.
+ ClientCertRequest* request = NULL;
+ for (ClientCertRequestList::iterator it = g_client_cert_requests.begin();
+ it != g_client_cert_requests.end(); ++it) {
+ if ((*it)->request_id() == request_id) {
+ // Found it, remove it from the active list.
+ request = (*it);
+ g_client_cert_requests.erase(it);
+ break;
+ }
+ }
+
+ if (!request)
+ return;
+
+ // Convert Java object to their C++ counterparts
+ std::string private_key_alias;
+
+ if (private_key_alias_ref) {
+ private_key_alias = ConvertJavaStringToUTF8(
+ env, private_key_alias_ref);
+ }
+
+ // Convert the encoded chain to a vector of strings.
+ std::vector<std::string> encoded_chain;
+ JavaArrayOfByteArrayToStringVector(
+ env, encoded_chain_ref, &encoded_chain);
+
+ // Call the delegate.
+ request->OnCertificateSelection(private_key_alias,
+ encoded_chain,
+ private_key_ref);
+}
+
+ClientCertRequest::~ClientCertRequest() {
+ if (request_id_ != 0)
+ Cancel();
+}
+
+bool ClientCertRequest::Start(
+ const std::vector<std::string>& key_types,
+ const std::vector<std::string>& principals,
+ const std::string& host_name,
+ int port) {
+
+ // Convert parameters to equivalent Java objects.
+ JNIEnv* env = AttachCurrentThread();
+
+ ScopedJavaLocalRef<jobjectArray> key_types_ref =
+ ToJavaArrayOfStrings(env, key_types);
+ if (key_types_ref.is_null())
+ return false;
+
+ ScopedJavaLocalRef<jobjectArray> principals_ref =
+ ToJavaArrayOfByteArray(env, principals);
+ if (principals_ref.is_null())
+ return false;
+
+ ScopedJavaLocalRef<jstring> host_name_ref =
+ ConvertUTF8ToJavaString(env, host_name);
+ if (host_name_ref.is_null())
+ return false;
+
+ // Add to global list of active requests.
+ request_id_ = GetNewRequestId();
+ g_client_cert_requests.push_back(this);
+
+ // Invoke platform API.
+ return Java_AndroidKeyStore_selectClientCertificate(
+ env, request_id_, key_types_ref.obj(), principals_ref.obj(),
+ host_name_ref.obj(), port, NULL);
+}
+
+void ClientCertRequest::Cancel() {
+ if (request_id_ == 0)
+ return;
+
+ ClientCertRequestList::iterator it = std::find(
+ g_client_cert_requests.begin(),
+ g_client_cert_requests.end(),
+ this);
+
+ if (it != g_client_cert_requests.end()) {
+ (*it)->request_id_ = 0;
+ g_client_cert_requests.erase(it);
+ }
+}
+
+bool SignWithPrivateKey(
+ jobject private_key_ref,
+ const base::StringPiece& message,
+ std::vector<uint8>* signature) {
+ JNIEnv* env = AttachCurrentThread();
+
+ // Convert message to byte[] array.
+ ScopedJavaLocalRef<jbyteArray> message_ref =
+ ToJavaByteArray(env,
+ reinterpret_cast<const uint8*>(message.data()),
+ message.length());
+ DCHECK(!message_ref.is_null());
+
+ // Invoke platform API
+ ScopedJavaLocalRef<jbyteArray> signature_ref =
+ Java_AndroidKeyStore_signWithPrivateKey(
+ env, private_key_ref, message_ref.obj());
+ if (HasException(env) || signature_ref.is_null())
+ return false;
+
+ // Write signature to string.
+ JavaByteArrayToByteVector(env, signature_ref.obj(), signature);
+ return true;
+}
+
+bool RegisterKeyStore(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698