Methods Summary |
---|
public java.util.Enumeration | engineAliases()
return Collections.enumeration(getUniqueAliases());
|
public boolean | engineContainsAlias(java.lang.String alias)
if (alias == null) {
throw new NullPointerException("alias == null");
}
return mKeyStore.contains(Credentials.USER_PRIVATE_KEY + alias)
|| mKeyStore.contains(Credentials.USER_CERTIFICATE + alias)
|| mKeyStore.contains(Credentials.CA_CERTIFICATE + alias);
|
public void | engineDeleteEntry(java.lang.String alias)
if (!isKeyEntry(alias) && !isCertificateEntry(alias)) {
return;
}
if (!Credentials.deleteAllTypesForAlias(mKeyStore, alias)) {
throw new KeyStoreException("No such entry " + alias);
}
|
public java.security.cert.Certificate | engineGetCertificate(java.lang.String alias)
if (alias == null) {
throw new NullPointerException("alias == null");
}
byte[] certificate = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
if (certificate != null) {
return toCertificate(certificate);
}
certificate = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
if (certificate != null) {
return toCertificate(certificate);
}
return null;
|
public java.lang.String | engineGetCertificateAlias(java.security.cert.Certificate cert)
if (cert == null) {
return null;
}
final Set<String> nonCaEntries = new HashSet<String>();
/*
* First scan the PrivateKeyEntry types. The KeyStoreSpi documentation
* says to only compare the first certificate in the chain which is
* equivalent to the USER_CERTIFICATE prefix for the Android keystore
* convention.
*/
final String[] certAliases = mKeyStore.saw(Credentials.USER_CERTIFICATE);
if (certAliases != null) {
for (String alias : certAliases) {
final byte[] certBytes = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
if (certBytes == null) {
continue;
}
final Certificate c = toCertificate(certBytes);
nonCaEntries.add(alias);
if (cert.equals(c)) {
return alias;
}
}
}
/*
* Look at all the TrustedCertificateEntry types. Skip all the
* PrivateKeyEntry we looked at above.
*/
final String[] caAliases = mKeyStore.saw(Credentials.CA_CERTIFICATE);
if (certAliases != null) {
for (String alias : caAliases) {
if (nonCaEntries.contains(alias)) {
continue;
}
final byte[] certBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
if (certBytes == null) {
continue;
}
final Certificate c =
toCertificate(mKeyStore.get(Credentials.CA_CERTIFICATE + alias));
if (cert.equals(c)) {
return alias;
}
}
}
return null;
|
public java.security.cert.Certificate[] | engineGetCertificateChain(java.lang.String alias)
if (alias == null) {
throw new NullPointerException("alias == null");
}
final X509Certificate leaf = (X509Certificate) engineGetCertificate(alias);
if (leaf == null) {
return null;
}
final Certificate[] caList;
final byte[] caBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
if (caBytes != null) {
final Collection<X509Certificate> caChain = toCertificates(caBytes);
caList = new Certificate[caChain.size() + 1];
final Iterator<X509Certificate> it = caChain.iterator();
int i = 1;
while (it.hasNext()) {
caList[i++] = it.next();
}
} else {
caList = new Certificate[1];
}
caList[0] = leaf;
return caList;
|
public java.util.Date | engineGetCreationDate(java.lang.String alias)
if (alias == null) {
throw new NullPointerException("alias == null");
}
Date d = getModificationDate(Credentials.USER_PRIVATE_KEY + alias);
if (d != null) {
return d;
}
d = getModificationDate(Credentials.USER_CERTIFICATE + alias);
if (d != null) {
return d;
}
return getModificationDate(Credentials.CA_CERTIFICATE + alias);
|
public java.security.Key | engineGetKey(java.lang.String alias, char[] password)
if (!isKeyEntry(alias)) {
return null;
}
final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
try {
return engine.getPrivateKeyById(Credentials.USER_PRIVATE_KEY + alias);
} catch (InvalidKeyException e) {
UnrecoverableKeyException t = new UnrecoverableKeyException("Can't get key");
t.initCause(e);
throw t;
}
|
public boolean | engineIsCertificateEntry(java.lang.String alias)
return !isKeyEntry(alias) && isCertificateEntry(alias);
|
public boolean | engineIsKeyEntry(java.lang.String alias)
return isKeyEntry(alias);
|
public void | engineLoad(java.io.InputStream stream, char[] password)
if (stream != null) {
throw new IllegalArgumentException("InputStream not supported");
}
if (password != null) {
throw new IllegalArgumentException("password not supported");
}
// Unfortunate name collision.
mKeyStore = android.security.KeyStore.getInstance();
|
public void | engineSetCertificateEntry(java.lang.String alias, java.security.cert.Certificate cert)
if (isKeyEntry(alias)) {
throw new KeyStoreException("Entry exists and is not a trusted certificate");
}
// We can't set something to null.
if (cert == null) {
throw new NullPointerException("cert == null");
}
final byte[] encoded;
try {
encoded = cert.getEncoded();
} catch (CertificateEncodingException e) {
throw new KeyStoreException(e);
}
if (!mKeyStore.put(Credentials.CA_CERTIFICATE + alias, encoded,
android.security.KeyStore.UID_SELF, android.security.KeyStore.FLAG_NONE)) {
throw new KeyStoreException("Couldn't insert certificate; is KeyStore initialized?");
}
|
public void | engineSetEntry(java.lang.String alias, java.security.KeyStore.Entry entry, java.security.KeyStore.ProtectionParameter param)
if (entry == null) {
throw new KeyStoreException("entry == null");
}
if (engineContainsAlias(alias)) {
engineDeleteEntry(alias);
}
if (entry instanceof KeyStore.TrustedCertificateEntry) {
KeyStore.TrustedCertificateEntry trE = (KeyStore.TrustedCertificateEntry) entry;
engineSetCertificateEntry(alias, trE.getTrustedCertificate());
return;
}
if (param != null && !(param instanceof KeyStoreParameter)) {
throw new KeyStoreException(
"protParam should be android.security.KeyStoreParameter; was: "
+ param.getClass().getName());
}
if (entry instanceof PrivateKeyEntry) {
PrivateKeyEntry prE = (PrivateKeyEntry) entry;
setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(),
(KeyStoreParameter) param);
return;
}
throw new KeyStoreException(
"Entry must be a PrivateKeyEntry or TrustedCertificateEntry; was " + entry);
|
public void | engineSetKeyEntry(java.lang.String alias, byte[] userKey, java.security.cert.Certificate[] chain)
throw new KeyStoreException("Operation not supported because key encoding is unknown");
|
public void | engineSetKeyEntry(java.lang.String alias, java.security.Key key, char[] password, java.security.cert.Certificate[] chain)
if ((password != null) && (password.length > 0)) {
throw new KeyStoreException("entries cannot be protected with passwords");
}
if (key instanceof PrivateKey) {
setPrivateKeyEntry(alias, (PrivateKey) key, chain, null);
} else {
throw new KeyStoreException("Only PrivateKeys are supported");
}
|
public int | engineSize()
return getUniqueAliases().size();
|
public void | engineStore(java.io.OutputStream stream, char[] password)
throw new UnsupportedOperationException("Can not serialize AndroidKeyStore to OutputStream");
|
private java.util.Date | getModificationDate(java.lang.String alias)
final long epochMillis = mKeyStore.getmtime(alias);
if (epochMillis == -1L) {
return null;
}
return new Date(epochMillis);
|
private java.util.Set | getUniqueAliases()
final String[] rawAliases = mKeyStore.saw("");
if (rawAliases == null) {
return new HashSet<String>();
}
final Set<String> aliases = new HashSet<String>(rawAliases.length);
for (String alias : rawAliases) {
final int idx = alias.indexOf('_");
if ((idx == -1) || (alias.length() <= idx)) {
Log.e(NAME, "invalid alias: " + alias);
continue;
}
aliases.add(new String(alias.substring(idx + 1)));
}
return aliases;
|
private boolean | isCertificateEntry(java.lang.String alias)
if (alias == null) {
throw new NullPointerException("alias == null");
}
return mKeyStore.contains(Credentials.CA_CERTIFICATE + alias);
|
private boolean | isKeyEntry(java.lang.String alias)
if (alias == null) {
throw new NullPointerException("alias == null");
}
return mKeyStore.contains(Credentials.USER_PRIVATE_KEY + alias);
|
private void | setPrivateKeyEntry(java.lang.String alias, java.security.PrivateKey key, java.security.cert.Certificate[] chain, KeyStoreParameter params)
byte[] keyBytes = null;
final String pkeyAlias;
if (key instanceof OpenSSLKeyHolder) {
pkeyAlias = ((OpenSSLKeyHolder) key).getOpenSSLKey().getAlias();
} else {
pkeyAlias = null;
}
final boolean shouldReplacePrivateKey;
if (pkeyAlias != null && pkeyAlias.startsWith(Credentials.USER_PRIVATE_KEY)) {
final String keySubalias = pkeyAlias.substring(Credentials.USER_PRIVATE_KEY.length());
if (!alias.equals(keySubalias)) {
throw new KeyStoreException("Can only replace keys with same alias: " + alias
+ " != " + keySubalias);
}
shouldReplacePrivateKey = false;
} else {
// Make sure the PrivateKey format is the one we support.
final String keyFormat = key.getFormat();
if ((keyFormat == null) || (!"PKCS#8".equals(keyFormat))) {
throw new KeyStoreException(
"Only PrivateKeys that can be encoded into PKCS#8 are supported");
}
// Make sure we can actually encode the key.
keyBytes = key.getEncoded();
if (keyBytes == null) {
throw new KeyStoreException("PrivateKey has no encoding");
}
shouldReplacePrivateKey = true;
}
// Make sure the chain exists since this is a PrivateKey
if ((chain == null) || (chain.length == 0)) {
throw new KeyStoreException("Must supply at least one Certificate with PrivateKey");
}
// Do chain type checking.
X509Certificate[] x509chain = new X509Certificate[chain.length];
for (int i = 0; i < chain.length; i++) {
if (!"X.509".equals(chain[i].getType())) {
throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #"
+ i);
}
if (!(chain[i] instanceof X509Certificate)) {
throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #"
+ i);
}
x509chain[i] = (X509Certificate) chain[i];
}
final byte[] userCertBytes;
try {
userCertBytes = x509chain[0].getEncoded();
} catch (CertificateEncodingException e) {
throw new KeyStoreException("Couldn't encode certificate #1", e);
}
/*
* If we have a chain, store it in the CA certificate slot for this
* alias as concatenated DER-encoded certificates. These can be
* deserialized by {@link CertificateFactory#generateCertificates}.
*/
final byte[] chainBytes;
if (chain.length > 1) {
/*
* The chain is passed in as {user_cert, ca_cert_1, ca_cert_2, ...}
* so we only need the certificates starting at index 1.
*/
final byte[][] certsBytes = new byte[x509chain.length - 1][];
int totalCertLength = 0;
for (int i = 0; i < certsBytes.length; i++) {
try {
certsBytes[i] = x509chain[i + 1].getEncoded();
totalCertLength += certsBytes[i].length;
} catch (CertificateEncodingException e) {
throw new KeyStoreException("Can't encode Certificate #" + i, e);
}
}
/*
* Serialize this into one byte array so we can later call
* CertificateFactory#generateCertificates to recover them.
*/
chainBytes = new byte[totalCertLength];
int outputOffset = 0;
for (int i = 0; i < certsBytes.length; i++) {
final int certLength = certsBytes[i].length;
System.arraycopy(certsBytes[i], 0, chainBytes, outputOffset, certLength);
outputOffset += certLength;
certsBytes[i] = null;
}
} else {
chainBytes = null;
}
/*
* Make sure we clear out all the appropriate types before trying to
* write.
*/
if (shouldReplacePrivateKey) {
Credentials.deleteAllTypesForAlias(mKeyStore, alias);
} else {
Credentials.deleteCertificateTypesForAlias(mKeyStore, alias);
}
final int flags = (params == null) ? 0 : params.getFlags();
if (shouldReplacePrivateKey
&& !mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, keyBytes,
android.security.KeyStore.UID_SELF, flags)) {
Credentials.deleteAllTypesForAlias(mKeyStore, alias);
throw new KeyStoreException("Couldn't put private key in keystore");
} else if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, userCertBytes,
android.security.KeyStore.UID_SELF, flags)) {
Credentials.deleteAllTypesForAlias(mKeyStore, alias);
throw new KeyStoreException("Couldn't put certificate #1 in keystore");
} else if (chainBytes != null
&& !mKeyStore.put(Credentials.CA_CERTIFICATE + alias, chainBytes,
android.security.KeyStore.UID_SELF, flags)) {
Credentials.deleteAllTypesForAlias(mKeyStore, alias);
throw new KeyStoreException("Couldn't put certificate chain in keystore");
}
|
private static java.security.cert.X509Certificate | toCertificate(byte[] bytes)
try {
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return (X509Certificate) certFactory
.generateCertificate(new ByteArrayInputStream(bytes));
} catch (CertificateException e) {
Log.w(NAME, "Couldn't parse certificate in keystore", e);
return null;
}
|
private static java.util.Collection | toCertificates(byte[] bytes)
try {
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return (Collection<X509Certificate>) certFactory
.generateCertificates(new ByteArrayInputStream(bytes));
} catch (CertificateException e) {
Log.w(NAME, "Couldn't parse certificates in keystore", e);
return new ArrayList<X509Certificate>();
}
|