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