OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser; | 5 package org.chromium.chrome.browser; |
6 | 6 |
7 import android.app.Activity; | 7 import android.app.Activity; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.os.AsyncTask; | 9 import android.os.AsyncTask; |
10 import android.security.KeyChain; | 10 import android.security.KeyChain; |
11 import android.security.KeyChainAliasCallback; | 11 import android.security.KeyChainAliasCallback; |
12 import android.security.KeyChainException; | 12 import android.security.KeyChainException; |
13 import android.util.Log; | 13 import android.util.Log; |
14 | 14 |
15 import org.chromium.base.ActivityStatus; | 15 import org.chromium.base.ActivityStatus; |
16 import org.chromium.base.CalledByNative; | 16 import org.chromium.base.CalledByNative; |
17 import org.chromium.base.JNINamespace; | 17 import org.chromium.base.JNINamespace; |
18 import org.chromium.base.ThreadUtils; | 18 import org.chromium.base.ThreadUtils; |
19 import org.chromium.net.AndroidKeyStoreLocalImpl; | |
20 import org.chromium.net.AndroidPrivateKey; | |
19 | 21 |
20 import java.security.Principal; | 22 import java.security.Principal; |
21 import java.security.PrivateKey; | |
22 import java.security.cert.CertificateEncodingException; | 23 import java.security.cert.CertificateEncodingException; |
23 import java.security.cert.X509Certificate; | 24 import java.security.cert.X509Certificate; |
24 | 25 |
25 import javax.security.auth.x500.X500Principal; | 26 import javax.security.auth.x500.X500Principal; |
26 | 27 |
27 /** | 28 /** |
28 * Handles selection of client certificate on the Java side. This class is respo nsible for selection | 29 * Handles selection of client certificate on the Java side. This class is respo nsible for selection |
29 * of the client certificate to be used for authentication and retrieval of the private key and full | 30 * of the client certificate to be used for authentication and retrieval of the private key and full |
30 * certificate chain. | 31 * certificate chain. |
31 * | 32 * |
32 * The entry point is selectClientCertificate() and it will be called on the UI thread. Then the | 33 * The entry point is selectClientCertificate() and it will be called on the UI thread. Then the |
33 * class will construct and run an appropriate CertAsyncTask, that will run in b ackground, and | 34 * class will construct and run an appropriate CertAsyncTask, that will run in b ackground, and |
34 * finally pass the results back to the UI thread, which will return to the nati ve code. | 35 * finally pass the results back to the UI thread, which will return to the nati ve code. |
35 */ | 36 */ |
36 @JNINamespace("chrome::android") | 37 @JNINamespace("chrome::android") |
37 class SSLClientCertificateRequest { | 38 public class SSLClientCertificateRequest { |
38 static final String TAG = "SSLClientCertificateRequest"; | 39 static final String TAG = "SSLClientCertificateRequest"; |
39 | 40 |
41 static final AndroidKeyStoreLocalImpl sLocalKeyStore = new AndroidKeyStoreLo calImpl(); | |
bulach
2014/02/14 10:45:29
nit: can this be private, and wrapped in a GetInst
Yaron
2014/02/14 19:36:56
Done.
| |
42 | |
40 /** | 43 /** |
41 * Common implementation for anynchronous task of handling the certificate r equest. This | 44 * Common implementation for anynchronous task of handling the certificate r equest. This |
42 * AsyncTask uses the abstract methods to retrieve the authentication materi al from a | 45 * AsyncTask uses the abstract methods to retrieve the authentication materi al from a |
43 * generalized key store. The key store is accessed in background, as the AP Is being exercised | 46 * generalized key store. The key store is accessed in background, as the AP Is being exercised |
44 * may be blocking. The results are posted back to native on the UI thread. | 47 * may be blocking. The results are posted back to native on the UI thread. |
45 */ | 48 */ |
46 abstract static class CertAsyncTask extends AsyncTask<Void, Void, Void> { | 49 abstract static class CertAsyncTask extends AsyncTask<Void, Void, Void> { |
47 // These fields will store the results computed in doInBackground so tha t they can be posted | 50 // These fields will store the results computed in doInBackground so tha t they can be posted |
48 // back in onPostExecute. | 51 // back in onPostExecute. |
49 private byte[][] mEncodedChain; | 52 private byte[][] mEncodedChain; |
50 private PrivateKey mPrivateKey; | 53 private AndroidPrivateKey mAndroidKey; |
bulach
2014/02/14 10:45:29
nit: mAndroidPrivateKey, just to avoid confusion..
Yaron
2014/02/14 19:36:56
Done.
| |
51 | 54 |
52 // Pointer to the native certificate request needed to return the result s. | 55 // Pointer to the native certificate request needed to return the result s. |
53 private final int mNativePtr; | 56 private final int mNativePtr; |
54 | 57 |
55 CertAsyncTask(int nativePtr) { | 58 CertAsyncTask(int nativePtr) { |
56 mNativePtr = nativePtr; | 59 mNativePtr = nativePtr; |
57 } | 60 } |
58 | 61 |
59 // These overriden methods will be used to access the key store. | 62 // These overriden methods will be used to access the key store. |
60 abstract String getAlias(); | 63 abstract String getAlias(); |
61 abstract PrivateKey getPrivateKey(String alias); | 64 abstract AndroidPrivateKey getPrivateKey(String alias); |
62 abstract X509Certificate[] getCertificateChain(String alias); | 65 abstract X509Certificate[] getCertificateChain(String alias); |
63 | 66 |
64 @Override | 67 @Override |
65 protected Void doInBackground(Void... params) { | 68 protected Void doInBackground(Void... params) { |
66 String alias = getAlias(); | 69 String alias = getAlias(); |
67 if (alias == null) return null; | 70 if (alias == null) return null; |
68 | 71 |
69 PrivateKey key = getPrivateKey(alias); | 72 AndroidPrivateKey key = getPrivateKey(alias); |
73 Log.d(TAG, "got key " + key); | |
70 X509Certificate[] chain = getCertificateChain(alias); | 74 X509Certificate[] chain = getCertificateChain(alias); |
75 Log.d(TAG, "got chain " + chain); | |
bulach
2014/02/14 10:45:29
nit: unindent
Yaron
2014/02/14 19:36:56
Done.
| |
76 | |
71 if (key == null || chain == null || chain.length == 0) { | 77 if (key == null || chain == null || chain.length == 0) { |
72 Log.w(TAG, "Empty client certificate chain?"); | 78 Log.w(TAG, "Empty client certificate chain?"); |
73 return null; | 79 return null; |
74 } | 80 } |
75 | 81 |
76 // Encode the certificate chain. | 82 // Encode the certificate chain. |
77 byte[][] encodedChain = new byte[chain.length][]; | 83 byte[][] encodedChain = new byte[chain.length][]; |
78 try { | 84 try { |
79 for (int i = 0; i < chain.length; ++i) { | 85 for (int i = 0; i < chain.length; ++i) { |
80 encodedChain[i] = chain[i].getEncoded(); | 86 encodedChain[i] = chain[i].getEncoded(); |
81 } | 87 } |
82 } catch (CertificateEncodingException e) { | 88 } catch (CertificateEncodingException e) { |
83 Log.w(TAG, "Could not retrieve encoded certificate chain: " + e) ; | 89 Log.w(TAG, "Could not retrieve encoded certificate chain: " + e) ; |
84 return null; | 90 return null; |
85 } | 91 } |
86 | 92 |
87 mEncodedChain = encodedChain; | 93 mEncodedChain = encodedChain; |
88 mPrivateKey = key; | 94 mAndroidKey = key; |
89 return null; | 95 return null; |
90 } | 96 } |
91 | 97 |
92 @Override | 98 @Override |
93 protected void onPostExecute(Void result) { | 99 protected void onPostExecute(Void result) { |
94 ThreadUtils.assertOnUiThread(); | 100 ThreadUtils.assertOnUiThread(); |
95 nativeOnSystemRequestCompletion(mNativePtr, mEncodedChain, mPrivateK ey); | 101 nativeOnSystemRequestCompletion(mNativePtr, mEncodedChain, mAndroidK ey); |
96 } | 102 } |
97 } | 103 } |
98 | 104 |
99 /** Implementation of CertAsyncTask for the system KeyChain API. */ | 105 /** Implementation of CertAsyncTask for the system KeyChain API. */ |
100 private static class CertAsyncTaskKeyChain extends CertAsyncTask { | 106 private static class CertAsyncTaskKeyChain extends CertAsyncTask { |
101 final Context mContext; | 107 final Context mContext; |
102 final String mAlias; | 108 final String mAlias; |
103 | 109 |
104 CertAsyncTaskKeyChain(Context context, int nativePtr, String alias) { | 110 CertAsyncTaskKeyChain(Context context, int nativePtr, String alias) { |
105 super(nativePtr); | 111 super(nativePtr); |
106 mContext = context; | 112 mContext = context; |
107 assert alias != null; | 113 assert alias != null; |
108 mAlias = alias; | 114 mAlias = alias; |
109 } | 115 } |
110 | 116 |
111 @Override | 117 @Override |
112 String getAlias() { | 118 String getAlias() { |
113 return mAlias; | 119 return mAlias; |
114 } | 120 } |
115 | 121 |
116 @Override | 122 @Override |
117 PrivateKey getPrivateKey(String alias) { | 123 AndroidPrivateKey getPrivateKey(String alias) { |
118 try { | 124 try { |
119 return KeyChain.getPrivateKey(mContext, alias); | 125 return sLocalKeyStore.createKey(KeyChain.getPrivateKey(mContext, alias)); |
120 } catch (KeyChainException e) { | 126 } catch (KeyChainException e) { |
121 Log.w(TAG, "KeyChainException when looking for '" + alias + "' c ertificate"); | 127 Log.w(TAG, "KeyChainException when looking for '" + alias + "' c ertificate"); |
122 return null; | 128 return null; |
123 } catch (InterruptedException e) { | 129 } catch (InterruptedException e) { |
124 Log.w(TAG, "InterruptedException when looking for '" + alias + " 'certificate"); | 130 Log.w(TAG, "InterruptedException when looking for '" + alias + " 'certificate"); |
125 return null; | 131 return null; |
126 } | 132 } |
127 } | 133 } |
128 | 134 |
129 @Override | 135 @Override |
(...skipping 23 matching lines...) Expand all Loading... | |
153 mPort = port; | 159 mPort = port; |
154 mPKCS11AuthManager = pkcs11CardAuthManager; | 160 mPKCS11AuthManager = pkcs11CardAuthManager; |
155 } | 161 } |
156 | 162 |
157 @Override | 163 @Override |
158 String getAlias() { | 164 String getAlias() { |
159 return mPKCS11AuthManager.getClientCertificateAlias(mHostName, mPort ); | 165 return mPKCS11AuthManager.getClientCertificateAlias(mHostName, mPort ); |
160 } | 166 } |
161 | 167 |
162 @Override | 168 @Override |
163 PrivateKey getPrivateKey(String alias) { | 169 AndroidPrivateKey getPrivateKey(String alias) { |
164 return mPKCS11AuthManager.getPrivateKey(alias); | 170 return mPKCS11AuthManager.getPrivateKey(alias); |
165 } | 171 } |
166 | 172 |
167 @Override | 173 @Override |
168 X509Certificate[] getCertificateChain(String alias) { | 174 X509Certificate[] getCertificateChain(String alias) { |
169 return mPKCS11AuthManager.getCertificateChain(alias); | 175 return mPKCS11AuthManager.getCertificateChain(alias); |
170 } | 176 } |
171 } | 177 } |
172 | 178 |
173 /** | 179 /** |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 // Smart card support is not available, use the system store uncondi tionally. | 289 // Smart card support is not available, use the system store uncondi tionally. |
284 useSystemStore.run(); | 290 useSystemStore.run(); |
285 } | 291 } |
286 | 292 |
287 // We've taken ownership of the native ssl request object. | 293 // We've taken ownership of the native ssl request object. |
288 return true; | 294 return true; |
289 } | 295 } |
290 | 296 |
291 // Called to pass request results to native side. | 297 // Called to pass request results to native side. |
292 private static native void nativeOnSystemRequestCompletion( | 298 private static native void nativeOnSystemRequestCompletion( |
293 int requestPtr, byte[][] certChain, PrivateKey privateKey); | 299 int requestPtr, byte[][] certChain, AndroidPrivateKey androidKey); |
294 } | 300 } |
OLD | NEW |