Skip to content

Commit 4898087

Browse files
krutonAndroid (Google) Code Review
authored andcommitted
Merge changes Ibdf23227,I3681f98c
* changes: Update Wifi to use new keystore function Add signing to keystore
2 parents fa7887b + 565f9f2 commit 4898087

File tree

7 files changed

+446
-21
lines changed

7 files changed

+446
-21
lines changed

keystore/java/android/security/Credentials.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
2626
import java.io.ByteArrayOutputStream;
2727
import java.io.IOException;
2828
import java.io.InputStreamReader;
29+
import java.io.ObjectOutputStream;
2930
import java.io.OutputStreamWriter;
3031
import java.io.Reader;
3132
import java.io.Writer;
3233
import java.nio.charset.Charsets;
3334
import java.security.KeyPair;
35+
import java.security.cert.X509Certificate;
3436
import java.util.ArrayList;
3537
import java.util.List;
3638

@@ -72,6 +74,36 @@ public class Credentials {
7274
public static final String EXTENSION_CER = ".cer";
7375
public static final String EXTENSION_PFX = ".pfx";
7476

77+
/**
78+
* Intent extra: name for the user's private key.
79+
*/
80+
public static final String EXTRA_USER_PRIVATE_KEY_NAME = "user_private_key_name";
81+
82+
/**
83+
* Intent extra: data for the user's private key in PEM-encoded PKCS#8.
84+
*/
85+
public static final String EXTRA_USER_PRIVATE_KEY_DATA = "user_private_key_data";
86+
87+
/**
88+
* Intent extra: name for the user's certificate.
89+
*/
90+
public static final String EXTRA_USER_CERTIFICATE_NAME = "user_certificate_name";
91+
92+
/**
93+
* Intent extra: data for the user's certificate in PEM-encoded X.509.
94+
*/
95+
public static final String EXTRA_USER_CERTIFICATE_DATA = "user_certificate_data";
96+
97+
/**
98+
* Intent extra: name for CA certificate chain
99+
*/
100+
public static final String EXTRA_CA_CERTIFICATES_NAME = "ca_certificates_name";
101+
102+
/**
103+
* Intent extra: data for CA certificate chain in PEM-encoded X.509.
104+
*/
105+
public static final String EXTRA_CA_CERTIFICATES_DATA = "ca_certificates_data";
106+
75107
/**
76108
* Convert objects to a PEM format, which is used for
77109
* CA_CERTIFICATE, USER_CERTIFICATE, and USER_PRIVATE_KEY

keystore/java/android/security/IKeyChainService.aidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ package android.security;
2323
*/
2424
interface IKeyChainService {
2525
// APIs used by KeyChain
26-
byte[] getPrivateKey(String alias);
26+
String requestPrivateKey(String alias);
2727
byte[] getCertificate(String alias);
2828

2929
// APIs used by CertInstaller

keystore/java/android/security/KeyChain.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.io.ByteArrayInputStream;
2828
import java.io.Closeable;
2929
import java.io.IOException;
30+
import java.security.InvalidKeyException;
3031
import java.security.KeyPair;
3132
import java.security.Principal;
3233
import java.security.PrivateKey;
@@ -39,6 +40,8 @@
3940
import java.util.concurrent.BlockingQueue;
4041
import java.util.concurrent.LinkedBlockingQueue;
4142
import libcore.util.Objects;
43+
44+
import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
4245
import org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore;
4346

4447
/**
@@ -301,14 +304,21 @@ public static PrivateKey getPrivateKey(Context context, String alias)
301304
}
302305
KeyChainConnection keyChainConnection = bind(context);
303306
try {
304-
IKeyChainService keyChainService = keyChainConnection.getService();
305-
byte[] privateKeyBytes = keyChainService.getPrivateKey(alias);
306-
return toPrivateKey(privateKeyBytes);
307+
final IKeyChainService keyChainService = keyChainConnection.getService();
308+
final String keyId = keyChainService.requestPrivateKey(alias);
309+
if (keyId == null) {
310+
throw new KeyChainException("keystore had a problem");
311+
}
312+
313+
final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
314+
return engine.getPrivateKeyById(keyId);
307315
} catch (RemoteException e) {
308316
throw new KeyChainException(e);
309317
} catch (RuntimeException e) {
310318
// only certain RuntimeExceptions can be propagated across the IKeyChainService call
311319
throw new KeyChainException(e);
320+
} catch (InvalidKeyException e) {
321+
throw new KeyChainException(e);
312322
} finally {
313323
keyChainConnection.close();
314324
}
@@ -356,18 +366,6 @@ public static X509Certificate[] getCertificateChain(Context context, String alia
356366
}
357367
}
358368

359-
private static PrivateKey toPrivateKey(byte[] bytes) {
360-
if (bytes == null) {
361-
throw new IllegalArgumentException("bytes == null");
362-
}
363-
try {
364-
KeyPair keyPair = (KeyPair) Credentials.convertFromPem(bytes).get(0);
365-
return keyPair.getPrivate();
366-
} catch (IOException e) {
367-
throw new AssertionError(e);
368-
}
369-
}
370-
371369
private static X509Certificate toCertificate(byte[] bytes) {
372370
if (bytes == null) {
373371
throw new IllegalArgumentException("bytes == null");

keystore/java/android/security/KeyStore.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,78 @@ public boolean isEmpty() {
155155
return mError == KEY_NOT_FOUND;
156156
}
157157

158+
private boolean generate(byte[] key) {
159+
execute('a', key);
160+
return mError == NO_ERROR;
161+
}
162+
163+
public boolean generate(String key) {
164+
return generate(getBytes(key));
165+
}
166+
167+
private boolean importKey(byte[] keyName, byte[] key) {
168+
execute('m', keyName, key);
169+
return mError == NO_ERROR;
170+
}
171+
172+
public boolean importKey(String keyName, byte[] key) {
173+
return importKey(getBytes(keyName), key);
174+
}
175+
176+
private byte[] getPubkey(byte[] key) {
177+
ArrayList<byte[]> values = execute('b', key);
178+
return (values == null || values.isEmpty()) ? null : values.get(0);
179+
}
180+
181+
public byte[] getPubkey(String key) {
182+
return getPubkey(getBytes(key));
183+
}
184+
185+
private boolean delKey(byte[] key) {
186+
execute('k', key);
187+
return mError == NO_ERROR;
188+
}
189+
190+
public boolean delKey(String key) {
191+
return delKey(getBytes(key));
192+
}
193+
194+
private byte[] sign(byte[] keyName, byte[] data) {
195+
final ArrayList<byte[]> values = execute('n', keyName, data);
196+
return (values == null || values.isEmpty()) ? null : values.get(0);
197+
}
198+
199+
public byte[] sign(String key, byte[] data) {
200+
return sign(getBytes(key), data);
201+
}
202+
203+
private boolean verify(byte[] keyName, byte[] data, byte[] signature) {
204+
execute('v', keyName, data, signature);
205+
return mError == NO_ERROR;
206+
}
207+
208+
public boolean verify(String key, byte[] data, byte[] signature) {
209+
return verify(getBytes(key), data, signature);
210+
}
211+
212+
private boolean grant(byte[] key, byte[] uid) {
213+
execute('x', key, uid);
214+
return mError == NO_ERROR;
215+
}
216+
217+
public boolean grant(String key, int uid) {
218+
return grant(getBytes(key), Integer.toString(uid).getBytes());
219+
}
220+
221+
private boolean ungrant(byte[] key, byte[] uid) {
222+
execute('y', key, uid);
223+
return mError == NO_ERROR;
224+
}
225+
226+
public boolean ungrant(String key, int uid) {
227+
return ungrant(getBytes(key), Integer.toString(uid).getBytes());
228+
}
229+
158230
public int getLastError() {
159231
return mError;
160232
}

0 commit comments

Comments
 (0)