1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package com.ohos.hapsigntool.utils; 17 18 import com.ohos.hapsigntool.hap.exception.VerifyCertificateChainException; 19 20 import java.io.File; 21 import java.io.FileInputStream; 22 import java.io.IOException; 23 import java.security.InvalidKeyException; 24 import java.security.NoSuchAlgorithmException; 25 import java.security.NoSuchProviderException; 26 import java.security.SignatureException; 27 import java.security.cert.CertificateException; 28 import java.security.cert.CertificateExpiredException; 29 import java.security.cert.CertificateFactory; 30 import java.security.cert.X509Certificate; 31 import java.security.cert.CertificateNotYetValidException; 32 import java.util.ArrayList; 33 import java.util.Collection; 34 import java.util.Collections; 35 import java.util.List; 36 37 38 /** 39 * Utils of certificate processing. 40 */ 41 public class CertificateUtils { 42 /** 43 * Constructor of Method 44 */ CertificateUtils()45 private CertificateUtils() { 46 } 47 48 /** 49 * Check cert list is cert chain. 50 * @param certs certs 51 * @throws VerifyCertificateChainException certificates in file are not certificate chain 52 */ verifyCertChain(List<X509Certificate> certs)53 public static void verifyCertChain(List<X509Certificate> certs) throws VerifyCertificateChainException { 54 if (certs.size() <= 1) { 55 return; 56 } 57 for(int i = 1; i < certs.size(); i++) { 58 try { 59 certs.get(i - 1).verify(certs.get(i).getPublicKey()); 60 certs.get(i - 1).checkValidity(); 61 if (!certs.get(i - 1).getIssuerDN().equals(certs.get(i).getSubjectDN())){ 62 throw new CertificateException("verify certificate chain issuer subject failed") ; 63 } 64 if (i == certs.size() - 1) { 65 certs.get(i).checkValidity(); 66 } 67 } catch (CertificateExpiredException | CertificateNotYetValidException e) { 68 throw new VerifyCertificateChainException("The certificate has expired! " + e.getMessage()); 69 } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException 70 | NoSuchProviderException | SignatureException e) { 71 throw new VerifyCertificateChainException("verify certificate chain failed! " + e.getMessage()); 72 } 73 } 74 } 75 76 /** 77 * Get certificates chains from input file. 78 * 79 * @param certsFile input file 80 * @return list of certificate chain 81 * @throws IOException file is not exist 82 * @throws CertificateException data in file is not certificate 83 * @throws VerifyCertificateChainException certificates in file are not certificate chain 84 */ 85 @SuppressWarnings("unchecked") getCertListFromFile(String certsFile)86 public static List<X509Certificate> getCertListFromFile(String certsFile) throws IOException, CertificateException, 87 VerifyCertificateChainException { 88 try (FileInputStream fileInputStream = FileUtils.openInputStream(new File(certsFile))) { 89 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 90 Collection<X509Certificate> certificates = 91 (Collection<X509Certificate>) cf.generateCertificates(fileInputStream); 92 if (certificates != null && certificates.size() > 0) { 93 List<X509Certificate> certs = new ArrayList<X509Certificate>(certificates); 94 CertUtils.sortCertificateChain(certs); 95 verifyCertChain(certs); 96 return certs; 97 } 98 } 99 return Collections.emptyList(); 100 } 101 } 102