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