1 /* 2 * Copyright (c) 2021-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.api; 17 18 import com.ohos.hapsigntool.cert.CertBuilder; 19 import com.ohos.hapsigntool.cert.CertLevel; 20 import com.ohos.hapsigntool.adapter.LocalizationAdapter; 21 import com.ohos.hapsigntool.entity.Options; 22 import com.ohos.hapsigntool.error.CustomException; 23 import com.ohos.hapsigntool.error.ERROR; 24 import com.ohos.hapsigntool.error.SignToolErrMsg; 25 import com.ohos.hapsigntool.utils.CertUtils; 26 27 import com.ohos.hapsigntool.utils.LogUtils; 28 import org.bouncycastle.asn1.x500.X500Name; 29 import org.bouncycastle.asn1.x509.KeyPurposeId; 30 import org.bouncycastle.asn1.x509.KeyUsage; 31 import org.bouncycastle.pkcs.PKCS10CertificationRequest; 32 import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; 33 34 import java.io.IOException; 35 import java.security.KeyPair; 36 import java.security.cert.X509Certificate; 37 38 /** 39 * CertTools. 40 * 41 * @since 2021/12/28 42 */ 43 public final class CertTools { 44 /** 45 * Ten years, in days. 46 */ 47 private static final int TEN_YEAR_DAY = 3650; 48 49 /** 50 * Three years, in dats. 51 */ 52 private static final int THREE_YEAR_DAY = 1095; 53 54 /** 55 * Empty csr array. 56 */ 57 private static final byte[] NO_CSR = {}; 58 59 /** 60 * Logger. 61 */ 62 private static final LogUtils LOGGER = new LogUtils(ServiceApi.class); 63 CertTools()64 private CertTools() { 65 } 66 67 /** 68 * Generate root ca certificate. 69 * 70 * @param keyPair keyPair 71 * @param csr csr 72 * @param adapter adapter 73 * @return X509Certificate 74 */ generateRootCaCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter)75 public static X509Certificate generateRootCaCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter) { 76 try { 77 return new CertBuilder(keyPair, adapter.getIssuer(), csr, 78 adapter.getOptions().getInt(Options.VALIDITY, TEN_YEAR_DAY)) 79 .withAuthorityKeyIdentifier(CertLevel.ROOT_CA) 80 .withBasicConstraints(CertLevel.ROOT_CA, true, true, 81 adapter.getBasicConstraintsPathLen()) 82 .withKeyUsages(new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign), true) 83 .withExtKeyUsages(null, false) 84 .build(adapter.getSignAlg()); 85 } catch (IOException exception) { 86 LOGGER.debug(exception.getMessage(), exception); 87 CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED 88 .toString(exception.getMessage())); 89 } 90 return null; 91 } 92 93 /** 94 * Generate sub ca certificate. 95 * 96 * @param keyPair keyPair 97 * @param csr csr 98 * @param adapter parameter 99 * @return X509Certificate 100 */ generateSubCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter)101 public static X509Certificate generateSubCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter) { 102 try { 103 return new CertBuilder(keyPair, adapter.getIssuer(), csr, 104 adapter.getOptions().getInt(Options.VALIDITY, TEN_YEAR_DAY)) 105 .withAuthorityKeyIdentifier(CertLevel.SUB_CA) 106 .withBasicConstraints(CertLevel.SUB_CA, true, true, 107 adapter.getBasicConstraintsPathLen()) 108 .withKeyUsages(new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign), true) 109 .build(adapter.getSignAlg()); 110 } catch (IOException exception) { 111 LOGGER.debug(exception.getMessage(), exception); 112 CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED 113 .toString(exception.getMessage())); 114 } 115 return null; 116 } 117 118 /** 119 * Generate certificate. 120 * 121 * @param keyPair keyPair 122 * @param csr csr 123 * @param adapter parameter 124 * @return X509Certificate 125 */ generateCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter)126 public static X509Certificate generateCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter) { 127 try { 128 return new CertBuilder(keyPair, adapter.getIssuer(), csr, 129 adapter.getOptions().getInt(Options.VALIDITY, THREE_YEAR_DAY)) 130 // Need CertLevel 131 .withAuthorityKeyIdentifier(CertLevel.ROOT_CA) 132 .withBasicConstraints(CertLevel.ROOT_CA, 133 adapter.isBasicConstraintsCritical(), 134 adapter.isBasicConstraintsCa(), 135 adapter.getBasicConstraintsPathLen()) 136 .withKeyUsages(adapter.getKeyUsage(), adapter.isKeyUsageCritical()) 137 .withExtKeyUsages(adapter.getExtKeyUsage(), adapter.isExtKeyUsageCritical()) 138 .build(adapter.getSignAlg()); 139 } catch (IOException exception) { 140 LOGGER.debug(exception.getMessage(), exception); 141 CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED 142 .toString(exception.getMessage())); 143 } 144 return null; 145 } 146 147 /** 148 * Generate app certificate. 149 * 150 * @param keyPair keyPair 151 * @param csr csr 152 * @param adapter adapter 153 * @param signingCapabiltyBytes signingCapabiltyBytes 154 * @return X509Certificate 155 */ generateEndCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter, byte[] signingCapabiltyBytes)156 public static X509Certificate generateEndCert(KeyPair keyPair, byte[] csr, LocalizationAdapter adapter, 157 byte[] signingCapabiltyBytes) { 158 try { 159 return new CertBuilder(keyPair, adapter.getIssuer(), csr, 160 adapter.getOptions().getInt(Options.VALIDITY, THREE_YEAR_DAY)) 161 .withBasicConstraints(CertLevel.END_ENTITY, false, false, 162 null) 163 .withKeyUsages(new KeyUsage(KeyUsage.digitalSignature), true) 164 .withExtKeyUsages(new KeyPurposeId[]{KeyPurposeId.id_kp_codeSigning}, false) 165 .withSigningCapabilty(signingCapabiltyBytes) 166 .build(adapter.getSignAlg()); 167 } catch (IOException exception) { 168 LOGGER.debug(exception.getMessage(), exception); 169 CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED 170 .toString(exception.getMessage())); 171 } 172 return null; 173 } 174 175 /** 176 * generateCsr. 177 * 178 * @param keyPair Applier keypair 179 * @param signAlgorithm sign algorithm 180 * @param subject Applier subject 181 * @return csr bytes 182 */ generateCsr(KeyPair keyPair, String signAlgorithm, X500Name subject)183 public static byte[] generateCsr(KeyPair keyPair, String signAlgorithm, X500Name subject) { 184 JcaPKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(subject, 185 keyPair.getPublic()); 186 PKCS10CertificationRequest csr = csrBuilder.build(CertUtils.createFixedContentSigner(keyPair.getPrivate(), 187 signAlgorithm)); 188 try { 189 return csr.getEncoded(); 190 } catch (IOException exception) { 191 LOGGER.debug(exception.getMessage(), exception); 192 CustomException.throwException(ERROR.IO_CSR_ERROR, SignToolErrMsg.IO_CSR_ERROR 193 .toString("Not support " + subject)); 194 return NO_CSR; 195 } 196 } 197 198 199 200 } 201