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 17package android.security.keystore.recovery; 18 19import java.io.ByteArrayInputStream; 20import java.io.InputStream; 21import java.security.cert.CertificateException; 22import java.security.cert.CertificateFactory; 23import java.security.cert.X509Certificate; 24import java.util.Base64; 25 26/** 27 * Static helper methods for decoding {@link X509Certificate} instances. 28 * 29 * @hide 30 */ 31public 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 */ 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 */ 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 */ 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 */ 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