use of org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder in project android_frameworks_base by ParanoidAndroid.
the class AndroidKeyStore method setPrivateKeyEntry.
private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain, KeyStoreParameter params) throws KeyStoreException {
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");
}
}
use of org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder in project android_frameworks_base by ParanoidAndroid.
the class ClientCertRequestHandler method proceed.
/**
* Proceed with the specified private key and client certificate chain.
*/
public void proceed(PrivateKey privateKey, X509Certificate[] chain) {
try {
byte[][] chainBytes = NativeCrypto.encodeCertificates(chain);
mTable.Allow(mHostAndPort, privateKey, chainBytes);
if (privateKey instanceof OpenSSLKeyHolder) {
OpenSSLKey pkey = ((OpenSSLKeyHolder) privateKey).getOpenSSLKey();
setSslClientCertFromCtx(pkey.getPkeyContext(), chainBytes);
} else {
setSslClientCertFromPKCS8(privateKey.getEncoded(), chainBytes);
}
} catch (CertificateEncodingException e) {
post(new Runnable() {
public void run() {
mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
return;
}
});
}
}
use of org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder in project android_frameworks_base by ParanoidAndroid.
the class BrowserFrame method requestClientCert.
/**
* Called by JNI when the native HTTPS stack gets a client
* certificate request.
*
* We delegate the request to CallbackProxy, and route its response to
* {@link #nativeSslClientCert(int, X509Certificate)}.
*/
private void requestClientCert(int handle, String hostAndPort) {
SslClientCertLookupTable table = SslClientCertLookupTable.getInstance();
if (table.IsAllowed(hostAndPort)) {
// previously allowed
PrivateKey pkey = table.PrivateKey(hostAndPort);
if (pkey instanceof OpenSSLKeyHolder) {
OpenSSLKey sslKey = ((OpenSSLKeyHolder) pkey).getOpenSSLKey();
nativeSslClientCert(handle, sslKey.getPkeyContext(), table.CertificateChain(hostAndPort));
} else {
nativeSslClientCert(handle, pkey.getEncoded(), table.CertificateChain(hostAndPort));
}
} else if (table.IsDenied(hostAndPort)) {
// previously denied
nativeSslClientCert(handle, 0, null);
} else {
// previously ignored or new
mCallbackProxy.onReceivedClientCertRequest(new ClientCertRequestHandler(this, handle, hostAndPort, table), hostAndPort);
}
}
Aggregations