OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.net; | |
6 | |
7 import android.util.Log; | |
8 | |
9 import java.security.interfaces.DSAPrivateKey; | |
10 import java.security.interfaces.ECPrivateKey; | |
11 import java.security.interfaces.RSAPrivateKey; | |
12 import java.security.PrivateKey; | |
13 import java.security.Signature; | |
14 | |
15 import org.chromium.base.CalledByNative; | |
16 import org.chromium.base.JNINamespace; | |
17 import org.chromium.net.SSLClientCertType; | |
18 | |
19 @JNINamespace("net::android") | |
20 public class AndroidKeyStore { | |
21 | |
22 private static final String TAG = AndroidKeyStore.class.getName(); | |
23 | |
24 //////////////////////////////////////////////////////////////////// | |
25 // | |
26 // Message signing support. | |
27 // | |
28 | |
29 /** | |
30 * Called from native code to sign a given message with an RSA-based | |
31 * PrivateKey object. | |
32 * Assumes that initSignatureForKey() was called previously on the | |
33 * same privateKey handle. | |
34 * @param privateKey The PrivateKey handle. | |
35 * @param message The message to sign. | |
36 * @return signature as a byte buffer. | |
37 */ | |
38 @CalledByNative | |
39 public static byte[] signWithPrivateKey(PrivateKey privateKey, | |
40 byte[] message) { | |
41 synchronized (TAG) { | |
42 // Get the Signature singleton for this key. | |
43 Signature signature = null; | |
44 if (privateKey instanceof RSAPrivateKey) { | |
45 signature = sRsaSignature; | |
46 } else if (privateKey instanceof DSAPrivateKey) { | |
47 signature = sDsaSignature; | |
48 } else if (privateKey instanceof ECPrivateKey) { | |
49 signature = sEcdsaSignature; | |
50 } | |
51 if (signature == null) { | |
52 Log.e(TAG, "Unsupported private key algorithm: " + privateKey.ge tAlgorithm()); | |
53 return null; | |
54 } | |
55 | |
56 // Sign the message. | |
57 try { | |
58 signature.initSign(privateKey); | |
59 signature.update(message); | |
60 return signature.sign(); | |
61 } catch (Exception e) { | |
62 Log.e(TAG, "Exception while signing message with " + privateKey. getAlgorithm() + | |
63 " private key: " + e); | |
64 return null; | |
65 } | |
66 } | |
67 } | |
68 | |
69 /** | |
70 * Called from native code to return the type of a given PrivateKey | |
71 * object. This is an integer that maps to one of the values defined | |
72 * by org.chromium.net.SSLClientCertType, which is itself | |
73 * auto-generated from net/base/ssl_client_cert_type_list.h | |
74 * @param privateKey The PrivateKey handle | |
75 * @return key type, or SSLClientCertType.INVALID_TYPE if unknown. | |
76 */ | |
77 @CalledByNative | |
78 public static int getPrivateKeySigningType(PrivateKey privateKey) { | |
79 if (privateKey instanceof RSAPrivateKey) | |
80 return SSLClientCertType.RSA_SIGN; | |
81 if (privateKey instanceof DSAPrivateKey) | |
82 return SSLClientCertType.DSS_SIGN; | |
83 if (privateKey instanceof ECPrivateKey) | |
84 return SSLClientCertType.ECDSA_SIGN; | |
85 else | |
86 return SSLClientCertType.INVALID_TYPE; | |
87 } | |
88 | |
89 // Single signature instances. Used to perform signing with private | |
90 // keys. To avoid increasing Chromium's startup time, these are | |
91 // created lazily by calling initSignatureForKey below. | |
92 private static Signature sRsaSignature; | |
93 private static Signature sDsaSignature; | |
94 private static Signature sEcdsaSignature; | |
95 | |
96 /** | |
97 * Called to ensure that the global Signature object corresponding | |
98 * to a given private key is initialized before a call to signWithPrivateKey . | |
99 * Note that this is a potentially blocking operation. | |
100 * @param key A PrivateKey handle. | |
101 */ | |
102 public static void initSignatureForKey(PrivateKey key) { | |
103 String algorithm = key.getAlgorithm(); | |
104 synchronized (TAG) { | |
105 try { | |
106 // Hint: Algorithm names come from: | |
107 // http://docs.oracle.com/javase/6/docs/technotes/guides/securit y/StandardNames.html | |
108 if (algorithm.equals("RSA") && sRsaSignature == null) { | |
109 // IMPORTANT: Due to what looks like a platform bug, this wi ll | |
110 // throw NoSuchAlgorithmException on Android 4.2.1. Fixed in 4.2 | |
digit1
2013/01/25 14:23:41
This should read Android 4.1.2 :/
| |
111 // and higher. See https://android-review.googlesource.com/# /c/40352/ | |
112 sRsaSignature = Signature.getInstance("NONEwithRSA"); | |
113 } else if (algorithm.equals("DSA") && sDsaSignature == null) { | |
114 sDsaSignature = Signature.getInstance("NONEwithDSA"); | |
115 } else if (algorithm.equals("ECDSA") && sEcdsaSignature == null) { | |
116 // The documentation mentions that NONEwithECDSA is ambiguou s | |
117 // and that SHA1withECDSA, its synonym, should be used inste ad. | |
118 sEcdsaSignature = Signature.getInstance("SHA1withECDSA"); | |
119 } | |
120 } catch (Exception e) { | |
121 Log.w(TAG, "Could not create " + algorithm + " Signature singlet on:" + e); | |
122 } | |
123 } | |
124 } | |
125 | |
126 } | |
OLD | NEW |