use of java.security.spec.X509EncodedKeySpec in project Shuttle by timusus.
the class Security method generatePublicKey.
/**
* Generates a PublicKey instance from a string containing the
* Base64-encoded public key.
*
* @param encodedPublicKey Base64-encoded public key
* @throws IllegalArgumentException if encodedPublicKey is invalid
*/
public static PublicKey generatePublicKey(String encodedPublicKey) {
try {
byte[] decodedKey = Base64.decode(encodedPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeySpecException e) {
Log.e(TAG, "Invalid key specification.");
throw new IllegalArgumentException(e);
} catch (Base64DecoderException e) {
Log.e(TAG, "Base64 decoding failed.");
throw new IllegalArgumentException(e);
}
}
use of java.security.spec.X509EncodedKeySpec in project helios by spotify.
the class X509CertificateFactoryTest method setUp.
@Before
public void setUp() throws Exception {
final X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(ROHAN_PUB_KEY));
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(pubKeySpec);
when(identity.getPublicKey()).thenReturn(publicKey);
when(identity.getKeyBlob()).thenReturn(publicKey.getEncoded());
when(agentProxy.sign(any(Identity.class), any(byte[].class))).thenAnswer(new Answer<byte[]>() {
@Override
public byte[] answer(InvocationOnMock invocation) throws Throwable {
final byte[] bytesToSign = (byte[]) invocation.getArguments()[1];
return sha1digest(bytesToSign);
}
});
sut = new X509CertificateFactory(cacheFolder.getRoot().toPath(), 500, 5000);
}
use of java.security.spec.X509EncodedKeySpec in project platform_frameworks_base by android.
the class ApkSignatureSchemeV2Verifier method verifySigner.
private static X509Certificate[] verifySigner(ByteBuffer signerBlock, Map<Integer, byte[]> contentDigests, CertificateFactory certFactory) throws SecurityException, IOException {
ByteBuffer signedData = getLengthPrefixedSlice(signerBlock);
ByteBuffer signatures = getLengthPrefixedSlice(signerBlock);
byte[] publicKeyBytes = readLengthPrefixedByteArray(signerBlock);
int signatureCount = 0;
int bestSigAlgorithm = -1;
byte[] bestSigAlgorithmSignatureBytes = null;
List<Integer> signaturesSigAlgorithms = new ArrayList<>();
while (signatures.hasRemaining()) {
signatureCount++;
try {
ByteBuffer signature = getLengthPrefixedSlice(signatures);
if (signature.remaining() < 8) {
throw new SecurityException("Signature record too short");
}
int sigAlgorithm = signature.getInt();
signaturesSigAlgorithms.add(sigAlgorithm);
if (!isSupportedSignatureAlgorithm(sigAlgorithm)) {
continue;
}
if ((bestSigAlgorithm == -1) || (compareSignatureAlgorithm(sigAlgorithm, bestSigAlgorithm) > 0)) {
bestSigAlgorithm = sigAlgorithm;
bestSigAlgorithmSignatureBytes = readLengthPrefixedByteArray(signature);
}
} catch (IOException | BufferUnderflowException e) {
throw new SecurityException("Failed to parse signature record #" + signatureCount, e);
}
}
if (bestSigAlgorithm == -1) {
if (signatureCount == 0) {
throw new SecurityException("No signatures found");
} else {
throw new SecurityException("No supported signatures found");
}
}
String keyAlgorithm = getSignatureAlgorithmJcaKeyAlgorithm(bestSigAlgorithm);
Pair<String, ? extends AlgorithmParameterSpec> signatureAlgorithmParams = getSignatureAlgorithmJcaSignatureAlgorithm(bestSigAlgorithm);
String jcaSignatureAlgorithm = signatureAlgorithmParams.first;
AlgorithmParameterSpec jcaSignatureAlgorithmParams = signatureAlgorithmParams.second;
boolean sigVerified;
try {
PublicKey publicKey = KeyFactory.getInstance(keyAlgorithm).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Signature sig = Signature.getInstance(jcaSignatureAlgorithm);
sig.initVerify(publicKey);
if (jcaSignatureAlgorithmParams != null) {
sig.setParameter(jcaSignatureAlgorithmParams);
}
sig.update(signedData);
sigVerified = sig.verify(bestSigAlgorithmSignatureBytes);
} catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | InvalidAlgorithmParameterException | SignatureException e) {
throw new SecurityException("Failed to verify " + jcaSignatureAlgorithm + " signature", e);
}
if (!sigVerified) {
throw new SecurityException(jcaSignatureAlgorithm + " signature did not verify");
}
// Signature over signedData has verified.
byte[] contentDigest = null;
signedData.clear();
ByteBuffer digests = getLengthPrefixedSlice(signedData);
List<Integer> digestsSigAlgorithms = new ArrayList<>();
int digestCount = 0;
while (digests.hasRemaining()) {
digestCount++;
try {
ByteBuffer digest = getLengthPrefixedSlice(digests);
if (digest.remaining() < 8) {
throw new IOException("Record too short");
}
int sigAlgorithm = digest.getInt();
digestsSigAlgorithms.add(sigAlgorithm);
if (sigAlgorithm == bestSigAlgorithm) {
contentDigest = readLengthPrefixedByteArray(digest);
}
} catch (IOException | BufferUnderflowException e) {
throw new IOException("Failed to parse digest record #" + digestCount, e);
}
}
if (!signaturesSigAlgorithms.equals(digestsSigAlgorithms)) {
throw new SecurityException("Signature algorithms don't match between digests and signatures records");
}
int digestAlgorithm = getSignatureAlgorithmContentDigestAlgorithm(bestSigAlgorithm);
byte[] previousSignerDigest = contentDigests.put(digestAlgorithm, contentDigest);
if ((previousSignerDigest != null) && (!MessageDigest.isEqual(previousSignerDigest, contentDigest))) {
throw new SecurityException(getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm) + " contents digest does not match the digest specified by a preceding signer");
}
ByteBuffer certificates = getLengthPrefixedSlice(signedData);
List<X509Certificate> certs = new ArrayList<>();
int certificateCount = 0;
while (certificates.hasRemaining()) {
certificateCount++;
byte[] encodedCert = readLengthPrefixedByteArray(certificates);
X509Certificate certificate;
try {
certificate = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(encodedCert));
} catch (CertificateException e) {
throw new SecurityException("Failed to decode certificate #" + certificateCount, e);
}
certificate = new VerbatimX509Certificate(certificate, encodedCert);
certs.add(certificate);
}
if (certs.isEmpty()) {
throw new SecurityException("No certificates listed");
}
X509Certificate mainCertificate = certs.get(0);
byte[] certificatePublicKeyBytes = mainCertificate.getPublicKey().getEncoded();
if (!Arrays.equals(publicKeyBytes, certificatePublicKeyBytes)) {
throw new SecurityException("Public key mismatch between certificate and signature record");
}
return certs.toArray(new X509Certificate[certs.size()]);
}
use of java.security.spec.X509EncodedKeySpec in project platform_frameworks_base by android.
the class AndroidKeyStoreProvider method getAndroidKeyStorePublicKey.
@NonNull
public static AndroidKeyStorePublicKey getAndroidKeyStorePublicKey(@NonNull String alias, int uid, @NonNull @KeyProperties.KeyAlgorithmEnum String keyAlgorithm, @NonNull byte[] x509EncodedForm) {
PublicKey publicKey;
try {
KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedForm));
} catch (NoSuchAlgorithmException e) {
throw new ProviderException("Failed to obtain " + keyAlgorithm + " KeyFactory", e);
} catch (InvalidKeySpecException e) {
throw new ProviderException("Invalid X.509 encoding of public key", e);
}
if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
return new AndroidKeyStoreECPublicKey(alias, uid, (ECPublicKey) publicKey);
} else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
return new AndroidKeyStoreRSAPublicKey(alias, uid, (RSAPublicKey) publicKey);
} else {
throw new ProviderException("Unsupported Android Keystore public key algorithm: " + keyAlgorithm);
}
}
use of java.security.spec.X509EncodedKeySpec in project platform_frameworks_base by android.
the class AndroidKeyStoreKeyFactorySpi method engineGetKeySpec.
@Override
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpecClass) throws InvalidKeySpecException {
if (key == null) {
throw new InvalidKeySpecException("key == null");
} else if ((!(key instanceof AndroidKeyStorePrivateKey)) && (!(key instanceof AndroidKeyStorePublicKey))) {
throw new InvalidKeySpecException("Unsupported key type: " + key.getClass().getName() + ". This KeyFactory supports only Android Keystore asymmetric keys");
}
if (keySpecClass == null) {
throw new InvalidKeySpecException("keySpecClass == null");
} else if (KeyInfo.class.equals(keySpecClass)) {
if (!(key instanceof AndroidKeyStorePrivateKey)) {
throw new InvalidKeySpecException("Unsupported key type: " + key.getClass().getName() + ". KeyInfo can be obtained only for Android Keystore private keys");
}
AndroidKeyStorePrivateKey keystorePrivateKey = (AndroidKeyStorePrivateKey) key;
String keyAliasInKeystore = keystorePrivateKey.getAlias();
String entryAlias;
if (keyAliasInKeystore.startsWith(Credentials.USER_PRIVATE_KEY)) {
entryAlias = keyAliasInKeystore.substring(Credentials.USER_PRIVATE_KEY.length());
} else {
throw new InvalidKeySpecException("Invalid key alias: " + keyAliasInKeystore);
}
@SuppressWarnings("unchecked") T result = (T) AndroidKeyStoreSecretKeyFactorySpi.getKeyInfo(mKeyStore, entryAlias, keyAliasInKeystore, keystorePrivateKey.getUid());
return result;
} else if (X509EncodedKeySpec.class.equals(keySpecClass)) {
if (!(key instanceof AndroidKeyStorePublicKey)) {
throw new InvalidKeySpecException("Unsupported key type: " + key.getClass().getName() + ". X509EncodedKeySpec can be obtained only for Android Keystore public" + " keys");
}
@SuppressWarnings("unchecked") T result = (T) new X509EncodedKeySpec(((AndroidKeyStorePublicKey) key).getEncoded());
return result;
} else if (PKCS8EncodedKeySpec.class.equals(keySpecClass)) {
if (key instanceof AndroidKeyStorePrivateKey) {
throw new InvalidKeySpecException("Key material export of Android Keystore private keys is not supported");
} else {
throw new InvalidKeySpecException("Cannot export key material of public key in PKCS#8 format." + " Only X.509 format (X509EncodedKeySpec) supported for public keys.");
}
} else if (RSAPublicKeySpec.class.equals(keySpecClass)) {
if (key instanceof AndroidKeyStoreRSAPublicKey) {
AndroidKeyStoreRSAPublicKey rsaKey = (AndroidKeyStoreRSAPublicKey) key;
@SuppressWarnings("unchecked") T result = (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
return result;
} else {
throw new InvalidKeySpecException("Obtaining RSAPublicKeySpec not supported for " + key.getAlgorithm() + " " + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public") + " key");
}
} else if (ECPublicKeySpec.class.equals(keySpecClass)) {
if (key instanceof AndroidKeyStoreECPublicKey) {
AndroidKeyStoreECPublicKey ecKey = (AndroidKeyStoreECPublicKey) key;
@SuppressWarnings("unchecked") T result = (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
return result;
} else {
throw new InvalidKeySpecException("Obtaining ECPublicKeySpec not supported for " + key.getAlgorithm() + " " + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public") + " key");
}
} else {
throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
}
}
Aggregations