• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 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.codesigning.utils;
17 
18 import org.bouncycastle.cert.X509CertificateHolder;
19 import org.bouncycastle.cms.CMSException;
20 import org.bouncycastle.cms.CMSProcessableByteArray;
21 import org.bouncycastle.cms.CMSSignedData;
22 import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
23 import org.bouncycastle.jce.provider.BouncyCastleProvider;
24 import org.bouncycastle.operator.OperatorCreationException;
25 
26 import java.security.Security;
27 import java.security.cert.CertificateException;
28 import java.util.Collection;
29 
30 /**
31  * CMS utils class
32  *
33  * @since 2023/06/05
34  */
35 public class CmsUtils {
36     static {
37         if (Security.getProvider("BC") == null) {
Security.addProvider(new BouncyCastleProvider())38             Security.addProvider(new BouncyCastleProvider());
39         }
40     }
41 
42     /**
43      * Private constructor
44      */
CmsUtils()45     private CmsUtils() {
46     }
47 
isCollectionValid(Collection<X509CertificateHolder> collection)48     private static void isCollectionValid(Collection<X509CertificateHolder> collection)
49         throws OperatorCreationException {
50         if (collection == null) {
51             throw new OperatorCreationException("No matched cert: " + collection);
52         }
53         if (collection.size() != 1) {
54             throw new OperatorCreationException(
55                 "More than one matched certs, matched certs size: " + collection.size());
56         }
57     }
58 
59     @SuppressWarnings("unchecked")
verifyCmsSignedData(CMSSignedData cmsSignedData)60     private static boolean verifyCmsSignedData(CMSSignedData cmsSignedData) throws CMSException {
61         return cmsSignedData.verifySignatures(signId -> {
62             Collection<X509CertificateHolder> collection = cmsSignedData.getCertificates().getMatches(signId);
63             isCollectionValid(collection);
64             X509CertificateHolder cert = collection.iterator().next();
65             try {
66                 return new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert);
67             } catch (CertificateException e) {
68                 throw new OperatorCreationException("Verify BC signatures failed: " + e.getMessage(), e);
69             }
70         });
71     }
72 
73     /**
74      * Verify signed data using an unsigned data digest
75      *
76      * @param unsignedDataDigest unsigned data digest
77      * @param signedData         signed data
78      * @return true if verify success
79      * @throws CMSException if error
80      */
verifySignDataWithUnsignedDataDigest(byte[] unsignedDataDigest, byte[] signedData)81     public static boolean verifySignDataWithUnsignedDataDigest(byte[] unsignedDataDigest, byte[] signedData)
82         throws CMSException {
83         CMSSignedData cmsSignedData = new CMSSignedData(new CMSProcessableByteArray(unsignedDataDigest), signedData);
84         return verifyCmsSignedData(cmsSignedData);
85     }
86 }
87