1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security.keystore.recovery; 18 19 import java.io.ByteArrayInputStream; 20 import java.io.InputStream; 21 import java.security.cert.CertificateException; 22 import java.security.cert.CertificateFactory; 23 import java.security.cert.X509Certificate; 24 import java.util.Base64; 25 26 /** 27 * Static helper methods for decoding {@link X509Certificate} instances. 28 * 29 * @hide 30 */ 31 public class X509CertificateParsingUtils { 32 private static final String CERT_FORMAT = "X.509"; 33 34 /** 35 * Decodes an {@link X509Certificate} encoded as a base-64 string. 36 */ decodeBase64Cert(String string)37 public static X509Certificate decodeBase64Cert(String string) throws CertificateException { 38 try { 39 return decodeCert(decodeBase64(string)); 40 } catch (IllegalArgumentException e) { 41 throw new CertificateException(e); 42 } 43 } 44 45 /** 46 * Decodes a base-64 string. 47 * 48 * @throws IllegalArgumentException if not a valid base-64 string. 49 */ decodeBase64(String string)50 private static byte[] decodeBase64(String string) { 51 return Base64.getDecoder().decode(string); 52 } 53 54 /** 55 * Decodes a byte array containing an encoded X509 certificate. 56 * 57 * @param certBytes the byte array containing the encoded X509 certificate 58 * @return the decoded X509 certificate 59 * @throws CertificateException if any parsing error occurs 60 */ decodeCert(byte[] certBytes)61 private static X509Certificate decodeCert(byte[] certBytes) throws CertificateException { 62 return decodeCert(new ByteArrayInputStream(certBytes)); 63 } 64 65 /** 66 * Decodes an X509 certificate from an {@code InputStream}. 67 * 68 * @param inStream the input stream containing the encoded X509 certificate 69 * @return the decoded X509 certificate 70 * @throws CertificateException if any parsing error occurs 71 */ decodeCert(InputStream inStream)72 private static X509Certificate decodeCert(InputStream inStream) throws CertificateException { 73 CertificateFactory certFactory; 74 try { 75 certFactory = CertificateFactory.getInstance(CERT_FORMAT); 76 } catch (CertificateException e) { 77 // Should not happen, as X.509 is mandatory for all providers. 78 throw new RuntimeException(e); 79 } 80 return (X509Certificate) certFactory.generateCertificate(inStream); 81 } 82 } 83