blob: 09c206d2fef938575804b27b898542e46fb904b1 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.apksig.internal.util;
import com.android.apksig.ApkSignerTest;
import com.android.apksig.SigningCertificateLineage;
import com.android.apksig.util.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
/**
* Assorted methods to obtaining test input from resources.
*/
public final class Resources {
private Resources() {}
public static byte[] toByteArray(Class<?> cls, String resourceName) throws IOException {
try (InputStream in = cls.getResourceAsStream(resourceName)) {
if (in == null) {
throw new IllegalArgumentException("Resource not found: " + resourceName);
}
return ByteStreams.toByteArray(in);
}
}
public static X509Certificate toCertificate(
Class <?> cls, String resourceName) throws IOException, CertificateException {
try (InputStream in = cls.getResourceAsStream(resourceName)) {
if (in == null) {
throw new IllegalArgumentException("Resource not found: " + resourceName);
}
return (X509Certificate)
CertificateFactory.getInstance("X.509").generateCertificate(in);
}
}
public static List<X509Certificate> toCertificateChain(
Class <?> cls, String resourceName) throws IOException, CertificateException {
Collection<? extends Certificate> certs;
try (InputStream in = cls.getResourceAsStream(resourceName)) {
if (in == null) {
throw new IllegalArgumentException("Resource not found: " + resourceName);
}
certs = CertificateFactory.getInstance("X.509").generateCertificates(in);
}
List<X509Certificate> result = new ArrayList<>(certs.size());
for (Certificate cert : certs) {
result.add((X509Certificate) cert);
}
return result;
}
public static PrivateKey toPrivateKey(Class <?> cls, String resourceName)
throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
int delimiterIndex = resourceName.indexOf('-');
if (delimiterIndex == -1) {
throw new IllegalArgumentException(
"Failed to autodetect key algorithm from resource name: " + resourceName);
}
String keyAlgorithm = resourceName.substring(0, delimiterIndex).toUpperCase(Locale.US);
return toPrivateKey(cls, resourceName, keyAlgorithm);
}
public static PrivateKey toPrivateKey(
Class <?> cls, String resourceName, String keyAlgorithm)
throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
byte[] encoded = toByteArray(cls, resourceName);
// Keep overly strictly linter happy by limiting what JCA KeyFactory algorithms are used
// here
KeyFactory keyFactory;
switch (keyAlgorithm.toUpperCase(Locale.US)) {
case "RSA":
keyFactory = KeyFactory.getInstance("rsa");
break;
case "DSA":
keyFactory = KeyFactory.getInstance("dsa");
break;
case "EC":
keyFactory = KeyFactory.getInstance("ec");
break;
default:
throw new InvalidKeySpecException("Unsupported key algorithm: " + keyAlgorithm);
}
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
}
public static SigningCertificateLineage.SignerConfig toLineageSignerConfig(Class<?> cls,
String resourcePrefix) throws Exception {
PrivateKey privateKey = toPrivateKey(cls, resourcePrefix + ".pk8");
X509Certificate cert = Resources.toCertificate(cls,
resourcePrefix + ".x509.pem");
return new SigningCertificateLineage.SignerConfig.Builder(privateKey, cert).build();
}
public static DataSource toDataSource(Class<?> cls, String dataSourceResourceName)
throws IOException {
return new ByteBufferDataSource(ByteBuffer.wrap(Resources
.toByteArray(ApkSignerTest.class, dataSourceResourceName)));
}
public static SigningCertificateLineage toSigningCertificateLineage(Class<?> cls,
String fileResourceName) throws IOException {
DataSource lineageDataSource = toDataSource(cls, fileResourceName);
return SigningCertificateLineage.readFromDataSource(lineageDataSource);
}
}