xref: /aosp_15_r20/system/extras/verity/Utils.java (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker package com.android.verity;
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker import java.lang.reflect.Constructor;
20*288bf522SAndroid Build Coastguard Worker import java.io.File;
21*288bf522SAndroid Build Coastguard Worker import java.io.ByteArrayInputStream;
22*288bf522SAndroid Build Coastguard Worker import java.io.Console;
23*288bf522SAndroid Build Coastguard Worker import java.io.FileInputStream;
24*288bf522SAndroid Build Coastguard Worker import java.io.FileOutputStream;
25*288bf522SAndroid Build Coastguard Worker import java.io.InputStreamReader;
26*288bf522SAndroid Build Coastguard Worker import java.io.IOException;
27*288bf522SAndroid Build Coastguard Worker import java.security.GeneralSecurityException;
28*288bf522SAndroid Build Coastguard Worker import java.security.Key;
29*288bf522SAndroid Build Coastguard Worker import java.security.PrivateKey;
30*288bf522SAndroid Build Coastguard Worker import java.security.PublicKey;
31*288bf522SAndroid Build Coastguard Worker import java.security.KeyFactory;
32*288bf522SAndroid Build Coastguard Worker import java.security.Provider;
33*288bf522SAndroid Build Coastguard Worker import java.security.Security;
34*288bf522SAndroid Build Coastguard Worker import java.security.Signature;
35*288bf522SAndroid Build Coastguard Worker import java.security.cert.Certificate;
36*288bf522SAndroid Build Coastguard Worker import java.security.cert.CertificateFactory;
37*288bf522SAndroid Build Coastguard Worker import java.security.cert.X509Certificate;
38*288bf522SAndroid Build Coastguard Worker import java.security.spec.ECPublicKeySpec;
39*288bf522SAndroid Build Coastguard Worker import java.security.spec.ECPrivateKeySpec;
40*288bf522SAndroid Build Coastguard Worker import java.security.spec.X509EncodedKeySpec;
41*288bf522SAndroid Build Coastguard Worker import java.security.spec.PKCS8EncodedKeySpec;
42*288bf522SAndroid Build Coastguard Worker import java.security.spec.InvalidKeySpecException;
43*288bf522SAndroid Build Coastguard Worker import java.util.Arrays;
44*288bf522SAndroid Build Coastguard Worker import java.util.HashMap;
45*288bf522SAndroid Build Coastguard Worker import java.util.Map;
46*288bf522SAndroid Build Coastguard Worker 
47*288bf522SAndroid Build Coastguard Worker import javax.crypto.Cipher;
48*288bf522SAndroid Build Coastguard Worker import javax.crypto.EncryptedPrivateKeyInfo;
49*288bf522SAndroid Build Coastguard Worker import javax.crypto.SecretKeyFactory;
50*288bf522SAndroid Build Coastguard Worker import javax.crypto.spec.PBEKeySpec;
51*288bf522SAndroid Build Coastguard Worker 
52*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.asn1.ASN1InputStream;
53*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.asn1.ASN1ObjectIdentifier;
54*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
55*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
56*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
57*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
58*288bf522SAndroid Build Coastguard Worker import org.bouncycastle.util.encoders.Base64;
59*288bf522SAndroid Build Coastguard Worker 
60*288bf522SAndroid Build Coastguard Worker public class Utils {
61*288bf522SAndroid Build Coastguard Worker 
62*288bf522SAndroid Build Coastguard Worker     private static final Map<String, String> ID_TO_ALG;
63*288bf522SAndroid Build Coastguard Worker     private static final Map<String, String> ALG_TO_ID;
64*288bf522SAndroid Build Coastguard Worker 
65*288bf522SAndroid Build Coastguard Worker     static {
66*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG = new HashMap<String, String>();
67*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID = new HashMap<String, String>();
68*288bf522SAndroid Build Coastguard Worker 
X9ObjectIdentifiers.ecdsa_with_SHA256.getId()69*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA256.getId(), "SHA256withECDSA");
X9ObjectIdentifiers.ecdsa_with_SHA384.getId()70*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA384.getId(), "SHA384withECDSA");
X9ObjectIdentifiers.ecdsa_with_SHA512.getId()71*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA512.getId(), "SHA512withECDSA");
PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()72*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1withRSA");
PKCSObjectIdentifiers.sha256WithRSAEncryption.getId()73*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256withRSA");
PKCSObjectIdentifiers.sha512WithRSAEncryption.getId()74*288bf522SAndroid Build Coastguard Worker         ID_TO_ALG.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512withRSA");
75*288bf522SAndroid Build Coastguard Worker 
76*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID.put("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256.getId());
77*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID.put("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384.getId());
78*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID.put("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512.getId());
79*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID.put("SHA1withRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption.getId());
80*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID.put("SHA256withRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption.getId());
81*288bf522SAndroid Build Coastguard Worker         ALG_TO_ID.put("SHA512withRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption.getId());
82*288bf522SAndroid Build Coastguard Worker     }
83*288bf522SAndroid Build Coastguard Worker 
loadProviderIfNecessary(String providerClassName)84*288bf522SAndroid Build Coastguard Worker     private static void loadProviderIfNecessary(String providerClassName) {
85*288bf522SAndroid Build Coastguard Worker         if (providerClassName == null) {
86*288bf522SAndroid Build Coastguard Worker             return;
87*288bf522SAndroid Build Coastguard Worker         }
88*288bf522SAndroid Build Coastguard Worker 
89*288bf522SAndroid Build Coastguard Worker         final Class<?> klass;
90*288bf522SAndroid Build Coastguard Worker         try {
91*288bf522SAndroid Build Coastguard Worker             final ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
92*288bf522SAndroid Build Coastguard Worker             if (sysLoader != null) {
93*288bf522SAndroid Build Coastguard Worker                 klass = sysLoader.loadClass(providerClassName);
94*288bf522SAndroid Build Coastguard Worker             } else {
95*288bf522SAndroid Build Coastguard Worker                 klass = Class.forName(providerClassName);
96*288bf522SAndroid Build Coastguard Worker             }
97*288bf522SAndroid Build Coastguard Worker         } catch (ClassNotFoundException e) {
98*288bf522SAndroid Build Coastguard Worker             e.printStackTrace();
99*288bf522SAndroid Build Coastguard Worker             System.exit(1);
100*288bf522SAndroid Build Coastguard Worker             return;
101*288bf522SAndroid Build Coastguard Worker         }
102*288bf522SAndroid Build Coastguard Worker 
103*288bf522SAndroid Build Coastguard Worker         Constructor<?> constructor = null;
104*288bf522SAndroid Build Coastguard Worker         for (Constructor<?> c : klass.getConstructors()) {
105*288bf522SAndroid Build Coastguard Worker             if (c.getParameterTypes().length == 0) {
106*288bf522SAndroid Build Coastguard Worker                 constructor = c;
107*288bf522SAndroid Build Coastguard Worker                 break;
108*288bf522SAndroid Build Coastguard Worker             }
109*288bf522SAndroid Build Coastguard Worker         }
110*288bf522SAndroid Build Coastguard Worker         if (constructor == null) {
111*288bf522SAndroid Build Coastguard Worker             System.err.println("No zero-arg constructor found for " + providerClassName);
112*288bf522SAndroid Build Coastguard Worker             System.exit(1);
113*288bf522SAndroid Build Coastguard Worker             return;
114*288bf522SAndroid Build Coastguard Worker         }
115*288bf522SAndroid Build Coastguard Worker 
116*288bf522SAndroid Build Coastguard Worker         final Object o;
117*288bf522SAndroid Build Coastguard Worker         try {
118*288bf522SAndroid Build Coastguard Worker             o = constructor.newInstance();
119*288bf522SAndroid Build Coastguard Worker         } catch (Exception e) {
120*288bf522SAndroid Build Coastguard Worker             e.printStackTrace();
121*288bf522SAndroid Build Coastguard Worker             System.exit(1);
122*288bf522SAndroid Build Coastguard Worker             return;
123*288bf522SAndroid Build Coastguard Worker         }
124*288bf522SAndroid Build Coastguard Worker         if (!(o instanceof Provider)) {
125*288bf522SAndroid Build Coastguard Worker             System.err.println("Not a Provider class: " + providerClassName);
126*288bf522SAndroid Build Coastguard Worker             System.exit(1);
127*288bf522SAndroid Build Coastguard Worker         }
128*288bf522SAndroid Build Coastguard Worker 
129*288bf522SAndroid Build Coastguard Worker         Security.insertProviderAt((Provider) o, 1);
130*288bf522SAndroid Build Coastguard Worker     }
131*288bf522SAndroid Build Coastguard Worker 
pemToDer(String pem)132*288bf522SAndroid Build Coastguard Worker     static byte[] pemToDer(String pem) throws Exception {
133*288bf522SAndroid Build Coastguard Worker         pem = pem.replaceAll("^-.*", "");
134*288bf522SAndroid Build Coastguard Worker         String base64_der = pem.replaceAll("-.*$", "");
135*288bf522SAndroid Build Coastguard Worker         return Base64.decode(base64_der);
136*288bf522SAndroid Build Coastguard Worker     }
137*288bf522SAndroid Build Coastguard Worker 
decryptPrivateKey(byte[] encryptedPrivateKey)138*288bf522SAndroid Build Coastguard Worker     private static PKCS8EncodedKeySpec decryptPrivateKey(byte[] encryptedPrivateKey)
139*288bf522SAndroid Build Coastguard Worker         throws GeneralSecurityException {
140*288bf522SAndroid Build Coastguard Worker         EncryptedPrivateKeyInfo epkInfo;
141*288bf522SAndroid Build Coastguard Worker         try {
142*288bf522SAndroid Build Coastguard Worker             epkInfo = new EncryptedPrivateKeyInfo(encryptedPrivateKey);
143*288bf522SAndroid Build Coastguard Worker         } catch (IOException ex) {
144*288bf522SAndroid Build Coastguard Worker             // Probably not an encrypted key.
145*288bf522SAndroid Build Coastguard Worker             return null;
146*288bf522SAndroid Build Coastguard Worker         }
147*288bf522SAndroid Build Coastguard Worker 
148*288bf522SAndroid Build Coastguard Worker         char[] password = System.console().readPassword("Password for the private key file: ");
149*288bf522SAndroid Build Coastguard Worker 
150*288bf522SAndroid Build Coastguard Worker         SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName());
151*288bf522SAndroid Build Coastguard Worker         Key key = skFactory.generateSecret(new PBEKeySpec(password));
152*288bf522SAndroid Build Coastguard Worker         Arrays.fill(password, '\0');
153*288bf522SAndroid Build Coastguard Worker 
154*288bf522SAndroid Build Coastguard Worker         Cipher cipher = Cipher.getInstance(epkInfo.getAlgName());
155*288bf522SAndroid Build Coastguard Worker         cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters());
156*288bf522SAndroid Build Coastguard Worker 
157*288bf522SAndroid Build Coastguard Worker         try {
158*288bf522SAndroid Build Coastguard Worker             return epkInfo.getKeySpec(cipher);
159*288bf522SAndroid Build Coastguard Worker         } catch (InvalidKeySpecException ex) {
160*288bf522SAndroid Build Coastguard Worker             System.err.println("Password may be bad.");
161*288bf522SAndroid Build Coastguard Worker             throw ex;
162*288bf522SAndroid Build Coastguard Worker         }
163*288bf522SAndroid Build Coastguard Worker     }
164*288bf522SAndroid Build Coastguard Worker 
loadDERPrivateKey(byte[] der)165*288bf522SAndroid Build Coastguard Worker     static PrivateKey loadDERPrivateKey(byte[] der) throws Exception {
166*288bf522SAndroid Build Coastguard Worker         PKCS8EncodedKeySpec spec = decryptPrivateKey(der);
167*288bf522SAndroid Build Coastguard Worker 
168*288bf522SAndroid Build Coastguard Worker         if (spec == null) {
169*288bf522SAndroid Build Coastguard Worker             spec = new PKCS8EncodedKeySpec(der);
170*288bf522SAndroid Build Coastguard Worker         }
171*288bf522SAndroid Build Coastguard Worker 
172*288bf522SAndroid Build Coastguard Worker         ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()));
173*288bf522SAndroid Build Coastguard Worker         PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
174*288bf522SAndroid Build Coastguard Worker         String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
175*288bf522SAndroid Build Coastguard Worker 
176*288bf522SAndroid Build Coastguard Worker         return KeyFactory.getInstance(algOid).generatePrivate(spec);
177*288bf522SAndroid Build Coastguard Worker     }
178*288bf522SAndroid Build Coastguard Worker 
loadPEMPrivateKey(byte[] pem)179*288bf522SAndroid Build Coastguard Worker     static PrivateKey loadPEMPrivateKey(byte[] pem) throws Exception {
180*288bf522SAndroid Build Coastguard Worker         byte[] der = pemToDer(new String(pem));
181*288bf522SAndroid Build Coastguard Worker         return loadDERPrivateKey(der);
182*288bf522SAndroid Build Coastguard Worker     }
183*288bf522SAndroid Build Coastguard Worker 
loadPEMPrivateKeyFromFile(String keyFname)184*288bf522SAndroid Build Coastguard Worker     static PrivateKey loadPEMPrivateKeyFromFile(String keyFname) throws Exception {
185*288bf522SAndroid Build Coastguard Worker         return loadPEMPrivateKey(read(keyFname));
186*288bf522SAndroid Build Coastguard Worker     }
187*288bf522SAndroid Build Coastguard Worker 
loadDERPrivateKeyFromFile(String keyFname)188*288bf522SAndroid Build Coastguard Worker     static PrivateKey loadDERPrivateKeyFromFile(String keyFname) throws Exception {
189*288bf522SAndroid Build Coastguard Worker         return loadDERPrivateKey(read(keyFname));
190*288bf522SAndroid Build Coastguard Worker     }
191*288bf522SAndroid Build Coastguard Worker 
loadDERPublicKey(byte[] der)192*288bf522SAndroid Build Coastguard Worker     static PublicKey loadDERPublicKey(byte[] der) throws Exception {
193*288bf522SAndroid Build Coastguard Worker         X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(der);
194*288bf522SAndroid Build Coastguard Worker         KeyFactory factory = KeyFactory.getInstance("RSA");
195*288bf522SAndroid Build Coastguard Worker         return factory.generatePublic(publicKeySpec);
196*288bf522SAndroid Build Coastguard Worker     }
197*288bf522SAndroid Build Coastguard Worker 
loadPEMPublicKey(byte[] pem)198*288bf522SAndroid Build Coastguard Worker     static PublicKey loadPEMPublicKey(byte[] pem) throws Exception {
199*288bf522SAndroid Build Coastguard Worker         byte[] der = pemToDer(new String(pem));
200*288bf522SAndroid Build Coastguard Worker         X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(der);
201*288bf522SAndroid Build Coastguard Worker         KeyFactory factory = KeyFactory.getInstance("RSA");
202*288bf522SAndroid Build Coastguard Worker         return factory.generatePublic(publicKeySpec);
203*288bf522SAndroid Build Coastguard Worker     }
204*288bf522SAndroid Build Coastguard Worker 
loadPEMPublicKeyFromFile(String keyFname)205*288bf522SAndroid Build Coastguard Worker     static PublicKey loadPEMPublicKeyFromFile(String keyFname) throws Exception {
206*288bf522SAndroid Build Coastguard Worker         return loadPEMPublicKey(read(keyFname));
207*288bf522SAndroid Build Coastguard Worker     }
208*288bf522SAndroid Build Coastguard Worker 
loadDERPublicKeyFromFile(String keyFname)209*288bf522SAndroid Build Coastguard Worker     static PublicKey loadDERPublicKeyFromFile(String keyFname) throws Exception {
210*288bf522SAndroid Build Coastguard Worker         return loadDERPublicKey(read(keyFname));
211*288bf522SAndroid Build Coastguard Worker     }
212*288bf522SAndroid Build Coastguard Worker 
loadPEMCertificate(String fname)213*288bf522SAndroid Build Coastguard Worker     static X509Certificate loadPEMCertificate(String fname) throws Exception {
214*288bf522SAndroid Build Coastguard Worker         try (FileInputStream fis = new FileInputStream(fname)) {
215*288bf522SAndroid Build Coastguard Worker             CertificateFactory cf = CertificateFactory.getInstance("X.509");
216*288bf522SAndroid Build Coastguard Worker             return (X509Certificate) cf.generateCertificate(fis);
217*288bf522SAndroid Build Coastguard Worker         }
218*288bf522SAndroid Build Coastguard Worker     }
219*288bf522SAndroid Build Coastguard Worker 
getSignatureAlgorithm(Key key)220*288bf522SAndroid Build Coastguard Worker     private static String getSignatureAlgorithm(Key key) throws Exception {
221*288bf522SAndroid Build Coastguard Worker         if ("EC".equals(key.getAlgorithm())) {
222*288bf522SAndroid Build Coastguard Worker             int curveSize;
223*288bf522SAndroid Build Coastguard Worker             KeyFactory factory = KeyFactory.getInstance("EC");
224*288bf522SAndroid Build Coastguard Worker 
225*288bf522SAndroid Build Coastguard Worker             if (key instanceof PublicKey) {
226*288bf522SAndroid Build Coastguard Worker                 ECPublicKeySpec spec = factory.getKeySpec(key, ECPublicKeySpec.class);
227*288bf522SAndroid Build Coastguard Worker                 curveSize = spec.getParams().getCurve().getField().getFieldSize();
228*288bf522SAndroid Build Coastguard Worker             } else if (key instanceof PrivateKey) {
229*288bf522SAndroid Build Coastguard Worker                 ECPrivateKeySpec spec = factory.getKeySpec(key, ECPrivateKeySpec.class);
230*288bf522SAndroid Build Coastguard Worker                 curveSize = spec.getParams().getCurve().getField().getFieldSize();
231*288bf522SAndroid Build Coastguard Worker             } else {
232*288bf522SAndroid Build Coastguard Worker                 throw new InvalidKeySpecException();
233*288bf522SAndroid Build Coastguard Worker             }
234*288bf522SAndroid Build Coastguard Worker 
235*288bf522SAndroid Build Coastguard Worker             if (curveSize <= 256) {
236*288bf522SAndroid Build Coastguard Worker                 return "SHA256withECDSA";
237*288bf522SAndroid Build Coastguard Worker             } else if (curveSize <= 384) {
238*288bf522SAndroid Build Coastguard Worker                 return "SHA384withECDSA";
239*288bf522SAndroid Build Coastguard Worker             } else {
240*288bf522SAndroid Build Coastguard Worker                 return "SHA512withECDSA";
241*288bf522SAndroid Build Coastguard Worker             }
242*288bf522SAndroid Build Coastguard Worker         } else if ("RSA".equals(key.getAlgorithm())) {
243*288bf522SAndroid Build Coastguard Worker             return "SHA256withRSA";
244*288bf522SAndroid Build Coastguard Worker         } else {
245*288bf522SAndroid Build Coastguard Worker             throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm());
246*288bf522SAndroid Build Coastguard Worker         }
247*288bf522SAndroid Build Coastguard Worker     }
248*288bf522SAndroid Build Coastguard Worker 
getSignatureAlgorithmIdentifier(Key key)249*288bf522SAndroid Build Coastguard Worker     static AlgorithmIdentifier getSignatureAlgorithmIdentifier(Key key) throws Exception {
250*288bf522SAndroid Build Coastguard Worker         String id = ALG_TO_ID.get(getSignatureAlgorithm(key));
251*288bf522SAndroid Build Coastguard Worker 
252*288bf522SAndroid Build Coastguard Worker         if (id == null) {
253*288bf522SAndroid Build Coastguard Worker             throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm());
254*288bf522SAndroid Build Coastguard Worker         }
255*288bf522SAndroid Build Coastguard Worker 
256*288bf522SAndroid Build Coastguard Worker         return new AlgorithmIdentifier(new ASN1ObjectIdentifier(id));
257*288bf522SAndroid Build Coastguard Worker     }
258*288bf522SAndroid Build Coastguard Worker 
verify(PublicKey key, byte[] input, byte[] signature, AlgorithmIdentifier algId)259*288bf522SAndroid Build Coastguard Worker     static boolean verify(PublicKey key, byte[] input, byte[] signature,
260*288bf522SAndroid Build Coastguard Worker             AlgorithmIdentifier algId) throws Exception {
261*288bf522SAndroid Build Coastguard Worker         String algName = ID_TO_ALG.get(algId.getAlgorithm().getId());
262*288bf522SAndroid Build Coastguard Worker 
263*288bf522SAndroid Build Coastguard Worker         if (algName == null) {
264*288bf522SAndroid Build Coastguard Worker             throw new IllegalArgumentException("Unsupported algorithm " + algId.getAlgorithm());
265*288bf522SAndroid Build Coastguard Worker         }
266*288bf522SAndroid Build Coastguard Worker 
267*288bf522SAndroid Build Coastguard Worker         Signature verifier = Signature.getInstance(algName);
268*288bf522SAndroid Build Coastguard Worker         verifier.initVerify(key);
269*288bf522SAndroid Build Coastguard Worker         verifier.update(input);
270*288bf522SAndroid Build Coastguard Worker 
271*288bf522SAndroid Build Coastguard Worker         return verifier.verify(signature);
272*288bf522SAndroid Build Coastguard Worker     }
273*288bf522SAndroid Build Coastguard Worker 
sign(PrivateKey privateKey, byte[] input)274*288bf522SAndroid Build Coastguard Worker     static byte[] sign(PrivateKey privateKey, byte[] input) throws Exception {
275*288bf522SAndroid Build Coastguard Worker         Signature signer = Signature.getInstance(getSignatureAlgorithm(privateKey));
276*288bf522SAndroid Build Coastguard Worker         signer.initSign(privateKey);
277*288bf522SAndroid Build Coastguard Worker         signer.update(input);
278*288bf522SAndroid Build Coastguard Worker         return signer.sign();
279*288bf522SAndroid Build Coastguard Worker     }
280*288bf522SAndroid Build Coastguard Worker 
read(String fname)281*288bf522SAndroid Build Coastguard Worker     static byte[] read(String fname) throws Exception {
282*288bf522SAndroid Build Coastguard Worker         long offset = 0;
283*288bf522SAndroid Build Coastguard Worker         File f = new File(fname);
284*288bf522SAndroid Build Coastguard Worker         long length = f.length();
285*288bf522SAndroid Build Coastguard Worker         byte[] image = new byte[(int)length];
286*288bf522SAndroid Build Coastguard Worker         FileInputStream fis = new FileInputStream(f);
287*288bf522SAndroid Build Coastguard Worker         while (offset < length) {
288*288bf522SAndroid Build Coastguard Worker             offset += fis.read(image, (int)offset, (int)(length - offset));
289*288bf522SAndroid Build Coastguard Worker         }
290*288bf522SAndroid Build Coastguard Worker         fis.close();
291*288bf522SAndroid Build Coastguard Worker         return image;
292*288bf522SAndroid Build Coastguard Worker     }
293*288bf522SAndroid Build Coastguard Worker 
write(byte[] data, String fname)294*288bf522SAndroid Build Coastguard Worker     static void write(byte[] data, String fname) throws Exception{
295*288bf522SAndroid Build Coastguard Worker         FileOutputStream out = new FileOutputStream(fname);
296*288bf522SAndroid Build Coastguard Worker         out.write(data);
297*288bf522SAndroid Build Coastguard Worker         out.close();
298*288bf522SAndroid Build Coastguard Worker     }
299*288bf522SAndroid Build Coastguard Worker }
300