use of java.security.PublicKey in project android_frameworks_base by DirtyUnicorns.
the class PackageManagerService method getUidForVerifier.
private int getUidForVerifier(VerifierInfo verifierInfo) {
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
if (pkg == null) {
return -1;
} else if (pkg.mSignatures.length != 1) {
Slog.i(TAG, "Verifier package " + verifierInfo.packageName + " has more than one signature; ignoring");
return -1;
}
/*
* If the public key of the package's signature does not match
* our expected public key, then this is a different package and
* we should skip.
*/
final byte[] expectedPublicKey;
try {
final Signature verifierSig = pkg.mSignatures[0];
final PublicKey publicKey = verifierSig.getPublicKey();
expectedPublicKey = publicKey.getEncoded();
} catch (CertificateException e) {
return -1;
}
final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
Slog.i(TAG, "Verifier package " + verifierInfo.packageName + " does not have the expected public key; ignoring");
return -1;
}
return pkg.applicationInfo.uid;
}
}
use of java.security.PublicKey in project android_frameworks_base by AOSPA.
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.PublicKey in project android_frameworks_base by AOSPA.
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.PublicKey in project GNS by MobilityFirst.
the class KeyPairUtils method getGuidEntry.
/**
* Retrieves the public/private key pair for the given user.
*
* @param gnsName the name of the GNS instance (e.g. "server.gns.name:8080")
* @param username the user name
* @return the GNSProtocol.GUID.toString() entry if found, null otherwise
*/
public static GuidEntry getGuidEntry(String gnsName, String username) {
if (username == null) {
return null;
}
if (IS_ANDROID) {
return KeyPairUtilsAndroid.getGuidEntryFromPreferences(gnsName, username);
}
createSingleton();
String guid = keyStorageObj.get(generateKey(gnsName, username, GUID), "");
String publicString = keyStorageObj.get(generateKey(gnsName, username, PUBLIC), "");
String privateString = keyStorageObj.get(generateKey(gnsName, username, PRIVATE), "");
if (!guid.isEmpty() && !publicString.isEmpty() && !privateString.isEmpty()) {
try {
byte[] encodedPublicKey = DatatypeConverter.parseHexBinary(publicString);
//byte[] encodedPublicKey = ByteUtils.hexStringToByteArray(publicString);
byte[] encodedPrivateKey = DatatypeConverter.parseHexBinary(privateString);
//byte[] encodedPrivateKey = ByteUtils.hexStringToByteArray(privateString);
KeyFactory keyFactory = KeyFactory.getInstance(GNSProtocol.RSA_ALGORITHM.toString());
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return new GuidEntry(username, guid, publicKey, privateKey);
} catch (NoSuchAlgorithmException | InvalidKeySpecException | EncryptionException e) {
System.out.println(e.toString());
return null;
}
} else {
return null;
}
}
use of java.security.PublicKey in project GNS by MobilityFirst.
the class KeyPairUtilsAndroid method getAllGuids.
/**
* Return the list of all GUIDs stored locally that belong to a particular GNS
* instance
*
* @param gnsName the GNS host:port
* @return all matching GUIDs
*/
public static List<GuidEntry> getAllGuids(String gnsName) {
List<GuidEntry> guids = new LinkedList<>();
File gnsFolder = new File(GNS_KEY_DIR);
// Save the path as a string value
String extStorageDirectory = gnsFolder.toString();
File file = new File(extStorageDirectory, GNS_KEYS_FILENAME);
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
String aliasKey = line;
String guid = br.readLine();
String publicString = br.readLine();
String privateString = br.readLine();
if (aliasKey.contains(gnsName) && !publicString.isEmpty() && !privateString.isEmpty()) {
try {
byte[] encodedPublicKey = DatatypeConverter.parseHexBinary(publicString);
byte[] encodedPrivateKey = DatatypeConverter.parseHexBinary(privateString);
//byte[] encodedPublicKey = ByteUtils.hexStringToByteArray(publicString);
//byte[] encodedPrivateKey = ByteUtils.hexStringToByteArray(privateString);
KeyFactory keyFactory = KeyFactory.getInstance(GNSProtocol.RSA_ALGORITHM.toString());
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
// Strip gnsName from stored alias to only return the entity name
guids.add(new GuidEntry(aliasKey.substring(gnsName.length() + 1), guid, publicKey, privateKey));
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
Log.e(KeyPairUtilsAndroid.class.getName(), "Cannot decode keys", e);
} catch (EncryptionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
// You'll need to add proper error handling here
}
return guids;
}
Aggregations