diff --git a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntool/HapSignTool.java b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntool/HapSignTool.java index b7a2f51a5e0b6d1ad8fa9abbe1d66b9fff1c5dc6..cb6f6ca064c3f5c53bfcaea24c9b09d7b302b3ad 100644 --- a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntool/HapSignTool.java +++ b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntool/HapSignTool.java @@ -26,6 +26,7 @@ import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; import com.ohos.hapsigntool.error.ParamException; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.FileUtils; import com.ohos.hapsigntool.utils.LogUtils; import com.ohos.hapsigntool.utils.StringUtils; @@ -36,7 +37,6 @@ import com.ohos.hapsigntoolcmd.Params; import java.util.ArrayList; import java.util.List; -import java.util.Locale; /** * HapSignTool. @@ -97,12 +97,10 @@ public final class HapSignTool { System.exit(1); } } catch (CustomException e) { - LOGGER.error(String.format(Locale.ROOT, "%s, code: %d. Details: %s", e.getError(), - e.getError().getErrorCode(), e.getMessage())); + LOGGER.error(e.getMessage()); System.exit(1); } catch (Exception e) { - LOGGER.error(String.format(Locale.ROOT, "UNKNOWN_ERROR, code: %d. Details: %s", - ERROR.UNKNOWN_ERROR.getErrorCode(), e.getMessage())); + LOGGER.error(SignToolErrMsg.UNKNOWN_ERROR.toString(e.getMessage())); System.exit(1); } } @@ -139,7 +137,8 @@ public final class HapSignTool { private static boolean callGenerators(Params params, ServiceApi api) { boolean isSuccess = false; - switch (params.getMethod()) { + String method = params.getMethod(); + switch (method) { case Method.GENERATE_APP_CERT: isSuccess = runAppCert(params.getOptions(), api); break; @@ -159,7 +158,7 @@ public final class HapSignTool { isSuccess = runProfileCert(params.getOptions(), api); break; default: - CustomException.throwException(ERROR.COMMAND_ERROR, "Unsupported cmd"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.UNSUPPORTED_METHOD.toString(method)); break; } return isSuccess; @@ -286,7 +285,8 @@ public final class HapSignTool { if (!LOCAL_SIGN.equalsIgnoreCase(mode) && !REMOTE_SIGN.equalsIgnoreCase(mode) && !"remoteResign".equalsIgnoreCase(mode)) { - CustomException.throwException(ERROR.COMMAND_ERROR, "mode params is incorrect"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString(Options.MODE, "value must be localSign/remoteSign/remoteResign")); } if (LOCAL_SIGN.equalsIgnoreCase(mode)) { @@ -296,7 +296,8 @@ public final class HapSignTool { checkProfile(params); String inForm = params.getString(Options.IN_FORM, "zip"); if (!StringUtils.isEmpty(inForm) && !containsIgnoreCase(inForm)) { - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "inForm params is incorrect"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString(Options.IN_FORM, "value must be " + informList)); } String signAlg = params.getString(Options.SIGN_ALG); CmdUtil.judgeEndSignAlgType(signAlg); @@ -313,7 +314,8 @@ public final class HapSignTool { return; } if (!SIGNED.equals(profileSigned) && !NOT_SIGNED.equals(profileSigned)) { - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "profileSigned params is incorrect"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString(Options.PROFILE_SIGNED, "value must be 1/0")); } if (SIGNED.equals(profileSigned)) { FileUtils.validFileType(profileFile, "p7b"); @@ -326,7 +328,8 @@ public final class HapSignTool { params.required(Options.MODE, Options.SIGN_ALG, Options.OUT_FILE, Options.IN_FILE); String mode = params.getString(Options.MODE); if (!LOCAL_SIGN.equalsIgnoreCase(mode) && !REMOTE_SIGN.equalsIgnoreCase(mode)) { - CustomException.throwException(ERROR.COMMAND_ERROR, "mode params is incorrect"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString(Options.MODE, "value must be localSign/remoteSign/remoteResign")); } if (LOCAL_SIGN.equalsIgnoreCase(mode)) { params.required(Options.KEY_STORE_FILE, Options.KEY_ALIAS, Options.PROFILE_CERT_FILE); @@ -346,7 +349,8 @@ public final class HapSignTool { Options.OUT_PROFILE); String inForm = params.getString(Options.IN_FORM, "zip"); if (!containsIgnoreCase(inForm)) { - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "inForm params must is " + informList); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString(Options.IN_FORM, "value must be " + informList)); } FileUtils.validFileType(params.getString(Options.OUT_CERT_CHAIN), "cer"); FileUtils.validFileType(params.getString(Options.OUT_PROFILE), "p7b"); diff --git a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/CmdUtil.java b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/CmdUtil.java index a43077b69d3fdce60227445de36c2f8c885770c4..1b0041c34358d98f7b1622268e5dc9de400b91de 100644 --- a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/CmdUtil.java +++ b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/CmdUtil.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntoolcmd; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.StringUtils; import com.ohos.hapsigntool.utils.ValidateUtils; @@ -51,20 +52,23 @@ public final class CmdUtil { * @return Params */ public static Params convert2Params(String[] args) { - ValidateUtils.throwIfNotMatches(args.length >= ARGS_MIN_LEN, ERROR.COMMAND_ERROR, ""); + ValidateUtils.throwIfNotMatches(args.length >= ARGS_MIN_LEN, ERROR.COMMAND_ERROR, + SignToolErrMsg.PARAM_NUM_ERROR.toString()); Params params = new Params(); - params.setMethod(args[0]); + String method = args[0]; + params.setMethod(method); String keyStandBy = null; boolean readKey = true; - List trustList = ParamsTrustlist.getTrustList(args[0]); - if (trustList.size() == 0) { - CustomException.throwException(ERROR.COMMAND_ERROR, "Unsupported cmd"); + List trustList = ParamsTrustlist.getTrustList(method); + if (trustList.isEmpty()) { + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.UNSUPPORTED_METHOD.toString(method)); } for (int i = 1; i < args.length; i++) { String value = args[i]; if (StringUtils.isEmpty(value)) { - CustomException.throwException(ERROR.COMMAND_ERROR, "param value could not be empty"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_VALUE_EMPTY + .toString("first param")); } if (readKey) { // prepare key @@ -72,12 +76,12 @@ public final class CmdUtil { value = value.equals("-signcode") ? "-signCode" : value; boolean isTrust = trustList.contains(value); ValidateUtils.throwIfNotMatches(isTrust, - ERROR.COMMAND_PARAM_ERROR, "Not support command param"); + ERROR.COMMAND_PARAM_ERROR, SignToolErrMsg.PARAM_NOT_TRUSTED.toString()); keyStandBy = value.substring(1); readKey = false; } else { - ValidateUtils.throwIfNotMatches(false, - ERROR.COMMAND_PARAM_ERROR, "param key value must in pairs"); + CustomException.throwException(ERROR.COMMAND_PARAM_ERROR, SignToolErrMsg + .PARAM_NOT_IN_PAIRS.toString()); } } else { // prepare value @@ -97,11 +101,10 @@ public final class CmdUtil { result = false; } else if (StringUtils.isEmpty(value)) { CustomException.throwException(ERROR.COMMAND_ERROR, - String.format("Command -%s could not be empty", key)); + SignToolErrMsg.PARAM_VALUE_EMPTY.toString(key)); result = false; } else if (params.getOptions().containsKey(key)) { - CustomException.throwException(ERROR.COMMAND_ERROR, - String.format("Duplicate param '%s'. Stop processing", key)); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_DUPLICATE.toString(key)); result = false; } else if (key.toLowerCase(Locale.ROOT).endsWith("pwd")) { params.getOptions().put(key, value.toCharArray()); @@ -120,8 +123,8 @@ public final class CmdUtil { */ public static void judgeAlgType(String alg) { if (!"RSA".equalsIgnoreCase(alg) && !"ECC".equalsIgnoreCase(alg)) { - CustomException.throwException(ERROR.COMMAND_ERROR, - "KeyAlg params is incorrect"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("keyAlg", "Key algorithm only allowed to be ECC or RSA.")); } } @@ -135,18 +138,19 @@ public final class CmdUtil { String[] array = {"2048", "3072", "4096", "NIST-P-256", "NIST-P-384"}; List arrayList = Arrays.asList(array); if (!arrayList.contains(size)) { - CustomException.throwException(ERROR.COMMAND_ERROR, String.format("KeySize '%s' is incorrect", size)); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("KeySize", "Key size include in set of " + arrayList)); } if ("RSA".equalsIgnoreCase(alg)) { if (!"2048".equals(size) && !"3072".equals(size) && !"4096".equals(size)) { - CustomException.throwException(ERROR.COMMAND_ERROR, - String.format("KeySize of '%s' is incorrect", alg)); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("KeySize", "Key size of RSA include in set of {2048, 3072, 4096}")); } } else { if (!"NIST-P-256".equalsIgnoreCase(size) && !"NIST-P-384".equalsIgnoreCase(size)) { - CustomException.throwException(ERROR.COMMAND_ERROR, - String.format("KeySize of '%s' is incorrect", alg)); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("KeySize", "Key size include in set of " + arrayList)); } } } @@ -160,8 +164,8 @@ public final class CmdUtil { List arrayList = Arrays.asList("SHA256withRSA", "SHA384withRSA", "SHA256withECDSA", "SHA384withECDSA"); if (!arrayList.contains(signAlg)) { - CustomException.throwException(ERROR.COMMAND_ERROR, - "SignAlg params is incorrect"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("SignAlg", "signature algorithms include " + arrayList)); } } @@ -173,8 +177,8 @@ public final class CmdUtil { public static void judgeEndSignAlgType(String signAlg) { List arrayList = Arrays.asList("SHA256withECDSA", "SHA384withECDSA"); if (!arrayList.contains(signAlg)) { - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, - "SignAlg params is incorrect, signature algorithms include SHA256withECDSA,SHA384withECDSA"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("SignAlg", "signature algorithms include SHA256withECDSA,SHA384withECDSA")); } } @@ -192,8 +196,8 @@ public final class CmdUtil { continue; } if (!supportList.contains(type.trim())) { - CustomException.throwException(ERROR.COMMAND_ERROR, - "'" + type + "' in params '" + inputType + "' is not support"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg + .PARAM_NOT_TRUSTED.toString(inputType)); } } } @@ -210,8 +214,8 @@ public final class CmdUtil { } else if (INTEGER_PATTERN.matcher(size).matches()) { return size; } else { - CustomException.throwException(ERROR.COMMAND_ERROR, - String.format("KeySize '%s' is incorrect", size)); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_CHECK_FAILED + .toString("KeySize", "Key size is incorrect")); return size; } } diff --git a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/HelpDocument.java b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/HelpDocument.java index f5f711656b144554475c96f6825dbc8870b7baa4..67d760bf2fbcbbeac3f3881228496a991762aa2e 100644 --- a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/HelpDocument.java +++ b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/HelpDocument.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntoolcmd; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.FileUtils; import com.ohos.hapsigntool.utils.LogUtils; @@ -55,7 +56,7 @@ public final class HelpDocument { logger.info(helpStr); } catch (IOException ioe) { logger.debug(ioe.getMessage(), ioe); - CustomException.throwException(ERROR.READ_FILE_ERROR, "Failed to read " + page + " resource"); + CustomException.throwException(ERROR.READ_FILE_ERROR, SignToolErrMsg.FILE_READ_FAILED.toString(page)); } } } diff --git a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/ParamsTrustlist.java b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/ParamsTrustlist.java index 56fb0ae65fd93324565c9216f6072daacdd5ad84..55fb4aa0bfdd5382f87f505fe8fc980356cbd034 100644 --- a/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/ParamsTrustlist.java +++ b/hapsigntool/hap_sign_tool/src/main/java/com/ohos/hapsigntoolcmd/ParamsTrustlist.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntoolcmd; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import java.io.BufferedReader; import java.io.IOException; @@ -83,7 +84,7 @@ public final class ParamsTrustlist { readHelpParam(br); } } catch (IOException e) { - CustomException.throwException(ERROR.READ_FILE_ERROR, "Failed to read " + page + " resource"); + CustomException.throwException(ERROR.READ_FILE_ERROR, SignToolErrMsg.FILE_READ_FAILED.toString(page)); } } diff --git a/hapsigntool/hap_sign_tool/src/test/java/com/ohos/hapsigntoolcmd/CmdUnitTest.java b/hapsigntool/hap_sign_tool/src/test/java/com/ohos/hapsigntoolcmd/CmdUnitTest.java index 26854416acd56e45e600af3719b87d2e6081db47..64d917ea69d0cc1cbef2ad487522c536f7f35d08 100644 --- a/hapsigntool/hap_sign_tool/src/test/java/com/ohos/hapsigntoolcmd/CmdUnitTest.java +++ b/hapsigntool/hap_sign_tool/src/test/java/com/ohos/hapsigntoolcmd/CmdUnitTest.java @@ -422,7 +422,7 @@ public class CmdUnitTest { /** * Add log info. */ - private static final Logger logger = LoggerFactory.getLogger(CmdUnitTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CmdUnitTest.class); /** * create test dir @@ -463,7 +463,7 @@ public class CmdUnitTest { assertFalse(FileUtils.isFileExist(CMD_KEY_APP_STORE_PATH)); assertFalse(FileUtils.isFileExist(CMD_KEY_PROFILE_STORE_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_KEY_APP_STORE_PATH); @@ -504,7 +504,7 @@ public class CmdUnitTest { assertFalse(result); assertFalse(FileUtils.isFileExist(CMD_CSR_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_CSR_PATH); @@ -535,7 +535,7 @@ public class CmdUnitTest { assertFalse(result); assertFalse(FileUtils.isFileExist(CMD_CERT_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_CERT_PATH); @@ -584,7 +584,7 @@ public class CmdUnitTest { assertFalse(FileUtils.isFileExist(CMD_SUB_APP_CA_PATH)); assertFalse(FileUtils.isFileExist(CMD_SUB_PROFILE_CA_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_ROOT_APP_CA_PATH); boolean result = generateAppRootCa(); @@ -620,7 +620,7 @@ public class CmdUnitTest { assertFalse(FileUtils.isFileExist(CMD_APP_DEBUG_CERT_PATH)); assertFalse(FileUtils.isFileExist(CMD_APP_RELEASE_CERT_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_APP_DEBUG_CERT_PATH); boolean result = HapSignTool.processCmd(new String[]{ @@ -678,7 +678,7 @@ public class CmdUnitTest { assertFalse(FileUtils.isFileExist(CMD_PROFILE_DEBUG_CERT_PATH)); assertFalse(FileUtils.isFileExist(CMD_PROFILE_RELEASE_CERT_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_PROFILE_DEBUG_CERT_PATH); boolean result = HapSignTool.processCmd(new String[]{ @@ -734,7 +734,7 @@ public class CmdUnitTest { assertFalse(result); assertFalse(FileUtils.isFileExist(CMD_SIGN_PROFILE_PATH)); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } deleteFile(CMD_SIGN_PROFILE_PATH); @@ -780,7 +780,7 @@ public class CmdUnitTest { boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.VERIFY_PROFILE}); assertFalse(result); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } boolean result = HapSignTool.processCmd(new String[]{ @@ -800,7 +800,7 @@ public class CmdUnitTest { boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.SIGN_APP}); assertFalse(result); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } } @@ -814,7 +814,7 @@ public class CmdUnitTest { boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.VERIFY_APP}); assertFalse(result); } catch (CustomException exception) { - logger.info(exception, () -> exception.getMessage()); + LOGGER.info(exception, () -> exception.getMessage()); } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/adapter/LocalizationAdapter.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/adapter/LocalizationAdapter.java index 55ce428f33a5b1cbe66c45b661b7d68698f0a651..65d85cf75bcef8906788fd00c0d81162678cdb5a 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/adapter/LocalizationAdapter.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/adapter/LocalizationAdapter.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.adapter; import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyCertificateChainException; import com.ohos.hapsigntool.utils.KeyPairTools; import com.ohos.hapsigntool.utils.KeyStoreHelper; @@ -185,7 +186,8 @@ public class LocalizationAdapter { if (keyStoreHelper == null) { initKeyStore(); } - ValidateUtils.throwIfNotMatches(!StringUtils.isEmpty(alias), ERROR.ACCESS_ERROR, "Alias could not be empty"); + ValidateUtils.throwIfNotMatches(!StringUtils.isEmpty(alias), ERROR.ACCESS_ERROR, + SignToolErrMsg.PARAM_VALUE_EMPTY.toString("KeyAlias")); KeyPair keyPair = null; if (keyStoreHelper.hasAlias(alias)) { keyPair = keyStoreHelper.loadKeyPair(alias, keyPwd); @@ -198,8 +200,7 @@ public class LocalizationAdapter { } } ValidateUtils.throwIfNotMatches(keyPair != null, ERROR.PARAM_NOT_EXIST_ERROR, - String.format("%s: '%s' is not exist in %s", Options.KEY_ALIAS, alias, - keyStoreHelper.getKeyStorePath())); + SignToolErrMsg.KEY_ALIAS_NOT_FOUND.toString(alias, keyStoreHelper.getKeyStorePath())); return keyPair; } @@ -217,8 +218,7 @@ public class LocalizationAdapter { ValidateUtils.throwIfNotMatches( certificates.size() >= MIN_CERT_CHAIN_SIZE && certificates.size() <= MAX_CERT_CHAIN_SIZE, - ERROR.NOT_SUPPORT_ERROR, String.format("Profile cert '%s' must a cert chain", certPath) - ); + ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.CERT_CHAIN_FORMAT_FAILED.toString(certPath)); return certificates; } @@ -261,22 +261,21 @@ public class LocalizationAdapter { */ public List getCertsFromFile(String certPath, String logTitle) { ValidateUtils.throwIfNotMatches(!StringUtils.isEmpty(certPath), ERROR.PARAM_NOT_EXIST_ERROR, - String.format("Params '%s' not exist", logTitle)); + SignToolErrMsg.FILE_NOT_EXIST.toString(logTitle)); File certFile = new File(certPath); ValidateUtils.throwIfNotMatches(certFile.exists(), ERROR.FILE_NOT_FOUND, - String.format("%s: '%s' not exist", logTitle, certPath)); + SignToolErrMsg.FILE_NOT_EXIST.toString(certPath)); List certificates = null; try { certificates = CertUtils.generateCertificates(FileUtils.readFile(certFile)); } catch (IOException | CertificateException | VerifyCertificateChainException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage() - + "\nSolutions:" - + "\n> The certificate format is incorrect, please check your appCertFile parameter."); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.CERT_FORMAT_FAILED + .toString(exception.getMessage())); } - ValidateUtils.throwIfNotMatches(certificates != null && certificates.size() > 0, ERROR.READ_FILE_ERROR, - String.format("Read fail from %s, bot found certificates", certPath)); + ValidateUtils.throwIfNotMatches(certificates != null && !certificates.isEmpty(), ERROR.READ_FILE_ERROR, + SignToolErrMsg.CERT_FORMAT_FAILED.toString("can not found certificates in file " + certPath)); return certificates; } @@ -388,8 +387,8 @@ public class LocalizationAdapter { */ public String getInFile() { String file = options.getString(Options.IN_FILE); - ValidateUtils.throwIfNotMatches(new File(file).exists(), ERROR.FILE_NOT_FOUND, - String.format("Required %s: '%s' not exist", Options.IN_FILE, file)); + ValidateUtils.throwIfNotMatches(new File(file).exists(), + ERROR.FILE_NOT_FOUND, SignToolErrMsg.FILE_NOT_EXIST.toString(file)); return file; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/CertTools.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/CertTools.java index f4f2abc1cd6254b2fa1a7a9021a594905915045a..9db68eccd497bf5fa54a1c9e7dc6c528b845ada6 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/CertTools.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/CertTools.java @@ -21,6 +21,7 @@ import com.ohos.hapsigntool.adapter.LocalizationAdapter; import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.CertUtils; import com.ohos.hapsigntool.utils.LogUtils; @@ -83,7 +84,8 @@ public final class CertTools { .build(adapter.getSignAlg()); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } return null; } @@ -107,7 +109,8 @@ public final class CertTools { .build(adapter.getSignAlg()); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } return null; } @@ -135,7 +138,8 @@ public final class CertTools { .build(adapter.getSignAlg()); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } return null; } @@ -162,7 +166,8 @@ public final class CertTools { .build(adapter.getSignAlg()); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } return null; } @@ -184,7 +189,8 @@ public final class CertTools { return csr.getEncoded(); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CSR_ERROR, "Not support " + subject); + CustomException.throwException(ERROR.IO_CSR_ERROR, SignToolErrMsg.IO_CSR_ERROR + .toString("Not support " + subject)); return NO_CSR; } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/SignToolServiceImpl.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/SignToolServiceImpl.java index 27fef50f041fbc09e73c078d88ecba833cb85cce..35d188ebee3ce013a38e4601c1bc7f8e3d2838c6 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/SignToolServiceImpl.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/api/SignToolServiceImpl.java @@ -20,6 +20,7 @@ import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.adapter.LocalizationAdapter; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyException; import com.ohos.hapsigntool.hap.provider.LocalJKSSignProvider; import com.ohos.hapsigntool.hap.provider.RemoteSignProvider; @@ -151,16 +152,15 @@ public class SignToolServiceImpl implements ServiceApi { String iksFile = options.getString(Options.ISSUER_KEY_STORE_FILE); if (isEmpty) { if (!StringUtils.isEmpty(iksFile) && !ksFile.equals(iksFile)) { - CustomException.throwException(ERROR.WRITE_FILE_ERROR, - String.format("Parameter '%s' and parameter '%s' are inconsistent", ksFile, iksFile)); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.GENERATE_CA_FAILED + .toString(ksFile, iksFile)); } if (options.containsKey(Options.ISSUER_KEY_STORE_RIGHTS)) { boolean isEqual = Arrays.equals(options.getChars(Options.KEY_STORE_RIGHTS), options.getChars(Options.ISSUER_KEY_STORE_RIGHTS)); if (!isEqual) { - CustomException.throwException(ERROR.WRITE_FILE_ERROR, - String.format("Parameter '%s' and parameter '%s' are inconsistent", - Options.KEY_STORE_RIGHTS, Options.ISSUER_KEY_STORE_RIGHTS)); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.GENERATE_CA_FAILED + .toString(Options.KEY_STORE_RIGHTS, Options.ISSUER_KEY_STORE_RIGHTS)); } } rootKey = subKey; @@ -287,7 +287,8 @@ public class SignToolServiceImpl implements ServiceApi { LOGGER.error(exception.getMessage()); isSign = false; } catch (VerifyException e) { - CustomException.throwException(ERROR.VERIFY_ERROR, "Verify Profile Failed! " + e.getMessage()); + CustomException.throwException(ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString(e.getMessage())); isSign = false; } return isSign; @@ -349,7 +350,8 @@ public class SignToolServiceImpl implements ServiceApi { FileUtils.write(content.getBytes(StandardCharsets.UTF_8), new File(file)); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.WRITE_FILE_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.FILE_WRITE_FAILED + .toString(exception.getMessage())); } } } @@ -372,7 +374,8 @@ public class SignToolServiceImpl implements ServiceApi { return true; } catch (CertificateException | IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.WRITE_FILE_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.FILE_WRITE_FAILED + .toString(exception.getMessage())); return false; } } @@ -398,7 +401,8 @@ public class SignToolServiceImpl implements ServiceApi { return true; } catch (CertificateException | IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.WRITE_FILE_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.FILE_WRITE_FAILED + .toString(exception.getMessage())); return false; } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/cert/CertBuilder.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/cert/CertBuilder.java index 97939ffd8c2e745e8df7c8c7d3fec9362b446781..5f2a15603fda8201cb2eca5fa6492b13f8066e13 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/cert/CertBuilder.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/cert/CertBuilder.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.cert; import com.ohos.hapsigntool.api.ServiceApi; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.CertUtils; import com.ohos.hapsigntool.utils.LogUtils; @@ -88,7 +89,8 @@ public class CertBuilder { request = new PKCS10CertificationRequest(csr); } catch (IOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CSR_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CSR_ERROR, SignToolErrMsg.IO_CSR_ERROR + .toString(exception.getMessage())); } x509v3CertificateBuilder = new X509v3CertificateBuilder( issuer, CertUtils.randomSerial(), Date.from(notBefore.atZone(ZoneId.systemDefault()).toInstant()), @@ -100,10 +102,12 @@ public class CertBuilder { extUtils.createSubjectKeyIdentifier(request.getSubjectPublicKeyInfo())); } catch (NoSuchAlgorithmException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(exception.getMessage())); } catch (CertIOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } } @@ -123,10 +127,12 @@ public class CertBuilder { } } catch (NoSuchAlgorithmException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(exception.getMessage())); } catch (CertIOException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } return this; } @@ -217,16 +223,20 @@ public class CertBuilder { cert.verify(keyPair.getPublic()); } catch (InvalidKeyException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.KEY_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.KEY_ERROR, SignToolErrMsg.INVALID_KEY + .toString(exception.getMessage())); } catch (SignatureException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.SIGN_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED + .toString(exception.getMessage())); } catch (CertificateException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.CERTIFICATE_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.CERTIFICATE_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } catch (NoSuchAlgorithmException | NoSuchProviderException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(exception.getMessage())); } return cert; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/PageInfoExtension.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/PageInfoExtension.java index 2136bd983b7fef1bcf55c661e8398a901b41682d..208f52c5ae0320c85c81188d29d0a0558593f6ee 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/PageInfoExtension.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/PageInfoExtension.java @@ -15,6 +15,7 @@ package com.ohos.hapsigntool.codesigning.datastructure; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.PageInfoException; import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException; import com.ohos.hapsigntool.codesigning.utils.NumberUtils; @@ -182,24 +183,28 @@ public class PageInfoExtension extends Extension { */ public static boolean valid(PageInfoExtension pgExtension, long dataSize) throws PageInfoException { if (!NumberUtils.isMultiple4K(pgExtension.getMapOffset())) { - throw new PageInfoException(String.format(Locale.ROOT, "Invalid bitmapOff(%d), not a multiple of 4096", - pgExtension.getMapOffset())); + throw new PageInfoException(CodeSignErrMsg.PAGE_INFO_ERROR.toString( + "Invalid bitmapOff { " + pgExtension.getMapOffset() + " }, not a multiple of 4096")); } if (pgExtension.getUnitSize() != PageInfoExtension.DEFAULT_UNIT_SIZE) { - throw new PageInfoException("Invalid page info unitSize : " + pgExtension.getUnitSize()); + throw new PageInfoException( + CodeSignErrMsg.PAGE_INFO_ERROR.toString("Invalid page info unitSize : " + pgExtension.getUnitSize())); } if (pgExtension.getMapOffset() < 0 || pgExtension.getMapSize() < 0) { - throw new PageInfoException("Page info offset/size is negative number"); + throw new PageInfoException( + CodeSignErrMsg.PAGE_INFO_ERROR.toString("Page info offset or size is negative number")); } if (pgExtension.getMapSize() % pgExtension.getUnitSize() != 0) { - throw new PageInfoException("Page info size is not multiple of unit"); + throw new PageInfoException( + CodeSignErrMsg.PAGE_INFO_ERROR.toString("Page info size is not multiple of unit")); } if (pgExtension.getMapOffset() > dataSize - pgExtension.getMapSize() / Byte.SIZE) { - throw new PageInfoException("Page info is out of dataSize"); + throw new PageInfoException(CodeSignErrMsg.PAGE_INFO_ERROR.toString("Page info is out of dataSize")); } if (pgExtension.getMapSize() / pgExtension.getUnitSize() >= dataSize / CodeSignBlock.PAGE_SIZE_4K) { - throw new PageInfoException("page info size is not consistent with data page "); + throw new PageInfoException( + CodeSignErrMsg.PAGE_INFO_ERROR.toString("Page info size is not less than data page ")); } return true; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfHeader.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfHeader.java index 3d246d46b81288eba6a06196cac02a0bb08f8bc9..bc538579113d35e1b497bfbd54680b6c6afd55cf 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfHeader.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfHeader.java @@ -15,6 +15,7 @@ package com.ohos.hapsigntool.codesigning.elf; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.ElfFormatException; import com.ohos.hapsigntool.zip.UnsignedDecimalUtil; @@ -138,7 +139,7 @@ public class ElfHeader { } else if (eiClass == ElfDefine.ELF_64_CLASS) { len = ElfDefine.ELF_HEADER_64_LEN - ElfDefine.EI_NIDENT_LEN; } else { - throw new ElfFormatException("ELF eiClass is incorrect"); + throw new ElfFormatException(CodeSignErrMsg.ELF_FILE_HEADER_ERROR.toString("ei_class")); } ByteOrder bo; if (eiData == ElfDefine.ELF_DATA_2_LSB) { @@ -146,19 +147,19 @@ public class ElfHeader { } else if (eiData == ElfDefine.ELF_DATA_2_MSB) { bo = ByteOrder.BIG_ENDIAN; } else { - throw new ElfFormatException("ELF eiData is incorrect"); + throw new ElfFormatException(CodeSignErrMsg.ELF_FILE_HEADER_ERROR.toString("ei_data")); } byte[] bytes = new byte[len]; read = is.read(bytes); if (read != len) { - throw new ElfFormatException("ELF file header is incorrect"); + throw new ElfFormatException(CodeSignErrMsg.ELF_FILE_HEADER_ERROR.toString("header")); } ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); byteBuffer.order(bo); initHeader(byteBuffer); } - private void initHeader(ByteBuffer byteBuffer) throws ElfFormatException { + private void initHeader(ByteBuffer byteBuffer) { eType = byteBuffer.getShort(); eMachine = byteBuffer.getShort(); eVersion = byteBuffer.getInt(); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfProgramHeader.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfProgramHeader.java index 91d2a3350e087ead8804deef0b21a22664281246..c59a1d426d24211b7cdcb268b0803cf24ee97632 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfProgramHeader.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/elf/ElfProgramHeader.java @@ -15,6 +15,7 @@ package com.ohos.hapsigntool.codesigning.elf; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.ElfFormatException; import com.ohos.hapsigntool.zip.UnsignedDecimalUtil; @@ -85,13 +86,13 @@ public class ElfProgramHeader { } else if (eiData == ElfDefine.ELF_DATA_2_MSB) { bo = ByteOrder.BIG_ENDIAN; } else { - throw new ElfFormatException("ELF ei_data is incorrect"); + throw new ElfFormatException(CodeSignErrMsg.ELF_FILE_HEADER_ERROR.toString("ei_data")); } if (eiClass == ElfDefine.ELF_32_CLASS) { byte[] bytes = new byte[ElfDefine.ELF_PHEADER_32_LEN]; int read = is.read(bytes); if (read != ElfDefine.ELF_PHEADER_32_LEN) { - throw new ElfFormatException("ELF program header is incorrect"); + throw new ElfFormatException(CodeSignErrMsg.ELF_FILE_HEADER_ERROR.toString("program header")); } ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); byteBuffer.order(bo); @@ -107,7 +108,7 @@ public class ElfProgramHeader { byte[] bytes = new byte[ElfDefine.ELF_PHEADER_64_LEN]; int read = is.read(bytes); if (read != ElfDefine.ELF_PHEADER_64_LEN) { - throw new ElfFormatException("ELF program header is incorrect"); + throw new ElfFormatException(CodeSignErrMsg.ELF_FILE_HEADER_ERROR.toString("program header")); } ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); byteBuffer.order(bo); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/CodeSignErrMsg.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/CodeSignErrMsg.java new file mode 100644 index 0000000000000000000000000000000000000000..aa1ac5aa6985db916040d1aa31715498a649cb01 --- /dev/null +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/CodeSignErrMsg.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.hapsigntool.codesigning.exception; + +import com.ohos.hapsigntool.error.ErrorMsg; + +/** + * CodeSignErrMsg + * + * @since 2025/01/06 + */ +public class CodeSignErrMsg { + /** + * FILE_FORMAT_UNSUPPORTED_ERROR + */ + public static final ErrorMsg FILE_FORMAT_UNSUPPORTED_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("06") + .addErrCode("001") + .addDescription("Invalid File Format") + .addCause("Unsupported file to sign") + .addSolution("Support file format: %s") + .build(); + + /** + * READ_INPUT_STREAM_ERROR + */ + public static final ErrorMsg READ_INPUT_STREAM_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("10") + .addErrCode("001") + .addDescription("Input Stream Read Error") + .addCause("Read buffer from input error") + .build(); + + /** + * CERTIFICATES_CONFIGURE_ERROR + */ + public static final ErrorMsg CERTIFICATES_CONFIGURE_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("11") + .addErrCode("001") + .addDescription("Certificates Error") + .addCause("%s") + .addSolution("Please check whether the certificate is correct") + .build(); + + /** + * SIGNATURE_VERIFY_FAILED_ERROR + */ + public static final ErrorMsg SIGNATURE_VERIFY_FAILED_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("11") + .addErrCode("002") + .addDescription("Certificates Error") + .addCause("Signing failed") + .addSolution("Please check whether the keyAlias is correct") + .build(); + + /** + * PROFILE_TYPE_UNSUPPORTED_ERROR + */ + public static final ErrorMsg PROFILE_TYPE_UNSUPPORTED_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Profile Content Error") + .addCause("Unsupported profile type") + .addSolution("Value of 'type' in profile file should be debug or release") + .build(); + + /** + * PROFILE_TYPE_NOT_EXISTED_ERROR + */ + public static final ErrorMsg PROFILE_TYPE_NOT_EXISTED_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Profile Content Error") + .addCause("'type' not found in profile file") + .addSolution("Add 'type' to the profile file") + .build(); + + /** + * PROFILE_BUNDLE_INFO_NOT_EXISTED_ERROR + */ + public static final ErrorMsg PROFILE_BUNDLE_INFO_NOT_EXISTED_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Profile Content Error") + .addCause("'bundle-info' not found in profile file") + .addSolution("Add 'bundle-info' to the profile file") + .build(); + + /** + * PROFILE_APPID_VALUE_TYPE_ERROR + */ + public static final ErrorMsg PROFILE_APPID_VALUE_TYPE_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Profile Content Error") + .addCause("Value type of app-identifier is not string") + .addSolution("Value type of app-identifier should be string") + .build(); + + /** + * PROFILE_APPID_VALUE_LENGTH_ERROR + */ + public static final ErrorMsg PROFILE_APPID_VALUE_LENGTH_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Profile Content Error") + .addCause("Value length of app-identifier is invalid") + .addSolution("Modify to a valid app-identifier in profile file") + .build(); + + /** + * PROFILE_JSON_PARSE_ERROR + */ + public static final ErrorMsg PROFILE_JSON_PARSE_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Profile Content Error") + .addCause("Profile json content is invalid") + .addSolution("Please check whether the profile file is correct") + .build(); + + /** + * MODULE_JSON_PARSE_ERROR + */ + public static final ErrorMsg MODULE_JSON_PARSE_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("002") + .addDescription("module.json Content Error") + .addCause("module.json content is invalid") + .addSolution("Please check whether the module.json is correct") + .build(); + + /** + * HNP_FILE_DESCRIPTION_ERROR + */ + public static final ErrorMsg HNP_FILE_DESCRIPTION_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("002") + .addDescription("module.json Content Error") + .addCause("Hnp {%s} is not described in module.json") + .addSolution("Hnp file should be described in module.json") + .build(); + + /** + * ELF_FILE_HEADER_ERROR + */ + public static final ErrorMsg ELF_FILE_HEADER_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("003") + .addDescription("Elf File Error") + .addCause("ELF {%s} is incorrect") + .addSolution("Failed to read the elf file, please check whether the file header information is correct") + .build(); + + /** + * EXTRACT_HNP_FILE_ERROR + */ + public static final ErrorMsg EXTRACT_HNP_FILE_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("12") + .addErrCode("004") + .addDescription("File Format Error") + .addCause("Extract hnp file {%s} error") + .addSolution("Check whether the hnp file is packaged correctly") + .build(); + + /** + * DIGEST_ALGORITHM_ERROR + */ + public static final ErrorMsg ALGORITHM_NOT_SUPPORT_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("13") + .addErrCode("001") + .addDescription("Digest Algorithm Error") + .addCause("Invalid algorithm {%s}") + .addSolution("Support SHA-256 and SHA-512, if an error occurs, please check the JDK version") + .build(); + + /** + * CODE_SIGN_INTERNAL_ERROR + */ + public static final ErrorMsg CODE_SIGN_INTERNAL_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("14") + .addErrCode("001") + .addDescription("Code Sign Internal Error") + .addCause("%s") + .build(); + + /** + * FILE_4K_ALIGNMENT_ERROR + */ + public static final ErrorMsg FILE_4K_ALIGNMENT_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("14") + .addErrCode("001") + .addDescription("Code Sign Internal Error") + .addCause("Invalid data size {%d}, not a multiple of 4096") + .build(); + + /** + * PAGE_INFO_UNIT_SIZE_ERROR + */ + public static final ErrorMsg PAGE_INFO_ERROR = ErrorMsg.getCodeSignErrBuilder() + .addTypeCode("14") + .addErrCode("001") + .addDescription("Code Sign Internal Error") + .addCause("Page Info Error : %s") + .build(); +} diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java index da6f8ec11e7e9eb6c1c37f2aa4c6744e4164d830..1575adce7d88d35a513d8c59d1b02de50ffc8d14 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java @@ -15,6 +15,7 @@ package com.ohos.hapsigntool.codesigning.fsverity; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException; import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException; import com.ohos.hapsigntool.codesigning.utils.NumberUtils; @@ -195,7 +196,7 @@ public class FsVerityDescriptor { buffer.put(hashAlgorithm); buffer.put(log2BlockSize); if (this.saltSize > SALT_SIZE) { - throw new FsVerityDigestException("Salt is too long"); + throw new FsVerityDigestException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Salt is too long")); } buffer.put(this.saltSize); buffer.putInt(signSize); @@ -223,7 +224,7 @@ public class FsVerityDescriptor { buffer.put(hashAlgorithm); buffer.put(log2BlockSize); if (this.saltSize > SALT_SIZE) { - throw new FsVerityDigestException("Salt is too long"); + throw new FsVerityDigestException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Salt is too long")); } buffer.put(this.saltSize); buffer.putInt(0); @@ -251,7 +252,7 @@ public class FsVerityDescriptor { buffer.put(hashAlgorithm); buffer.put(log2BlockSize); if (this.saltSize > SALT_SIZE) { - throw new FsVerityDigestException("Salt is too long"); + throw new FsVerityDigestException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Salt is too long")); } buffer.put(this.saltSize); buffer.putInt(0); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java index ff7e39543e15b353f367824c07dba98d1d1102a6..50f1a1a87e7497a72d2e4b5f006d5f4ea127100f 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java @@ -16,6 +16,7 @@ package com.ohos.hapsigntool.codesigning.fsverity; import com.ohos.hapsigntool.codesigning.datastructure.PageInfoExtension; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException; import com.ohos.hapsigntool.codesigning.exception.PageInfoException; import com.ohos.hapsigntool.codesigning.utils.DigestUtils; @@ -76,9 +77,10 @@ public class FsVerityGenerator { try (MerkleTreeBuilder builder = new MerkleTreeBuilder()) { merkleTree = builder.generateMerkleTree(inputStream, size, fsVerityHashAlgorithm); } catch (IOException e) { - throw new FsVerityDigestException("IOException: " + e.getMessage()); + throw new FsVerityDigestException(e.getMessage(), e); } catch (NoSuchAlgorithmException e) { - throw new FsVerityDigestException("Invalid algorithm:" + e.getMessage()); + throw new FsVerityDigestException( + CodeSignErrMsg.ALGORITHM_NOT_SUPPORT_ERROR.toString(fsVerityHashAlgorithm.getHashAlgorithm()), e); } return merkleTree; } @@ -115,7 +117,8 @@ public class FsVerityGenerator { byte[] digest = DigestUtils.computeDigest(fsVerityDescriptor, FS_VERITY_HASH_ALGORITHM.getHashAlgorithm()); fsVerityDigest = FsVerityDigest.getFsVerityDigest(FS_VERITY_HASH_ALGORITHM.getId(), digest); } catch (NoSuchAlgorithmException e) { - throw new FsVerityDigestException("Invalid algorithm" + e.getMessage(), e); + throw new FsVerityDigestException( + CodeSignErrMsg.ALGORITHM_NOT_SUPPORT_ERROR.toString(FS_VERITY_HASH_ALGORITHM.getHashAlgorithm()), e); } if (pageInfoExtension != null && flags != 0) { PageInfoExtension.valid(pageInfoExtension, size); @@ -127,7 +130,9 @@ public class FsVerityGenerator { FS_VERITY_HASH_ALGORITHM.getHashAlgorithm()); fsVerityDigestV2 = FsVerityDigest.getFsVerityDigest(FS_VERITY_HASH_ALGORITHM.getId(), digest); } catch (NoSuchAlgorithmException e) { - throw new FsVerityDigestException("Invalid algorithm" + e.getMessage(), e); + throw new FsVerityDigestException( + CodeSignErrMsg.ALGORITHM_NOT_SUPPORT_ERROR.toString(FS_VERITY_HASH_ALGORITHM.getHashAlgorithm()), + e); } } treeBytes = merkleTree.tree; diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java index 6c5f2731e2ba0f80e56a2bf6d0f0c3a9081b03f4..3426854e4294827dd985f281d08b0ea0d4c01f19 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java @@ -15,6 +15,7 @@ package com.ohos.hapsigntool.codesigning.fsverity; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.utils.DigestUtils; import java.io.IOException; @@ -80,9 +81,9 @@ public class MerkleTreeBuilder implements AutoCloseable { private void transInputStreamToHashData(InputStream inputStream, long size, ByteBuffer outputBuffer) throws IOException { if (size == 0) { - throw new IOException("Input size is empty"); + throw new IOException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Input size is empty")); } else if (size > INPUTSTREAM_MAX_SIZE) { - throw new IOException("Input size is too long"); + throw new IOException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Input size is too long")); } int count = (int) getChunkCount(size, MAX_READ_SIZE); int chunks = (int) getChunkCount(size, CHUNK_SIZE); @@ -98,7 +99,7 @@ public class MerkleTreeBuilder implements AutoCloseable { ByteBuffer byteBuffer = ByteBuffer.allocate(fullChunkSize); int readDataLen = readIs(inputStream, byteBuffer, readSize); if (readDataLen != readSize) { - throw new IOException("IOException read buffer from input errorLHJ."); + throw new IOException(CodeSignErrMsg.READ_INPUT_STREAM_ERROR.toString()); } byteBuffer.flip(); int readChunkIndex = (int) getFullChunkSize(MAX_READ_SIZE, CHUNK_SIZE, i); @@ -195,7 +196,8 @@ public class MerkleTreeBuilder implements AutoCloseable { try { hashes[index++] = DigestUtils.computeDigest(tempByte, this.mAlgorithm); } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException(e); + throw new IllegalStateException( + CodeSignErrMsg.ALGORITHM_NOT_SUPPORT_ERROR.toString(this.mAlgorithm), e); } offset += CHUNK_SIZE; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java index a38aea41461e34569298de221a9bb461e01a5145..9dcc97705e21e891887427943da04f0bd441d8d1 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java @@ -15,14 +15,14 @@ package com.ohos.hapsigntool.codesigning.sign; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.CodeSignException; import com.ohos.hapsigntool.codesigning.utils.CmsUtils; import com.ohos.hapsigntool.codesigning.utils.DigestUtils; -import com.ohos.hapsigntool.hap.config.SignerConfig; import com.ohos.hapsigntool.entity.Pair; import com.ohos.hapsigntool.entity.ContentDigestAlgorithm; import com.ohos.hapsigntool.entity.SignatureAlgorithm; - +import com.ohos.hapsigntool.hap.config.SignerConfig; import com.ohos.hapsigntool.utils.LogUtils; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; @@ -87,10 +87,12 @@ public class BcSignedDataGenerator implements SignedDataGenerator { public void setOwnerID(String ownerID) { this.ownerID = ownerID; } + @Override public byte[] generateSignedData(byte[] content, SignerConfig signConfig) throws CodeSignException { if (content == null) { - throw new CodeSignException("Verity digest is null"); + throw new CodeSignException( + CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("The content to be signed is empty")); } Pair pairDigestAndSignInfo = getSignInfo(content, signConfig); // Unsupported certificate revocation, SignedData's _crls is null @@ -121,14 +123,16 @@ public class BcSignedDataGenerator implements SignedDataGenerator { Pair signPair = signAlgorithm.getSignatureAlgAndParams(); byte[] signBytes = signConfig.getSigner().getSignature(codeAuthed, signPair.getFirst(), signPair.getSecond()); if (signBytes == null) { - throw new CodeSignException("get signature failed"); + throw new CodeSignException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Get signature failed")); } if (signConfig.getCertificates().isEmpty()) { - throw new CodeSignException("No certificates configured for sign"); + throw new CodeSignException( + CodeSignErrMsg.CERTIFICATES_CONFIGURE_ERROR.toString("No certificate is configured for sign")); } X509Certificate cert = signConfig.getCertificates().get(0); if (!verifySignFromServer(cert.getPublicKey(), signBytes, signPair, codeAuthed)) { - throw new CodeSignException("verifySignatureFromServer failed"); + throw new CodeSignException( + CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Verify signed result failed")); } JcaX509CertificateHolder certificateHolder = getJcaX509CertificateHolder(cert); return new SignerInfo(new ASN1Integer(1), @@ -142,7 +146,7 @@ public class BcSignedDataGenerator implements SignedDataGenerator { try { digest = DigestUtils.computeDigest(unsignedDataDigest, algorithm); } catch (NoSuchAlgorithmException e) { - throw new CodeSignException("Invalid algorithm" + e.getMessage(), e); + throw new CodeSignException(CodeSignErrMsg.ALGORITHM_NOT_SUPPORT_ERROR.toString(algorithm), e); } return digest; } @@ -152,7 +156,7 @@ public class BcSignedDataGenerator implements SignedDataGenerator { try { codeAuthed = authed.getEncoded(); } catch (IOException e) { - throw new CodeSignException("cannot encode authed", e); + throw new CodeSignException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Encode data error"), e); } return codeAuthed; } @@ -162,7 +166,7 @@ public class BcSignedDataGenerator implements SignedDataGenerator { try { crlHolder = new JcaX509CRLHolder(crl); } catch (CRLException e) { - throw new CodeSignException("Create crl failed", e); + throw new CodeSignException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Create crl failed"), e); } return crlHolder; } @@ -172,7 +176,7 @@ public class BcSignedDataGenerator implements SignedDataGenerator { try { certificateHolder = new JcaX509CertificateHolder(cert); } catch (CertificateEncodingException e) { - throw new CodeSignException("Create sign info failed", e); + throw new CodeSignException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Create sign info failed"), e); } return certificateHolder; } @@ -206,7 +210,7 @@ public class BcSignedDataGenerator implements SignedDataGenerator { } signature.update(authed); if (!signature.verify(signBytes)) { - throw new CodeSignException("Signature verify failed"); + throw new CodeSignException(CodeSignErrMsg.SIGNATURE_VERIFY_FAILED_ERROR.toString()); } return true; } catch (InvalidKeyException | SignatureException e) { @@ -243,7 +247,7 @@ public class BcSignedDataGenerator implements SignedDataGenerator { ContentInfo contentInfo = new ContentInfo(PKCSObjectIdentifiers.signedData, signedData); signResult = contentInfo.getEncoded(ASN1Encoding.DER); } catch (IOException e) { - throw new CodeSignException("failed to encode unsigned data!", e); + throw new CodeSignException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Encode data error"), e); } verifySignResult(unsignedDataDigest, signResult); return signResult; @@ -254,10 +258,12 @@ public class BcSignedDataGenerator implements SignedDataGenerator { try { result = CmsUtils.verifySignDataWithUnsignedDataDigest(unsignedDataDigest, signResult); } catch (CMSException e) { - throw new CodeSignException("failed to verify signed data and unsigned data digest", e); + throw new CodeSignException( + CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("PKCS cms data verify failed"), e); } if (!result) { - throw new CodeSignException("PKCS cms data did not verify"); + throw new CodeSignException( + CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("PKCS cms data did not verify")); } } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CentralDirectory.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CentralDirectory.java deleted file mode 100644 index e664912a75a6ad8abd5bbd0297205dd5db297405..0000000000000000000000000000000000000000 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CentralDirectory.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2023-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ohos.hapsigntool.codesigning.sign; - -import com.ohos.hapsigntool.utils.FileUtils; - -import org.bouncycastle.util.Strings; - -import java.util.Locale; -import java.util.zip.ZipEntry; - -/** - * Central directory structure - * further reference to Zip Format - * - * @since 2023/09/14 - */ -public class CentralDirectory { - /** - * Byte size of all fields before "compression method" in central directory structure - */ - public static final int BYTE_SIZE_BEFORE_COMPRESSION_METHOD = 10; - - /** - * Byte size of all fields between "compression method" and "file comment length" in central directory structure - */ - public static final int BYTE_SIZE_BETWEEN_COMPRESSION_MODE_AND_FILE_SIZE = 16; - - /** - * Byte size of all fields between "file comment length" and - * "relative offset of local header" in central directory structure - */ - public static final int BYTE_SIZE_BETWEEN_FILE_COMMENT_LENGTH_AND_LOCHDR_RELATIVE_OFFSET = 8; - - private final char compressionMethod; - - private final char fileNameLength; - - private final char extraFieldLength; - - private final char fileCommentLength; - - private final long relativeOffsetOfLocalHeader; - - private final byte[] fileName; - - public CentralDirectory(Builder builder) { - this.compressionMethod = builder.compressionMethod; - this.fileNameLength = builder.fileNameLength; - this.extraFieldLength = builder.extraFieldLength; - this.fileCommentLength = builder.fileCommentLength; - this.relativeOffsetOfLocalHeader = builder.relativeOffsetOfLocalHeader; - this.fileName = builder.fileName; - } - - /** - * Return true if entry is an executable file, i.e. abc or so - * - * @return true if entry is an executable file - */ - public boolean isCodeFile() { - return FileUtils.isRunnableFile(this.getFileName()); - } - - /** - * Return true if zip entry is uncompressed - * - * @return true if zip entry is uncompressed - */ - public boolean isUncompressed() { - return this.compressionMethod == ZipEntry.STORED; - } - - public String getFileName() { - return Strings.fromByteArray(this.fileName); - } - - public long getRelativeOffsetOfLocalHeader() { - return relativeOffsetOfLocalHeader; - } - - /** - * Sum byte size of three variable fields: file name, extra field, file comment - * - * @return Sum byte size of three variable fields - */ - public char getFileNameLength() { - return fileNameLength; - } - - public char getExtraFieldLength() { - return extraFieldLength; - } - - /** - * Return a string representation of the object - * - * @return string representation of the object - */ - public String toString() { - return String.format(Locale.ROOT, - "CentralDirectory:compressionMode(%d), fileName(%s), relativeOffsetOfLocalHeader(%d), " - + "fileNameLength(%d), extraFieldLength(%d), fileCommentLength(%d)", (int) this.compressionMethod, - this.getFileName(), this.relativeOffsetOfLocalHeader, (int) this.fileNameLength, - (int) this.extraFieldLength, (int) this.fileCommentLength); - } - - /** - * Builder of CentralDirectory class - */ - public static class Builder { - private char compressionMethod; - - private char fileNameLength; - - private char extraFieldLength; - - private char fileCommentLength; - - private long relativeOffsetOfLocalHeader; - - private byte[] fileName; - - public Builder setCompressionMethod(char compressionMethod) { - this.compressionMethod = compressionMethod; - return this; - } - - public Builder setFileNameLength(char fileNameLength) { - this.fileNameLength = fileNameLength; - return this; - } - - public Builder setExtraFieldLength(char extraFieldLength) { - this.extraFieldLength = extraFieldLength; - return this; - } - - public Builder setFileCommentLength(char fileCommentLength) { - this.fileCommentLength = fileCommentLength; - return this; - } - - public Builder setRelativeOffsetOfLocalHeader(long relativeOffsetOfLocalHeader) { - this.relativeOffsetOfLocalHeader = relativeOffsetOfLocalHeader; - return this; - } - - public Builder setFileName(byte[] fileName) { - this.fileName = fileName; - return this; - } - - /** - * Create a CentralDirectory object - * - * @return a CentralDirectory object - */ - public CentralDirectory build() { - return new CentralDirectory(this); - } - } -} diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java index f30b0430b8488a6a0ee140f918971be8173be2c5..1e1bf4a1adea85078394b49a3781129bcb3ce5d4 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java @@ -23,6 +23,7 @@ import com.ohos.hapsigntool.codesigning.datastructure.MerkleTreeExtension; import com.ohos.hapsigntool.codesigning.datastructure.PageInfoExtension; import com.ohos.hapsigntool.codesigning.datastructure.SignInfo; import com.ohos.hapsigntool.codesigning.elf.ElfHeader; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.CodeSignException; import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException; import com.ohos.hapsigntool.codesigning.exception.PageInfoException; @@ -113,7 +114,7 @@ public class CodeSigning { throws CodeSignException, FsVerityDigestException, IOException, ProfileException { LOGGER.info("Start to sign code."); if (!SUPPORT_BIN_FILE_FORM.equalsIgnoreCase(inForm)) { - throw new CodeSignException("file's format is unsupported"); + throw new CodeSignException(CodeSignErrMsg.FILE_FORMAT_UNSUPPORTED_ERROR.toString(SUPPORT_BIN_FILE_FORM)); } long fileSize = input.length(); int paddingSize = ElfSignBlock.computeMerkleTreePaddingLength(offset); @@ -169,7 +170,8 @@ public class CodeSigning { throws CodeSignException, IOException, HapFormatException, FsVerityDigestException, ProfileException { LOGGER.info("Start to sign code."); if (!StringUtils.containsIgnoreCase(SUPPORT_FILE_FORM, inForm)) { - throw new CodeSignException("file's format is unsupported"); + throw new CodeSignException( + CodeSignErrMsg.FILE_FORMAT_UNSUPPORTED_ERROR.toString(String.join(",", SUPPORT_FILE_FORM))); } long dataSize = computeDataSize(zip); // generate CodeSignBlock @@ -240,8 +242,7 @@ public class CodeSigning { break; } if (!NumberUtils.isMultiple4K(dataSize)) { - throw new HapFormatException( - String.format(Locale.ROOT, "Invalid dataSize(%d), not a multiple of 4096", dataSize)); + throw new HapFormatException(CodeSignErrMsg.FILE_4K_ALIGNMENT_ERROR.toString(dataSize)); } return dataSize; } @@ -274,7 +275,7 @@ public class CodeSigning { } String hnpFileName = HapUtils.parseHnpPath(entryName); if (!hnpTypeMap.containsKey(hnpFileName)) { - throw new CodeSignException("hnp should be described in module.json"); + throw new CodeSignException(CodeSignErrMsg.HNP_FILE_DESCRIPTION_ERROR.toString(entryName)); } LOGGER.debug("Sign hnp name = {}", entryName); String type = hnpTypeMap.get(hnpFileName); @@ -293,11 +294,11 @@ public class CodeSigning { File tempHnp = File.createTempFile("tmp-", ".hnp"); writeTempHnpFile(inputJar, hnpEntry, tempHnp); if (!tempHnp.exists() || tempHnp.length() == 0) { - throw new CodeSignException("extract hnp file error"); + throw new CodeSignException(CodeSignErrMsg.EXTRACT_HNP_FILE_ERROR.toString(hnpEntry.getName())); } try (JarFile hnp = new JarFile(tempHnp, false)) { List elfEntries = getHnpLibEntries(hnp); - LOGGER.debug("{} elf num : {}", hnp.getName(), elfEntries.size()); + LOGGER.debug("{} elf num : {}", hnpEntry.getName(), elfEntries.size()); List> nativeLibInfoList = elfEntries.stream().parallel().map(entry -> { String hnpElfPath = hnpEntry.getName() + "!/" + entry.getName(); try (InputStream inputStream = hnp.getInputStream(entry)) { @@ -307,7 +308,8 @@ public class CodeSigning { false, 0, ownerID); return (Pair.create(hnpElfPath, pairSignInfoAndMerkleTreeBytes.getFirst())); } catch (IOException | FsVerityDigestException | CodeSignException e) { - LOGGER.error("Sign hnp lib error, entry name = {}, msg : {}", hnpElfPath, e.getMessage()); + LOGGER.error("Sign hnp lib error msg : {} AT entry : {}" + System.lineSeparator(), e.getMessage(), + hnpElfPath); } return null; }).collect(Collectors.toList()); @@ -315,6 +317,8 @@ public class CodeSigning { throw new CodeSignException("Sign hnp lib error"); } return nativeLibInfoList; + } catch (IOException e) { + throw new CodeSignException(CodeSignErrMsg.EXTRACT_HNP_FILE_ERROR.toString(hnpEntry.getName()), e); } finally { if (tempHnp.exists()) { if (tempHnp.delete()) { @@ -416,7 +420,7 @@ public class CodeSigning { ownerID); return Pair.create(name, pairSignInfoAndMerkleTreeBytes.getFirst()); } catch (FsVerityDigestException | CodeSignException | IOException e) { - LOGGER.error("Sign lib error, entry name = {}, msg : {}", name, e.getMessage()); + LOGGER.error("Sign lib error msg : {} AT entry : {}" + System.lineSeparator(), e.getMessage(), name); } return null; }).collect(Collectors.toList()); @@ -477,7 +481,8 @@ public class CodeSigning { // signConfig is created by SignerFactory if ((copiedConfig.getSigner() instanceof LocalSigner)) { if (copiedConfig.getCertificates().isEmpty()) { - throw new CodeSignException("No certificates configured for sign"); + throw new CodeSignException( + CodeSignErrMsg.CERTIFICATES_CONFIGURE_ERROR.toString("No certificate is configured for sign")); } BcSignedDataGenerator bcSignedDataGenerator = new BcSignedDataGenerator(); bcSignedDataGenerator.setOwnerID(ownerID); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/PageInfoGenerator.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/PageInfoGenerator.java index 7184d59e3e673a53d509377132abb6ae867b4ab4..dbcfda66f03cf63c42eba38b1687aa1634311d5c 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/PageInfoGenerator.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/PageInfoGenerator.java @@ -19,6 +19,7 @@ import com.ohos.hapsigntool.codesigning.datastructure.CodeSignBlock; import com.ohos.hapsigntool.codesigning.datastructure.PageInfoExtension; import com.ohos.hapsigntool.codesigning.elf.ElfFile; import com.ohos.hapsigntool.codesigning.elf.ElfProgramHeader; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.codesigning.exception.ElfFormatException; import com.ohos.hapsigntool.codesigning.utils.NumberUtils; import com.ohos.hapsigntool.error.HapFormatException; @@ -38,7 +39,6 @@ import java.util.ArrayList; import java.util.BitSet; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -75,8 +75,7 @@ public class PageInfoGenerator { long entryDataOffset = entry.getCentralDirectory().getOffset() + ZipEntryHeader.HEADER_LENGTH + zipEntryHeader.getFileNameLength() + zipEntryHeader.getExtraLength(); if (!NumberUtils.isMultiple4K(entryDataOffset)) { - throw new HapFormatException( - String.format(Locale.ROOT, "Invalid entryDataOffset(%d), not a multiple of 4096", entryDataOffset)); + throw new HapFormatException(CodeSignErrMsg.FILE_4K_ALIGNMENT_ERROR.toString(entryDataOffset)); } if (EntryType.RUNNABLE_FILE.equals(entry.getZipEntryData().getType()) && Zip.FILE_UNCOMPRESS_METHOD_FLAG == entry.getZipEntryData().getZipEntryHeader().getMethod()) { @@ -127,8 +126,7 @@ public class PageInfoGenerator { */ public byte[] generateBitMap() throws HapFormatException { if (!NumberUtils.isMultiple4K(maxEntryDataOffset)) { - throw new HapFormatException( - String.format(Locale.ROOT, "Invalid maxEndOff(%d), not a multiple of 4096", maxEntryDataOffset)); + throw new HapFormatException(CodeSignErrMsg.FILE_4K_ALIGNMENT_ERROR.toString(maxEntryDataOffset)); } int len = (int) (maxEntryDataOffset / CodeSignBlock.PAGE_SIZE_4K * PageInfoExtension.DEFAULT_UNIT_SIZE); BitSet bitmap = new BitSet(len); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java index df4b11a7d18f1de22400abd3c26d36f17946ec53..090c0596f6f0db039b8887e3f4bbd34e9fefcb79 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java @@ -15,6 +15,8 @@ package com.ohos.hapsigntool.codesigning.utils; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; + import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSProcessableByteArray; @@ -48,11 +50,12 @@ public class CmsUtils { private static void isCollectionValid(Collection collection) throws OperatorCreationException { if (collection == null) { - throw new OperatorCreationException("No matched cert: " + collection); + throw new OperatorCreationException( + CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("No matched cert")); } if (collection.size() != 1) { - throw new OperatorCreationException( - "More than one matched certs, matched certs size: " + collection.size()); + throw new OperatorCreationException(CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString( + "More than one matched certs, matched certs size: " + collection.size())); } } @@ -65,7 +68,9 @@ public class CmsUtils { try { return new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert); } catch (CertificateException e) { - throw new OperatorCreationException("Verify BC signatures failed: " + e.getMessage(), e); + throw new OperatorCreationException( + CodeSignErrMsg.CODE_SIGN_INTERNAL_ERROR.toString("Verify BC signatures failed: " + e.getMessage()), + e); } }); } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java index 08ffbdabbb5f16b1174774f2d9fd2c8821ad47b2..f3053573a883f4fa0689b5621c0b8a89b38c450d 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java @@ -23,22 +23,19 @@ import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; import com.google.gson.stream.JsonReader; +import com.ohos.hapsigntool.codesigning.exception.CodeSignErrMsg; import com.ohos.hapsigntool.entity.Pair; import com.ohos.hapsigntool.error.ProfileException; import com.ohos.hapsigntool.utils.LogUtils; -import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -78,56 +75,6 @@ public class HapUtils { private HapUtils() { } - /** - * Check configuration in hap to find out whether the native libs are compressed - * - * @param hapFile the given hap - * @return boolean value of parsing result - * @throws IOException io error - */ - public static boolean checkCompressNativeLibs(File hapFile) throws IOException { - try (JarFile inputJar = new JarFile(hapFile, false)) { - for (String configFile : HAP_CONFIG_FILES) { - JarEntry entry = inputJar.getJarEntry(configFile); - if (entry == null) { - continue; - } - try (InputStream data = inputJar.getInputStream(entry)) { - String jsonString = new String(InputStreamUtils.toByteArray(data, (int) entry.getSize()), - StandardCharsets.UTF_8); - return checkCompressNativeLibs(jsonString); - } - } - } - return true; - } - - /** - * Check whether the native libs are compressed by parsing config json - * - * @param jsonString the config json string - * @return boolean value of parsing result - */ - public static boolean checkCompressNativeLibs(String jsonString) { - JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject(); - Queue queue = new LinkedList<>(); - queue.offer(jsonObject); - while (queue.size() > 0) { - JsonObject curJsonObject = queue.poll(); - JsonElement jsonElement = curJsonObject.get(COMPRESS_NATIVE_LIBS_OPTION); - if (jsonElement != null) { - return jsonElement.getAsBoolean(); - } - for (Map.Entry entry : curJsonObject.entrySet()) { - if (entry.getValue().isJsonObject()) { - queue.offer(entry.getValue().getAsJsonObject()); - } - } - } - // default to compress native libs - return true; - } - /** * get app-id from profile * @@ -144,7 +91,7 @@ public class HapUtils { } else if ("release".equals(profileType)) { return ownerID; } else { - throw new ProfileException("unsupported profile type"); + throw new ProfileException(CodeSignErrMsg.PROFILE_TYPE_UNSUPPORTED_ERROR.toString()); } } @@ -163,34 +110,32 @@ public class HapUtils { JsonObject profileJson = parser.getAsJsonObject(); String profileTypeKey = "type"; if (!profileJson.has(profileTypeKey)) { - throw new ProfileException("profile has no type key"); + throw new ProfileException(CodeSignErrMsg.PROFILE_TYPE_NOT_EXISTED_ERROR.toString()); } profileType = profileJson.get(profileTypeKey).getAsString(); - if (profileType == null || profileType.length() == 0) { - throw new ProfileException("Get profile type error"); + if (profileType == null || profileType.isEmpty()) { + throw new ProfileException(CodeSignErrMsg.PROFILE_TYPE_NOT_EXISTED_ERROR.toString()); } String appIdentifier = "app-identifier"; String buildInfoMember = "bundle-info"; JsonObject buildInfoObject = profileJson.getAsJsonObject(buildInfoMember); if (buildInfoObject == null) { - throw new ProfileException("can not find bundle-info"); + throw new ProfileException(CodeSignErrMsg.PROFILE_BUNDLE_INFO_NOT_EXISTED_ERROR.toString()); } if (buildInfoObject.has(appIdentifier)) { JsonElement ownerIDElement = buildInfoObject.get(appIdentifier); if (!ownerIDElement.getAsJsonPrimitive().isString()) { - throw new ProfileException("value of app-identifier is not string"); + throw new ProfileException(CodeSignErrMsg.PROFILE_APPID_VALUE_TYPE_ERROR.toString()); } ownerID = ownerIDElement.getAsString(); if (ownerID.isEmpty() || ownerID.length() > MAX_APP_ID_LEN) { - throw new ProfileException("app-id length in profile is invalid"); + throw new ProfileException(CodeSignErrMsg.PROFILE_APPID_VALUE_LENGTH_ERROR.toString()); } - } } catch (JsonSyntaxException | UnsupportedOperationException e) { - LOGGER.error(e.getMessage()); - throw new ProfileException("profile json is invalid"); + throw new ProfileException(CodeSignErrMsg.PROFILE_JSON_PARSE_ERROR.toString(), e); } LOGGER.info("profile type is: {}", profileType); return Pair.create(ownerID, profileType); @@ -260,7 +205,7 @@ public class HapUtils { JsonObject moduleObject = jsonObject.getAsJsonObject("module"); JsonArray hnpPackageArr = moduleObject.getAsJsonArray("hnpPackages"); if (hnpPackageArr == null || hnpPackageArr.isEmpty()) { - LOGGER.debug("profile has no hnpPackages key or hnpPackages value is empty"); + LOGGER.debug("module.json has no hnpPackages key or hnpPackages value is empty"); return hnpNameMap; } hnpPackageArr.iterator().forEachRemaining((element) -> { @@ -276,8 +221,7 @@ public class HapUtils { } }); } catch (JsonParseException e) { - LOGGER.error(e.getMessage()); - throw new ProfileException("profile json is invalid"); + throw new ProfileException(CodeSignErrMsg.MODULE_JSON_PARSE_ERROR.toString(), e); } return hnpNameMap; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/InputStreamUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/InputStreamUtils.java deleted file mode 100644 index 683a69cd55715a891c2d36fe4f0379d343552dfa..0000000000000000000000000000000000000000 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/InputStreamUtils.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2023-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ohos.hapsigntool.codesigning.utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * InputStream util class - * - * @since 2023/08/10 - */ -public class InputStreamUtils { - private static final int BUFFER_SIZE = 4096; - - /** - * get byte array by inputStream and size - * - * @param inputStream inputStream data - * @param inputStreamSize inputStream size - * @return byte array value - * @throws IOException io error - */ - public static byte[] toByteArray(InputStream inputStream, int inputStreamSize) throws IOException { - if (inputStreamSize == 0) { - return new byte[0]; - } - if (inputStreamSize < 0) { - throw new IllegalArgumentException("inputStreamSize: " + inputStreamSize + "is less than zero: "); - } - try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { - copy(inputStream, inputStreamSize, output); - return output.toByteArray(); - } - } - - private static int copy(InputStream inputStream, int inputStreamSize, OutputStream output) throws IOException { - byte[] buffer = new byte[BUFFER_SIZE]; - int readSize = 0; - int count = 0; - while (readSize < inputStreamSize && (readSize = inputStream.read(buffer)) != -1) { - output.write(buffer, 0, readSize); - count += readSize; - } - if (count != inputStreamSize) { - throw new IOException("read size err. readSizeCount: " + count + ", inputStreamSize: " + inputStreamSize); - } - return count; - } -} diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/entity/Options.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/entity/Options.java index 6f5b13fcc3b277589b5ab6ee620644f7bb2e3727..8040a2396a4c3e46aa55574288b3f55dcb5d5e0b 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/entity/Options.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/entity/Options.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.entity; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.LogUtils; import java.util.HashMap; @@ -247,7 +248,7 @@ public class Options extends HashMap { /** * Logger. */ - private static final LogUtils logger = new LogUtils(Options.class); + private static final LogUtils LOGGER = new LogUtils(Options.class); /** @@ -258,7 +259,7 @@ public class Options extends HashMap { public void required(String... keys) { for (String key : keys) { if (!isEmpty(key) && !this.containsKey(key)) { - CustomException.throwException(ERROR.COMMAND_ERROR, String.format("Params '%s' is required", key)); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.PARAM_REQUIRED.toString(key)); } } } @@ -356,7 +357,7 @@ public class Options extends HashMap { try { return Integer.parseInt((String) value); } catch (NumberFormatException exception) { - logger.debug(exception.getMessage(), exception); + LOGGER.debug(exception.getMessage(), exception); } } return defValue; diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ErrorMsg.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ErrorMsg.java new file mode 100644 index 0000000000000000000000000000000000000000..b75bd5ec522b2de791655a59c2529647d2ba6b25 --- /dev/null +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ErrorMsg.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.hapsigntool.error; + +import com.ohos.hapsigntool.utils.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.MissingFormatArgumentException; + +/** + * ErrorMsg + * + * @since 2025/01/06 + */ +public class ErrorMsg { + private static final Logger log = LogManager.getLogger(ErrorMsg.class); + + private static final String CODE_SIGN_SUB_SYSTEM_CODE = "111"; + + private static final String SIGN_TOOL_SUB_SYSTEM_CODE = "110"; + + private final String code; + + private final String description; + + private final String cause; + + private final String position; + + private final List solutions; + + private MoreInfo moreInfo; + + /** + * ErrorMsg constructor + * + * @param code code + * @param description description + * @param cause cause + * @param position position + * @param solutions solutions + */ + public ErrorMsg(String code, String description, String cause, + String position, List solutions) { + this.code = code; + this.description = description; + this.cause = cause; + this.position = position; + this.solutions = solutions; + this.moreInfo = new MoreInfo(); + } + + /** + * getCodeSignErrBuilder + * + * @return Builder + */ + public static Builder getCodeSignErrBuilder() { + return new Builder(CODE_SIGN_SUB_SYSTEM_CODE); + } + + /** + * getSignToolErrBuilder + * + * @return Builder + */ + public static Builder getSignToolErrBuilder() { + return new Builder(SIGN_TOOL_SUB_SYSTEM_CODE); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append(System.lineSeparator()) + .append("ERROR: ") + .append(code) + .append(" ") + .append(description) + .append(System.lineSeparator()) + .append("Error Message: ") + .append(cause) + .append(System.lineSeparator()); + + if (!StringUtils.isEmpty(position)) { + sb.append(" At ").append(position).append(System.lineSeparator()); + } + + if (solutions != null && !solutions.isEmpty()) { + sb.append(System.lineSeparator()).append("* Try the following: ").append(System.lineSeparator()); + for (String s : solutions) { + sb.append(" > ").append(s).append(System.lineSeparator()); + } + } + return sb.toString(); + } + + /** + * to String + * + * @param args args + * @return String + */ + public String toString(Object... args) { + try { + return String.format(Locale.ROOT, this.toString(), args); + } catch (MissingFormatArgumentException e) { + log.error("args format failed: " + args); + return this.toString(); + } + } + + static class MoreInfo { + private String cn; + + private String en; + } + + /** + * Builder + * + * @since 2025/01/06 + */ + public static class Builder { + private String sysCode; + + private String errCode; + + private String typeCode; + + private String description; + + private String cause; + + private String position; + + private List solutions = new ArrayList<>(); + + /** + * Builder Constructor + * + * @param sysCode sysCode + */ + public Builder(String sysCode) { + this.sysCode = sysCode; + } + + /** + * addErrCode + * + * @param errCode errCode + * @return Builder + */ + public Builder addErrCode(String errCode) { + this.errCode = errCode; + return this; + } + + /** + * addTypeCode + * + * @param typeCode typeCode + * @return Builder + */ + public Builder addTypeCode(String typeCode) { + this.typeCode = typeCode; + return this; + } + + /** + * addDescription + * + * @param description description + * @return Builder + */ + public Builder addDescription(String description) { + this.description = description; + return this; + } + + /** + * addCause + * + * @param cause cause + * @return Builder + */ + public Builder addCause(String cause) { + this.cause = cause; + return this; + } + + /** + * addPosition + * + * @param position position + * @return Builder + */ + public Builder addPosition(String position) { + this.position = position; + return this; + } + + /** + * addSolution + * + * @param solution solution + * @return Builder + */ + public Builder addSolution(String solution) { + this.solutions.add(solution); + return this; + } + + /** + * build + * + * @return ErrorMsg + */ + public ErrorMsg build() { + return new ErrorMsg(sysCode + typeCode + errCode, description, cause, position, solutions); + } + } +} diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/SignToolErrMsg.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/SignToolErrMsg.java new file mode 100644 index 0000000000000000000000000000000000000000..e40f733442c887535a6b0271441b0cc6d74409fd --- /dev/null +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/SignToolErrMsg.java @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.hapsigntool.error; + +/** + * SignToolErrMsg + * + * @since 2025/01/06 + */ +public class SignToolErrMsg { + // unknown error + /** + * UNKNOWN_ERROR + */ + public static final ErrorMsg UNKNOWN_ERROR = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("10") + .addErrCode("001") + .addDescription("Unknown error") + .addCause("%s") + .build(); + + // command error + /** + * UNSUPPORTED_METHOD + */ + public static final ErrorMsg UNSUPPORTED_METHOD = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("001") + .addDescription("Unsupported command method") + .addCause("Can not find method {%s}") + .addSolution("Please run java -jar hap-sign-tool.jar -h to see more help message.") + .build(); + + /** + * PARAM_CHECK_FAILED + */ + public static final ErrorMsg PARAM_CHECK_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("002") + .addDescription("{%s} param is incorrect") + .addCause("%s") + .build(); + + /** + * PARAM_NUM_ERROR + */ + public static final ErrorMsg PARAM_NUM_ERROR = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("003") + .addDescription("Check param num failed") + .addCause("Please run java -jar hap-sign-tool.jar -h to see more help message.") + .build(); + + /** + * PARAM_VALUE_EMPTY + */ + public static final ErrorMsg PARAM_VALUE_EMPTY = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("004") + .addDescription("Check param failed") + .addCause("Param {%s} value could not be empty") + .build(); + + /** + * PARAM_NOT_TRUSTED + */ + public static final ErrorMsg PARAM_NOT_TRUSTED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("005") + .addDescription("Param is not trusted") + .addCause("Please run java -jar hap-sign-tool.jar -h to see more help message.") + .build(); + + /** + * PARAM_NOT_IN_PAIRS + */ + public static final ErrorMsg PARAM_NOT_IN_PAIRS = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("006") + .addDescription("Param {-key value} must in pairs") + .addCause("Please run java -jar hap-sign-tool.jar -h to see more help message.") + .build(); + + /** + * PARAM_DUPLICATE + */ + public static final ErrorMsg PARAM_DUPLICATE = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("007") + .addDescription("Check param num failed") + .addCause("Param {%s} is duplicated") + .build(); + + /** + * PARAM_REQUIRED + */ + public static final ErrorMsg PARAM_REQUIRED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("008") + .addDescription("Check param failed") + .addCause("Param {%s} is required, but can not be found") + .addSolution("Please input required param") + .build(); + + /** + * MISSING_PARAM + */ + public static final ErrorMsg MISSING_PARAM = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("11") + .addErrCode("008") + .addDescription("Check param failed") + .addCause("Missed param {%s}") + .build(); + + // file error + /** + * LOAD_REMOTE_PLUGIN_FAILED + */ + public static final ErrorMsg LOAD_REMOTE_PLUGIN_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("12") + .addErrCode("001") + .addDescription("Load remote sign plugin failed") + .addCause("%s") + .build(); + + /** + * FILE_NOT_EXIST + */ + public static final ErrorMsg FILE_NOT_EXIST = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("12") + .addErrCode("002") + .addDescription("File not exist") + .addCause("Param {%s} is not exist") + .build(); + + /** + * FILE_WRITE_FAILED + */ + public static final ErrorMsg FILE_WRITE_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("12") + .addErrCode("003") + .addDescription("Write file failed") + .addCause("%s") + .build(); + + /** + * FILE_READ_FAILED + */ + public static final ErrorMsg FILE_READ_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("12") + .addErrCode("004") + .addDescription("Read file failed") + .addCause("Read file {%s} failed") + .build(); + + /** + * NOT_SUPPORT_FILE + */ + public static final ErrorMsg NOT_SUPPORT_FILE = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("12") + .addErrCode("005") + .addDescription("Not support file") + .addCause("Not support file: %s") + .build(); + + /** + * FILE_IO_FAILED + */ + public static final ErrorMsg FILE_IO_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("12") + .addErrCode("006") + .addDescription("File IO failed") + .addCause("%s") + .build(); + + // cert error + /** + * CERT_DN_FORMAT_FAILED + */ + public static final ErrorMsg CERT_DN_FORMAT_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("001") + .addDescription("Check DN format failed") + .addCause("Format error, must be \"X=xx,XX=xxx,...\"") + .addSolution("Please check param {%s}") + .build(); + + /** + * CERT_FORMAT_FAILED + */ + public static final ErrorMsg CERT_FORMAT_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("002") + .addDescription("Certificate format is in correct, please check your appCertFile parameter.") + .addCause("%s") + .addSolution("{-appCertFile} should input a cert chain file,This file is usually suffixed with .cer.") + .build(); + + /** + * GENERATE_CA_FAILED + */ + public static final ErrorMsg GENERATE_CA_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("003") + .addDescription("Generate CA failed") + .addCause("Parameter '%s' and parameter '%s' are inconsistent") + .build(); + + /** + * CERT_CHAIN_FORMAT_FAILED + */ + public static final ErrorMsg CERT_CHAIN_FORMAT_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("004") + .addDescription("Profile cert must a cert chain") + .addCause("cause in cert file: %s") + .build(); + + /** + * NO_SUCH_SIGNATURE + */ + public static final ErrorMsg NO_SUCH_SIGNATURE = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("005") + .addDescription("No such algorithm") + .addCause("%s") + .build(); + + /** + * CERT_IO_FAILED + */ + public static final ErrorMsg CERT_IO_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("006") + .addDescription("Certificate IO failed") + .addCause("%s") + .build(); + + /** + * CERTIFICATE_ERROR + */ + public static final ErrorMsg CERTIFICATE_ERROR = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("007") + .addDescription("Certificate check failed") + .addCause("%s") + .build(); + + /** + * IO_CSR_ERROR + */ + public static final ErrorMsg IO_CSR_ERROR = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("13") + .addErrCode("008") + .addDescription("generate csr failed") + .addCause("%s") + .build(); + + // key store error + /** + * KEY_ALIAS_NOT_FOUND + */ + public static final ErrorMsg KEY_ALIAS_NOT_FOUND = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("001") + .addDescription("key alias not found") + .addCause("KeyAlias {%s} is not exist in {%s}") + .addSolution("Please check keystore file and keyAlias, ensure keyAlias is exist") + .addSolution("Use jdk tool [keytool] check keystore: [keytool -list -keystore xxx.p12]") + .build(); + + /** + * KEY_ALIAS_EXIST + */ + public static final ErrorMsg KEY_ALIAS_EXIST = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("002") + .addDescription("Key alias is exist") + .addCause("KeyAlias {%s} is exist in {%s}, cloud not overwrite.") + .addSolution("Please check keystore file and keyAlias, ensure keyAlias is not exist") + .addSolution("Use jdk tool [keytool] check keystore: [keytool -list -keystore xxx.p12]") + .build(); + + /** + * INIT_KEYSTORE_FAILED + */ + public static final ErrorMsg INIT_KEYSTORE_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("003") + .addDescription("Init keystore failed") + .addCause("%s") + .addSolution("The key store file does not exist, please check the key store file path.") + .addSolution("Incorrect keystore password, please input the correct plaintext password.") + .addSolution("The keystore was created by a newer JDK version, please use the same JDK version") + .build(); + + /** + * INVALID_KEY + */ + public static final ErrorMsg INVALID_KEY = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("004") + .addDescription("Invalid Key") + .addCause("%s") + .build(); + + /** + * ALGORITHM_NOT_SUPPORT + */ + public static final ErrorMsg ALGORITHM_NOT_SUPPORT = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("005") + .addDescription("Not support algorithm") + .addCause("%s") + .build(); + + /** + * KEYSTORE_ERROR + */ + public static final ErrorMsg KEYSTORE_ERROR = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("006") + .addDescription("Keystore exception") + .addCause("%s") + .build(); + + /** + * KEY_PASSWORD_ERROR + */ + public static final ErrorMsg KEY_PASSWORD_ERROR = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("007") + .addDescription("Key alias {%s} password error") + .addCause("%s") + .build(); + + /** + * NO_USABLE_CERT + */ + public static final ErrorMsg NO_USABLE_CERT = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("14") + .addErrCode("008") + .addDescription("No usable cert found in {%s}") + .addCause("MayBe the certificate in keystore is invalid.") + .build(); + + // signature error + /** + * SIGNATURE_FAILED + */ + public static final ErrorMsg SIGNATURE_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("15") + .addErrCode("001") + .addDescription("Signature failed") + .addCause("%s") + .build(); + + /** + * SIGNATURE_NOT_MATCHED + */ + public static final ErrorMsg SIGNATURE_NOT_MATCHED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("15") + .addErrCode("002") + .addDescription("Signature not matched!") + .addCause("Signature verify failed") + .addSolution("Please check if the keyAlias private key matches the public key in the certificate") + .addSolution("If the certificate is changed, the keyAlias should be replaced synchronously") + .build(); + + /** + * VERIFY_FAILED + */ + public static final ErrorMsg VERIFY_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("15") + .addErrCode("003") + .addDescription("Verify signature failed") + .addCause("%s") + .build(); + + /** + * VERIFY_PROFILE_FAILED + */ + public static final ErrorMsg VERIFY_PROFILE_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("15") + .addErrCode("004") + .addDescription("Verify profile failed") + .addCause("%s") + .build(); + + /** + * VERIFY_PROFILE_INVALID + */ + public static final ErrorMsg VERIFY_PROFILE_INVALID = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("15") + .addErrCode("005") + .addDescription("Verify profile failed") + .addCause("Verify profile pkcs7 failed! Profile is invalid") + .addSolution("Check if the profile is legal") + .addSolution("Maybe Failed during transmission, please download profile again") + .build(); + + /** + * VERIFY_PROFILE_FAILED + */ + public static final ErrorMsg PROFILE_CERT_MATCH_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("15") + .addErrCode("005") + .addDescription("Profile certificate match failed") + .addCause("input certificates do not match with profile") + .addSolution("Profile include signature certificate info, please ensure it same as your appCertFile") + .addSolution("When applying for profile, need to select a certificate, please choose your appCertFile") + .build(); + + + // zip error + /** + * READ_ZIP_FAILED + */ + public static final ErrorMsg READ_ZIP_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("17") + .addErrCode("001") + .addDescription("Read zip file failed") + .addCause("%s") + .addSolution("App (or hap/hsp/hnp) use zip format.") + .addSolution("Zip file can support a maximum size of 4G and 65535 sub files.") + .addSolution("If this value is exceeded, it will be automatically converted to zip64.") + .addSolution("Please check if file is zip64 format, or zip formatted correctly.") + .build(); + + /** + * WRITE_ZIP_FAILED + */ + public static final ErrorMsg WRITE_ZIP_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("17") + .addErrCode("002") + .addDescription("Write zip file failed") + .addCause("%s") + .build(); + + /** + * ALIGNMENT_ZIP_FAILED + */ + public static final ErrorMsg ALIGNMENT_ZIP_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("17") + .addErrCode("003") + .addDescription("Alignment zip file failed") + .addCause("%s") + .build(); + + /** + * ZIP_FORMAT_FAILED + */ + public static final ErrorMsg ZIP_FORMAT_FAILED = ErrorMsg.getSignToolErrBuilder() + .addTypeCode("17") + .addErrCode("004") + .addDescription("Zip format failed") + .addCause("%s") + .build(); +} diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java index e72a1556457ef5e3f48bce4c82c8bc731c4af9fe..b5d98f00b15d39bf5577baf7d5444aa1d0014ab5 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java @@ -17,7 +17,7 @@ package com.ohos.hapsigntool.hap.provider; import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.error.InvalidParamsException; -import com.ohos.hapsigntool.error.MissingParamsException; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.FileUtils; import com.ohos.hapsigntool.entity.ParamConstants; import com.ohos.hapsigntool.utils.LogUtils; @@ -80,12 +80,13 @@ public class LocalJKSSignProvider extends SignProvider { FileUtils.isValidFile(publicKeyFile); } catch (IOException e) { LOGGER.error("file is invalid: " + publicCertsFile + System.lineSeparator(), e); - throw new InvalidParamsException("Invalid file: " + publicCertsFile); + throw new InvalidParamsException(SignToolErrMsg.PARAM_CHECK_FAILED + .toString(ParamConstants.PARAM_LOCAL_PUBLIC_CERT, "Invalid file: " + publicCertsFile)); } } @Override - public void checkParams(Options options) throws InvalidParamsException, MissingParamsException { + public void checkParams(Options options) throws InvalidParamsException { super.checkParams(options); String[] paramFileds = { ParamConstants.PARAM_LOCAL_JKS_KEYSTORE, diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/RemoteSignProvider.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/RemoteSignProvider.java index 061d046b002e9e0abd03314efcdaa860724865c2..aedd955b053ba7368ba9d79c015910dec708e3cc 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/RemoteSignProvider.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/RemoteSignProvider.java @@ -17,7 +17,6 @@ package com.ohos.hapsigntool.hap.provider; import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.error.InvalidParamsException; -import com.ohos.hapsigntool.error.MissingParamsException; import java.security.cert.X509Certificate; @@ -28,7 +27,7 @@ import java.security.cert.X509Certificate; */ public class RemoteSignProvider extends SignProvider { @Override - public void checkParams(Options options) throws MissingParamsException, InvalidParamsException { + public void checkParams(Options options) throws InvalidParamsException { super.checkParams(options); // add remote params check here } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java index 2193f385f2908a5763aced3653de1b52ed220e97..8c779e764882e2611261c6eaac3a3233b6f476c7 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java @@ -27,11 +27,11 @@ import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException; import com.ohos.hapsigntool.codesigning.sign.CodeSigning; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.hap.config.SignerConfig; import com.ohos.hapsigntool.hap.entity.SigningBlock; import com.ohos.hapsigntool.error.HapFormatException; import com.ohos.hapsigntool.error.InvalidParamsException; -import com.ohos.hapsigntool.error.MissingParamsException; import com.ohos.hapsigntool.error.ProfileException; import com.ohos.hapsigntool.error.SignatureException; import com.ohos.hapsigntool.error.VerifyCertificateChainException; @@ -73,7 +73,6 @@ import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.StandardCopyOption; -import java.security.InvalidKeyException; import java.security.Security; import java.security.cert.CertificateException; import java.security.cert.X509CRL; @@ -151,7 +150,8 @@ public abstract class SignProvider { } if (!checkFile(file)) { LOGGER.error("check file failed"); - throw new InvalidParamsException("Invalid file: " + file + ", filetype: " + type); + throw new InvalidParamsException(SignToolErrMsg.PARAM_CHECK_FAILED + .toString(file, "Invalid file: " + file + ", filetype: " + type)); } try { byte[] optionalBlockBytes = HapUtils.readFileToByte(file); @@ -161,8 +161,7 @@ public abstract class SignProvider { } optionalBlocks.add(new SigningBlock(type, optionalBlockBytes)); } catch (IOException e) { - LOGGER.error("read file error", e); - throw new InvalidParamsException("Invalid file: " + file + " is not readable. filetype: " + type); + throw new InvalidParamsException(SignToolErrMsg.FILE_READ_FAILED.toString(file)); } } @@ -218,10 +217,9 @@ public abstract class SignProvider { * @param crl certificate revocation list * @param options options * @return Object of SignerConfig - * @throws InvalidKeyException on error when the key is invalid. */ - public SignerConfig createSignerConfigs(List certificates, Optional crl, Options options) - throws InvalidKeyException { + public SignerConfig createSignerConfigs(List certificates, + Optional crl, Options options) { SignerConfig signerConfig = new SignerConfig(); signerConfig.setParameters(this.signParams); signerConfig.setCertificates(certificates); @@ -255,7 +253,7 @@ public abstract class SignProvider { // Create signer configs, which contains public cert and crl info. signerConfig = createSignerConfigs(publicCert, crl, options); - } catch (InvalidKeyException | InvalidParamsException | MissingParamsException | ProfileException e) { + } catch (InvalidParamsException | ProfileException e) { LOGGER.error("create signer configs failed.", e); printErrorLogWithoutStack(e); return false; @@ -263,7 +261,7 @@ public abstract class SignProvider { /* 6. make signed file into output file. */ if (!SignBin.sign(signerConfig, signParams)) { - LOGGER.error("hap-sign-tool: error: Sign bin internal failed."); + LOGGER.error("Sign bin internal failed."); return false; } LOGGER.info("Sign success"); @@ -287,7 +285,7 @@ public abstract class SignProvider { // Create signer configs, which contains public cert and crl info. signerConfig = createSignerConfigs(publicCert, crl, options); - } catch (InvalidKeyException | InvalidParamsException | MissingParamsException | ProfileException e) { + } catch (InvalidParamsException | ProfileException e) { LOGGER.error("create signer configs failed.", e); printErrorLogWithoutStack(e); return false; @@ -295,7 +293,7 @@ public abstract class SignProvider { if (ParamConstants.ProfileSignFlag.DISABLE_SIGN_CODE.getSignFlag().equals( signParams.get(ParamConstants.PARAM_BASIC_PROFILE_SIGNED))) { - LOGGER.error("hap-sign-tool: error: Sign elf can not use unsigned profile."); + LOGGER.error("Sign elf can not use unsigned profile."); return false; } @@ -304,7 +302,7 @@ public abstract class SignProvider { } /* 6. make signed file into output file. */ if (!SignElf.sign(signerConfig, signParams)) { - LOGGER.error("hap-sign-tool: error: Sign elf internal failed."); + LOGGER.error("Sign elf internal failed."); return false; } LOGGER.info("Sign success"); @@ -360,10 +358,11 @@ public abstract class SignProvider { outputSignedFile(outputHap, centralDirectoryOffset, signingBlock, centralDirectory, eocdBuffer); isRet = true; } - } catch (FsVerityDigestException | InvalidKeyException | HapFormatException | MissingParamsException - | InvalidParamsException | ProfileException | NumberFormatException | CustomException | IOException - | CodeSignException | ElfFormatException e) { + } catch (FsVerityDigestException | HapFormatException | InvalidParamsException | ProfileException + | CustomException | CodeSignException | ElfFormatException e) { printErrorLogWithoutStack(e); + } catch (IOException e) { + LOGGER.error(SignToolErrMsg.FILE_IO_FAILED.toString(e.getMessage())); } catch (SignatureException e) { printErrorLog(e); } @@ -419,7 +418,8 @@ public abstract class SignProvider { private String getFileSuffix(File output) throws HapFormatException { String[] fileNameArray = output.getName().split("\\."); if (fileNameArray.length < ParamConstants.FILE_NAME_MIN_LENGTH) { - throw new HapFormatException("hap format error :" + output); + throw new HapFormatException(SignToolErrMsg.ZIP_FORMAT_FAILED + .toString("suffix format error" + output)); } return fileNameArray[fileNameArray.length - 1]; } @@ -429,12 +429,10 @@ public abstract class SignProvider { * * @param options parameters used to sign hap file * @return list of type x509certificate - * @throws MissingParamsException Exception occurs when the required parameters are not entered. * @throws InvalidParamsException Exception occurs when the required parameters are invalid. * @throws ProfileException Exception occurs when profile is invalid. */ - private List getX509Certificates(Options options) throws MissingParamsException, - InvalidParamsException, ProfileException { + private List getX509Certificates(Options options) throws InvalidParamsException, ProfileException { List publicCerts; // 1. check the parameters checkParams(options); @@ -479,13 +477,13 @@ public abstract class SignProvider { private void printErrorLog(Exception exception) { if (exception != null) { - LOGGER.error("hap-sign-tool: error: {}", exception.getMessage(), exception); + LOGGER.error(exception.getMessage(), exception); } } private void printErrorLogWithoutStack(Exception exception) { if (exception != null) { - LOGGER.error("hap-sign-tool: error: {}", exception.getMessage()); + LOGGER.error(exception.getMessage()); } } @@ -534,7 +532,8 @@ public abstract class SignProvider { } } LOGGER.error("Unsupported signature algorithm :" + signAlg); - throw new InvalidParamsException("Invalid parameter: Sign Alg"); + throw new InvalidParamsException(SignToolErrMsg.PARAM_CHECK_FAILED + .toString(ParamConstants.PARAM_BASIC_SIGANTURE_ALG, "Invalid parameter: Sign Alg")); } /** @@ -578,7 +577,8 @@ public abstract class SignProvider { X500Name name = new X500Name(nameStr); RDN[] commonName = name.getRDNs(BCStyle.CN); if (commonName.length <= 0) { - CustomException.throwException(ERROR.CERTIFICATE_ERROR, "subject without common name"); + CustomException.throwException(ERROR.CERTIFICATE_ERROR, SignToolErrMsg.CERTIFICATE_ERROR + .toString("subject without common name")); } return commonName[0].getFirst().getValue().toString(); } @@ -609,11 +609,12 @@ public abstract class SignProvider { CMSSignedData cmsSignedData = new CMSSignedData(profile); boolean isVerify = VerifyUtils.verifyCmsSignedData(cmsSignedData); if (!isVerify) { - throw new ProfileException("Verify profile pkcs7 failed! Profile is invalid."); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_INVALID.toString()); } Object contentObj = cmsSignedData.getSignedContent().getContent(); if (!(contentObj instanceof byte[])) { - throw new ProfileException("Check profile failed, signed profile content is not byte array!"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString("Check profile failed, signed profile content is not byte array!")); } profileContent = new String((byte[]) contentObj, StandardCharsets.UTF_8); } else { @@ -623,9 +624,10 @@ public abstract class SignProvider { JsonObject profileJson = parser.getAsJsonObject(); checkProfileInfo(profileJson, inputCerts); } catch (CMSException e) { - throw new ProfileException("Verify profile pkcs7 failed! Profile is invalid.", e); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_INVALID.toString()); } catch (JsonParseException e) { - throw new ProfileException("Invalid parameter: profile content is not a JSON.", e); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString("Invalid parameter: profile content is not a JSON.", e)); } } @@ -633,7 +635,7 @@ public abstract class SignProvider { String profileTypeKey = "type"; String profileType = profileJson.get(profileTypeKey).getAsString(); if (profileType == null || profileType.length() == 0) { - throw new ProfileException("Get profile type error!"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED.toString("Get profile type error!")); } String buildInfoMember = "bundle-info"; JsonObject buildInfoObject = profileJson.getAsJsonObject(buildInfoMember); @@ -643,15 +645,16 @@ public abstract class SignProvider { } else if (profileType.equalsIgnoreCase("debug")) { certInProfile = getDevelopmentCertificate(buildInfoObject); } else { - throw new ProfileException("Unsupported profile type!"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED.toString("Unsupported profile type!")); } if (!inputCerts.isEmpty() && !checkInputCertMatchWithProfile(inputCerts.get(0), certInProfile)) { - throw new ProfileException("input certificates do not match with profile!"); + throw new ProfileException(SignToolErrMsg.PROFILE_CERT_MATCH_FAILED.toString()); } String cn = getCertificateCN(certInProfile); LOGGER.info("certificate in profile: {}", cn); if (cn.isEmpty()) { - throw new ProfileException("Common name of certificate is empty!"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString("Common name of certificate is empty!")); } } @@ -670,10 +673,9 @@ public abstract class SignProvider { * Check input parameters is valid. And put valid parameters into signParams. * * @param options parameters inputted by user. - * @throws MissingParamsException Exception occurs when the required parameters are not entered. * @throws InvalidParamsException Exception occurs when the required parameters are invalid. */ - public void checkParams(Options options) throws MissingParamsException, InvalidParamsException { + public void checkParams(Options options) throws InvalidParamsException { String[] paramFileds = { ParamConstants.PARAM_BASIC_ALIGNMENT, ParamConstants.PARAM_BASIC_SIGANTURE_ALG, @@ -722,7 +724,8 @@ public abstract class SignProvider { String codeSign = signParams.get(ParamConstants.PARAM_SIGN_CODE); if (!codeSign.equals(ParamConstants.SignCodeFlag.ENABLE_SIGN_CODE.getSignCodeFlag()) && !codeSign.equals(ParamConstants.SignCodeFlag.DISABLE_SIGN_CODE.getSignCodeFlag())) { - throw new InvalidParamsException("Invalid parameter: " + ParamConstants.PARAM_SIGN_CODE); + throw new InvalidParamsException(SignToolErrMsg.PARAM_CHECK_FAILED + .toString(ParamConstants.PARAM_SIGN_CODE, "Invalid parameter")); } } @@ -730,9 +733,8 @@ public abstract class SignProvider { * Check compatible version, if param do not have compatible version default 9. * * @throws InvalidParamsException invalid param - * @throws MissingParamsException missing param */ - protected void checkCompatibleVersion() throws InvalidParamsException, MissingParamsException { + protected void checkCompatibleVersion() throws InvalidParamsException { if (!signParams.containsKey(ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION)) { signParams.put(ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION, "9"); return; @@ -741,7 +743,8 @@ public abstract class SignProvider { try { int compatibleApiVersion = Integer.parseInt(compatibleApiVersionVal); } catch (NumberFormatException e) { - throw new InvalidParamsException("Invalid parameter: " + ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION); + throw new InvalidParamsException(SignToolErrMsg.PARAM_CHECK_FAILED + .toString(ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION, "Invalid parameter")); } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java index f4ec846a301b64f7a8ee132198ccd1c4f42d80f2..93ca6e9bc15fc11ba3738cdf986f81a41e44a638 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java @@ -21,15 +21,11 @@ import com.ohos.hapsigntool.entity.SignatureAlgorithm; import com.ohos.hapsigntool.hap.config.SignerConfig; import com.ohos.hapsigntool.entity.Pair; import com.ohos.hapsigntool.hap.entity.SigningBlock; -import com.ohos.hapsigntool.error.HapFormatException; import com.ohos.hapsigntool.error.SignatureException; -import com.ohos.hapsigntool.utils.FileUtils; import com.ohos.hapsigntool.hap.utils.HapUtils; -import com.ohos.hapsigntool.utils.StringUtils; import com.ohos.hapsigntool.zip.ZipDataInput; import java.io.IOException; -import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.DigestException; @@ -39,10 +35,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; -import java.util.stream.Collectors; /** * @@ -51,205 +43,15 @@ import java.util.stream.Collectors; * @since 2021/12/21 */ public abstract class SignHap { - private static final int STORED_ENTRY_SO_ALIGNMENT = 4096; - private static final int BUFFER_LENGTH = 4096; private static final int BLOCK_COUNT = 4; private static final int BLOCK_MAGIC = 16; private static final int BLOCK_VERSION = 4; - private static final long INIT_OFFSET_LEN = 4L; private static final int OPTIONAL_TYPE_SIZE = 4; private static final int OPTIONAL_LENGTH_SIZE = 4; private static final int OPTIONAL_OFFSET_SIZE = 4; private SignHap() {} - /** - * Copy the jar file and align the storage entries. - * - * @param in input hap-file which is opened as a jar-file. - * @param out output stream of jar. - * @param timestamp ZIP file timestamps - * @param defaultAlignment default value of alignment. - * @throws IOException io error. - * @throws HapFormatException hap format error. - */ - public static void copyFiles(JarFile in, - JarOutputStream out, long timestamp, int defaultAlignment) throws IOException, HapFormatException { - // split compressed and uncompressed - List entryListStored = in.stream() - .filter(jarFile -> jarFile.getMethod() == JarEntry.STORED).collect(Collectors.toList()); - - // uncompressed special files and place in front - entryListStored = storedEntryListOfSort(entryListStored); - long offset = INIT_OFFSET_LEN; - String lastAlignmentEntryName = ""; - for (JarEntry inEntry : entryListStored) { - String entryName = inEntry.getName(); - if (!FileUtils.isRunnableFile(entryName)) { - lastAlignmentEntryName = entryName; - break; - } - } - for (JarEntry inEntry : entryListStored) { - if (inEntry == null) { - continue; - } - - offset += JarFile.LOCHDR; - - JarEntry outEntry = getJarEntry(timestamp, inEntry); - offset += outEntry.getName().length(); - - int alignment = getStoredEntryDataAlignment(inEntry.getName(), defaultAlignment, lastAlignmentEntryName); - if (alignment > 0 && (offset % alignment != 0)) { - int needed = alignment - (int) (offset % alignment); - outEntry.setExtra(new byte[needed]); - offset += needed; - } - - out.putNextEntry(outEntry); - offset = writeOutputStreamAndGetOffset(in, out, inEntry, offset); - } - List entryListNotStored = in.stream() - .filter(jarFile -> jarFile.getMethod() != JarEntry.STORED).collect(Collectors.toList()); - // process byte alignment of the first compressed file - boolean isAlignmentFlag = StringUtils.isEmpty(lastAlignmentEntryName); - if (isAlignmentFlag) { - if (entryListNotStored.isEmpty()) { - throw new HapFormatException("Hap format is error, file missing"); - } - JarEntry firstEntry = entryListNotStored.get(0); - offset += JarFile.LOCHDR; - JarEntry outEntry = getFirstJarEntry(firstEntry, offset, timestamp); - out.putNextEntry(outEntry); - byte[] buffer = new byte[BUFFER_LENGTH]; - writeOutputStream(in, out, firstEntry, buffer); - } - - copyFilesExceptStoredFile(entryListNotStored, in, out, timestamp, isAlignmentFlag); - } - - /** - * uncompressed special files are placed in front - * - * @param entryListStored stored file entry list - * @return List jarEntryList - */ - private static List storedEntryListOfSort(List entryListStored) { - return entryListStored.stream().sorted((entry1, entry2) -> { - String name1 = entry1.getName(); - String name2 = entry2.getName(); - // files ending with .abc or .so are placed before other files - boolean isSpecial1 = FileUtils.isRunnableFile(name1); - boolean isSpecial2 = FileUtils.isRunnableFile(name2); - if (isSpecial1 && !isSpecial2) { - return -1; - } else if (!isSpecial1 && isSpecial2) { - return 1; - } else { - // if all files are special files or none of them are special files,the files are sorted lexically - return name1.compareTo(name2); - } - }).collect(Collectors.toList()); - } - - private static JarEntry getFirstJarEntry(JarEntry firstEntry, long offset, long timestamp) { - long currentOffset = offset; - JarEntry outEntry = getJarEntry(timestamp, firstEntry); - currentOffset += outEntry.getName().length(); - if (currentOffset % STORED_ENTRY_SO_ALIGNMENT != 0) { - int needed = STORED_ENTRY_SO_ALIGNMENT - (int) (currentOffset % STORED_ENTRY_SO_ALIGNMENT); - outEntry.setExtra(new byte[needed]); - } - return outEntry; - } - - /** - * write first not stored entry to outputStream - * - * @param in jar file - * @param out jarOutputStream - * @param firstEntry jarEntry - * @param buffer byte[] - * @throws IOException IOExpcetion - */ - private static void writeOutputStream(JarFile in, JarOutputStream out, JarEntry firstEntry, byte[] buffer) - throws IOException { - try (InputStream data = in.getInputStream(firstEntry)) { - int num; - while ((num = data.read(buffer)) > 0) { - out.write(buffer, 0, num); - } - out.flush(); - } - } - - private static long writeOutputStreamAndGetOffset(JarFile in, JarOutputStream out, JarEntry inEntry, long offset) - throws IOException { - byte[] buffer = new byte[BUFFER_LENGTH]; - long currentOffset = offset; - try (InputStream data = in.getInputStream(inEntry)) { - int num; - while ((num = data.read(buffer)) > 0) { - out.write(buffer, 0, num); - currentOffset += num; - } - out.flush(); - } - return currentOffset; - } - - private static JarEntry getJarEntry(long timestamp, JarEntry inEntry) { - JarEntry outEntry = new JarEntry(inEntry); - outEntry.setTime(timestamp); - - outEntry.setComment(null); - outEntry.setExtra(null); - return outEntry; - } - - private static void copyFilesExceptStoredFile(List entryListNotStored, JarFile in, - JarOutputStream out, long timestamp, boolean isAlignmentFlag) throws IOException { - byte[] buffer = new byte[BUFFER_LENGTH]; - int index = 0; - if (isAlignmentFlag) { - index = 1; - } - for (; index < entryListNotStored.size(); index++) { - JarEntry inEntry = entryListNotStored.get(index); - if (inEntry == null || inEntry.getMethod() == JarEntry.STORED) { - continue; - } - - JarEntry outEntry = new JarEntry(inEntry.getName()); - outEntry.setTime(timestamp); - out.putNextEntry(outEntry); - writeOutputStream(in, out, inEntry, buffer); - } - } - - /** - * If store entry is end with '.so', use 4096-alignment, otherwise, use default-alignment. - * - * @param entryName name of entry - * @param defaultAlignment default value of alignment. - * @param lastAlignmentEntryName lastAlignmentEntryName - * @return value of alignment. - */ - private static int getStoredEntryDataAlignment(String entryName, int defaultAlignment, - String lastAlignmentEntryName) { - if (defaultAlignment <= 0) { - return 0; - } - if (!StringUtils.isEmpty(lastAlignmentEntryName) && entryName.equals(lastAlignmentEntryName)) { - return STORED_ENTRY_SO_ALIGNMENT; - } - if (FileUtils.isRunnableFile(entryName)) { - return STORED_ENTRY_SO_ALIGNMENT; - } - return defaultAlignment; - } - private static byte[] getHapSigningBlock( Set contentDigestAlgorithms, List optionalBlocks, diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java index cbcaaa2a711e915fd67913cef1b2b7eedc68ed72..5a641abd50b441cb1fed3a2be28fd5f25fa173bb 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java @@ -19,6 +19,7 @@ import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException; import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException; import com.ohos.hapsigntool.codesigning.sign.VerifyCodeSignature; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.hap.entity.ElfBlockData; import com.ohos.hapsigntool.hap.entity.BlockHead; import com.ohos.hapsigntool.hap.entity.SignHead; @@ -67,11 +68,12 @@ public class VerifyElf { try { CMSSignedData cmsSignedData = new CMSSignedData(profile); if (!VerifyUtils.verifyCmsSignedData(cmsSignedData)) { - throw new ProfileException("Verify profile pkcs7 failed! Profile is invalid"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_INVALID.toString()); } Object contentObj = cmsSignedData.getSignedContent().getContent(); if (!(contentObj instanceof byte[])) { - throw new ProfileException("Check profile failed, signed profile content is not byte array!"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString("Check profile failed, signed profile content is not byte array!")); } return new String((byte[]) contentObj, StandardCharsets.UTF_8); } catch (CMSException e) { diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java index cce11d735e97df913160ee3d672d5d70af02097a..d619d1e8a8fc46ec7ab7b8afba0a486cf0542586 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java @@ -20,6 +20,7 @@ import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException; import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException; import com.ohos.hapsigntool.codesigning.sign.VerifyCodeSignature; import com.ohos.hapsigntool.entity.Pair; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.hap.entity.SigningBlock; import com.ohos.hapsigntool.error.HapFormatException; import com.ohos.hapsigntool.error.ProfileException; @@ -89,11 +90,12 @@ public class VerifyHap { try { CMSSignedData cmsSignedData = new CMSSignedData(profile); if (!VerifyUtils.verifyCmsSignedData(cmsSignedData)) { - throw new ProfileException("Verify profile pkcs7 failed! Profile is invalid"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_INVALID.toString()); } Object contentObj = cmsSignedData.getSignedContent().getContent(); if (!(contentObj instanceof byte[])) { - throw new ProfileException("Check profile failed, signed profile content is not byte array!"); + throw new ProfileException(SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString("Check profile failed, signed profile content is not byte array!")); } return new String((byte[]) contentObj, StandardCharsets.UTF_8); } catch (CMSException e) { diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java index a9b28a5a3a959e60b7e2ad25310f9f1d82fa3af6..c2969cc945fbbcfb0e88e0a63ce35ebec144252f 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.profile; import com.ohos.hapsigntool.adapter.LocalizationAdapter; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyException; import com.ohos.hapsigntool.profile.model.VerificationResult; import com.ohos.hapsigntool.signer.ISigner; @@ -93,10 +94,11 @@ public final class ProfileSignTool { try { verificationResult = verifyHelper.verify(p7b); } catch (VerifyException e) { - CustomException.throwException(ERROR.VERIFY_ERROR, "Generate Profile Failed! " + e.getMessage()); + CustomException.throwException(ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_PROFILE_FAILED + .toString("Generate Profile Failed! " + e.getMessage())); } - ValidateUtils.throwIfNotMatches(verificationResult.isVerifiedPassed(), ERROR.SIGN_ERROR, - verificationResult.getMessage()); + ValidateUtils.throwIfNotMatches(verificationResult.isVerifiedPassed(), + ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED.toString(verificationResult.getMessage())); return p7b; } @@ -135,7 +137,7 @@ public final class ProfileSignTool { return contentInfo.getEncoded("DER"); } catch (OperatorCreationException | IOException | CertificateEncodingException | CRLException e) { LOGGER.debug(e.getMessage(), e); - CustomException.throwException(ERROR.SIGN_ERROR, e.getMessage()); + CustomException.throwException(ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED.toString(e.getMessage())); } return NO_BYTE; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java index 19efcc7a6abf9d1b564db8bd3b89816ad9ca1172..f7b7f75ae609ff8e05e7335e6d1965f5700997be 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.profile; import com.google.gson.JsonObject; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyException; import com.ohos.hapsigntool.hap.verify.VerifyUtils; import com.ohos.hapsigntool.profile.model.VerificationResult; @@ -87,10 +88,12 @@ public class VerifyHelper implements IProvisionVerifier { Signature signature = Signature.getInstance(algorithm); signature.initVerify(cert); signature.update(unsignedData); - ValidateUtils.throwIfNotMatches(signature.verify(signedData), ERROR.SIGN_ERROR, "Signature not matched!"); + ValidateUtils.throwIfNotMatches(signature.verify(signedData), ERROR.SIGN_ERROR, + SignToolErrMsg.SIGNATURE_NOT_MATCHED.toString()); } catch (InvalidKeyException | SignatureException | NoSuchAlgorithmException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.SIGN_ERROR, "Failed to verify signature: " + exception.getMessage()); + CustomException.throwException(ERROR.SIGN_ERROR, SignToolErrMsg.VERIFY_FAILED + .toString(exception.getMessage())); } } @@ -103,10 +106,11 @@ public class VerifyHelper implements IProvisionVerifier { public static List certStoreToCertList(Store certificates) { String errorMsg = "Verify failed, not found cert chain"; JcaX509CertificateConverter converter = new JcaX509CertificateConverter(); - ValidateUtils.throwIfMatches(certificates == null, ERROR.VERIFY_ERROR, errorMsg); + ValidateUtils.throwIfMatches(certificates == null, ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED + .toString(errorMsg)); Collection matches = certificates.getMatches(null); ValidateUtils.throwIfMatches(matches == null || !matches.iterator().hasNext(), - ERROR.VERIFY_ERROR, errorMsg); + ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED.toString(errorMsg)); Iterator iterator = matches.iterator(); List certificateList = new ArrayList<>(); @@ -117,9 +121,10 @@ public class VerifyHelper implements IProvisionVerifier { } } catch (CertificateException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.VERIFY_ERROR, errorMsg); + CustomException.throwException(ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED.toString(errorMsg)); } - ValidateUtils.throwIfMatches(certificateList.size() == 0, ERROR.VERIFY_ERROR, errorMsg); + ValidateUtils.throwIfMatches(certificateList.size() == 0, + ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED.toString(errorMsg)); return certificateList; } @@ -192,12 +197,12 @@ public class VerifyHelper implements IProvisionVerifier { cmsSignedData = new CMSSignedData(p7b); boolean verifyResult = VerifyUtils.verifyCmsSignedData(cmsSignedData); ValidateUtils.throwIfNotMatches(verifyResult, ERROR.VERIFY_ERROR, - "Failed to verify BC signatures"); + SignToolErrMsg.VERIFY_FAILED.toString("Failed to verify BC signatures")); return cmsSignedData; } catch (CMSException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.VERIFY_ERROR, "Failed to verify BC signatures: " - + exception.getMessage()); + CustomException.throwException(ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED + .toString("Failed to verify BC signatures" + exception.getMessage())); } return cmsSignedData; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/BundleInfo.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/BundleInfo.java index dcf012da5526de87f5af548701ec4ac026fc8c54..5cacb121667555070927edb52a19ad0fcd489280 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/BundleInfo.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/BundleInfo.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.profile.model; import com.google.gson.annotations.SerializedName; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.ValidateUtils; /** @@ -122,10 +123,10 @@ public class BundleInfo { public void enforceValid(String buildType) { if (Provision.isBuildTypeRelease(buildType)) { ValidateUtils.throwIfMatches(this.distributionCertificate == null, - ERROR.SIGN_ERROR, "Require cert in bundleInfo!"); + ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED.toString("Require cert in bundleInfo!")); } else { ValidateUtils.throwIfMatches(this.developmentCertificate == null, - ERROR.SIGN_ERROR, "Require cert in bundleInfo!"); + ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED.toString("Require cert in bundleInfo!")); } } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/DebugInfo.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/DebugInfo.java index 9fcd714c62f3116c617e24b14f07d37223e45eb6..b2b8563eb7f979f25093293559a9f417a65b6c26 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/DebugInfo.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/DebugInfo.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.profile.model; import com.google.gson.annotations.SerializedName; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.ValidateUtils; import java.util.List; @@ -73,9 +74,9 @@ public class DebugInfo { public void enforceValid() { if (this.deviceIds != null) { ValidateUtils.throwIfMatches(this.deviceIds.size() > MAX_DEBUG_DEVICE_NUM, ERROR.SIGN_ERROR, - "Support at most: 100 devices!"); - ValidateUtils.throwIfMatches(!this.isDeviceIdTypeValid(), ERROR.SIGN_ERROR, - "Device id type must be sn or udid, current is " + this.deviceIdType); + SignToolErrMsg.SIGNATURE_FAILED.toString("Support at most: 100 devices!")); + ValidateUtils.throwIfMatches(!this.isDeviceIdTypeValid(), ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED + .toString("Device id type must be sn or udid, current is " + this.deviceIdType)); } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Provision.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Provision.java index 50c19b5ea5227de44c6e81a426edf5231704f0e3..14a09d786d8b574eef6b86d8f37c3d356f299ec5 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Provision.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Provision.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.profile.model; import com.google.gson.annotations.SerializedName; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.ValidateUtils; /** @@ -195,10 +196,11 @@ public class Provision { */ public static void enforceValid(Provision provision) { ValidateUtils.throwIfMatches(provision.type == null || !isBuildTypeValid(provision.type), - ERROR.SIGN_ERROR, "Require build type must be debug or release, current is :" + provision.type); + ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED + .toString("Require build type must be debug or release, current is :" + provision.type)); ValidateUtils.throwIfMatches(provision.bundleInfo == null, ERROR.SIGN_ERROR, - "Require bundleInfo in provision!"); + SignToolErrMsg.SIGNATURE_FAILED.toString("Require bundleInfo in provision!")); provision.bundleInfo.enforceValid(provision.type); } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Validity.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Validity.java index 021519730510fb883149a8fb4de862ba2593a736..bcca56fbdfc1193ec24a5ed7c53caee0455c0394 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Validity.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/model/Validity.java @@ -16,8 +16,6 @@ package com.ohos.hapsigntool.profile.model; import com.google.gson.annotations.SerializedName; -import com.ohos.hapsigntool.error.ERROR; -import com.ohos.hapsigntool.utils.ValidateUtils; /** * Sub dto of Provision. @@ -42,16 +40,6 @@ public class Validity { */ public Validity() {} - /** - * Validate attribute. - */ - public void enforceValid() { - ValidateUtils.throwIfMatches(this.notBefore == 0L, ERROR.SIGN_ERROR, "Require notBefore in validity!"); - ValidateUtils.throwIfMatches(this.notAfter == 0L, ERROR.SIGN_ERROR, "Require notAfter in validity!"); - ValidateUtils.throwIfMatches(this.notBefore >= this.notAfter, ERROR.SIGN_ERROR, - "Require notBefore less than notAfter in validity!"); - } - public Long getNotBefore() { return notBefore; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/LocalSigner.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/LocalSigner.java index cccb93812e19b440fe205d7a7db0ce750c6af25d..03940b9d08a6c99cf7814e46fbafb4b098e81827 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/LocalSigner.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/LocalSigner.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.signer; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.LogUtils; import java.security.InvalidAlgorithmParameterException; @@ -85,7 +86,8 @@ public class LocalSigner implements ISigner { } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | SignatureException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.SIGN_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.SIGN_ERROR, SignToolErrMsg.SIGNATURE_FAILED + .toString(exception.getMessage())); } return signData; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/SignerFactory.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/SignerFactory.java index bd62263d84c4aa99b13d1b58a2d43247436540f6..a69e116fdf6256fecbc055f8ac9ebef80aeaf165 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/SignerFactory.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/signer/SignerFactory.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.signer; import com.ohos.hapsigntool.adapter.LocalizationAdapter; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.utils.LogUtils; import com.ohos.hapsigntool.utils.StringUtils; @@ -132,7 +133,8 @@ public class SignerFactory { private File getClassLocation() { String jarPath = SignerFactory.class.getProtectionDomain().getCodeSource().getLocation().getFile(); if (StringUtils.isEmpty(jarPath)) { - CustomException.throwException(ERROR.COMMAND_ERROR, "class path is empty"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.LOAD_REMOTE_PLUGIN_FAILED + .toString("Class path is empty")); } try { jarPath = URLDecoder.decode(URLEncoder.encode(jarPath, "utf-8"), "utf-8"); @@ -141,7 +143,8 @@ public class SignerFactory { } File jarFile = new File(jarPath); if (!jarFile.exists()) { - CustomException.throwException(ERROR.COMMAND_ERROR, "class path" + jarFile + "is not exists"); + CustomException.throwException(ERROR.COMMAND_ERROR, SignToolErrMsg.LOAD_REMOTE_PLUGIN_FAILED + .toString("class path" + jarFile + "is not exists")); } if (jarFile.isFile()) { return jarFile.getParentFile(); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java index fe8e8ece4affbc36768599a8c57f677f6c6991d9..24a349531f5d73b64e65e83ad35fe372b51cbea0 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.utils; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyException; import javax.security.auth.x500.X500Principal; @@ -102,14 +103,16 @@ public class CertChainUtils { CertPathValidator validator = CertPathValidator.getInstance("PKIX"); CertPathValidatorResult validatorResult = validator.validate(certPath, params); ValidateUtils.throwIfNotMatches(validatorResult instanceof PKIXCertPathValidatorResult, - ERROR.VERIFY_ERROR, "Validator result not target type"); + ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED.toString("Validator result not target type")); if (validatorResult instanceof PKIXCertPathValidatorResult) { PKIXCertPathValidatorResult pkixValidatorResult = (PKIXCertPathValidatorResult) validatorResult; ValidateUtils.throwIfNotMatches(params.getTrustAnchors().contains(pkixValidatorResult.getTrustAnchor()), - ERROR.VERIFY_ERROR, "Anchor is not trusted: " + Base64.getEncoder().encodeToString( - pkixValidatorResult.getTrustAnchor().getTrustedCert().getEncoded())); + ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED.toString( + "Anchor is not trusted: " + Base64.getEncoder().encodeToString( + pkixValidatorResult.getTrustAnchor().getTrustedCert().getEncoded()))); } else { - CustomException.throwException(ERROR.VERIFY_ERROR, "Validator result not target type"); + CustomException.throwException(ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED + .toString("Validator result not target type")); } } catch (IOException | GeneralSecurityException exception) { throw new VerifyException("Cert chain verify failed! " + exception.getMessage()); diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertUtils.java index 83410b1c33f2a27e6574509fab2cd175316e33a0..426dba33ae7dbc7b016631fa7880953c32f7a6dc 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertUtils.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.utils; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyCertificateChainException; import org.bouncycastle.asn1.x500.X500Name; @@ -180,7 +181,7 @@ public final class CertUtils { * @param nameString subject or issuer */ private static void checkDN(String nameString) { - String errorMsg = String.format("Format error, must be \"X=xx,XX=xxx,...\", please check: \"%s\"", nameString); + String errorMsg = SignToolErrMsg.CERT_DN_FORMAT_FAILED.toString(nameString); ValidateUtils.throwIfNotMatches(!StringUtils.isEmpty(nameString), ERROR.COMMAND_ERROR, errorMsg); String[] pairs = nameString.split(","); for (String pair : pairs) { @@ -277,7 +278,8 @@ public final class CertUtils { */ public static ContentSigner createFixedContentSigner(PrivateKey privateKey, String signAlgorithm) { Matcher matcher = SIGN_ALGORITHM_PATTERN.matcher(signAlgorithm); - ValidateUtils.throwIfNotMatches(matcher.matches(), ERROR.NOT_SUPPORT_ERROR, "Not Support " + signAlgorithm); + ValidateUtils.throwIfNotMatches(matcher.matches(), ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.ALGORITHM_NOT_SUPPORT + .toString("Not Support " + signAlgorithm)); String signAlg = signAlgorithm; // Auto fix signAlgorithm error if (privateKey instanceof ECPrivateKey && signAlgorithm.contains("RSA")) { @@ -294,7 +296,8 @@ public final class CertUtils { return jcaContentSignerBuilder.build(privateKey); } catch (OperatorCreationException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.OPERATOR_CREATION_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.OPERATOR_CREATION_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); } return null; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java index ef0d98cb1ac94db474869799eb1435f7c714ba40..9a2c6a4bd72f8b6e4b655614c2a6eef958e29948 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java @@ -19,6 +19,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; @@ -213,8 +214,8 @@ public final class FileUtils { */ public static void write(byte[] content, File output) throws IOException { if (output.exists() && !output.canWrite()) { - CustomException.throwException(ERROR.WRITE_FILE_ERROR, "No permission to write file " + - output.getCanonicalPath()); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.FILE_WRITE_FAILED + .toString("No permission write to file " + output)); } try (FileOutputStream out = new FileOutputStream(output)) { for (byte con : content) { @@ -265,7 +266,7 @@ public final class FileUtils { public static void validFileType(String filePath, String... types) { String suffix = getSuffix(filePath); ValidateUtils.throwIfNotMatches(!StringUtils.isEmpty(suffix), - ERROR.NOT_SUPPORT_ERROR, "Not support file: " + filePath); + ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.NOT_SUPPORT_FILE.toString(filePath)); boolean isMatches = false; for (String type : types) { if (StringUtils.isEmpty(type)) { @@ -276,7 +277,8 @@ public final class FileUtils { break; } } - ValidateUtils.throwIfNotMatches(isMatches, ERROR.NOT_SUPPORT_ERROR, "Not support file: " + filePath); + ValidateUtils.throwIfNotMatches(isMatches, + ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.NOT_SUPPORT_FILE.toString(filePath)); } /** diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyPairTools.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyPairTools.java index 7b84b73fe0f114dbd10a8bccb318ba5fc1e44a6e..ea8e2c453aad9e7f4660dba3266610e4cb00f561 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyPairTools.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyPairTools.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.utils; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import org.bouncycastle.util.encoders.Base64; import java.security.Key; @@ -93,7 +94,8 @@ public final class KeyPairTools { */ public static KeyPair generateKeyPair(String algorithm, int keySize) { if (algorithm == null) { - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "Not support algorithm: null"); + CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.ALGORITHM_NOT_SUPPORT + .toString("Not support algorithm: null")); } String alg = algorithm; if (ECC_INPUT.equalsIgnoreCase(alg)) { @@ -101,12 +103,15 @@ public final class KeyPairTools { } if (RSA.equalsIgnoreCase(alg)) { ValidateUtils.throwIfNotMatches((keySize == RSA_2048 || keySize == RSA_3072 || keySize == RSA_4096), - ERROR.NOT_SUPPORT_ERROR, "Algorithm 'RSA' not support size: " + keySize); + ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.ALGORITHM_NOT_SUPPORT + .toString("Algorithm 'RSA' not support size: " + keySize)); } else if (ECC.equalsIgnoreCase(alg)) { ValidateUtils.throwIfNotMatches((keySize == NIST_P_256 || keySize == NIST_P_384), - ERROR.NOT_SUPPORT_ERROR, "Algorithm 'ECC' not support size: " + keySize); + ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.ALGORITHM_NOT_SUPPORT + .toString("Algorithm 'ECC' not support size: " + keySize)); } else { - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "Not support algorithm: " + alg); + CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.ALGORITHM_NOT_SUPPORT + .toString("Not support algorithm: " + alg)); } try { @@ -115,7 +120,8 @@ public final class KeyPairTools { return keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { LOGGER.debug(e.getMessage(), e); - CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, e.getMessage()); + CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(e.getMessage())); return null; } } @@ -144,7 +150,8 @@ public final class KeyPairTools { result = KeyFactory.getInstance(algorithm).generatePublic(spec); } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(exception.getMessage())); } return result; } @@ -163,7 +170,8 @@ public final class KeyPairTools { result = KeyFactory.getInstance(algorithm).generatePrivate(spec); } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(exception.getMessage())); } return result; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyStoreHelper.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyStoreHelper.java index 16e6b3d3457d2af51236291eeec95e4c387b5b9c..3d4f057198e9a7d8734b84c587c8db8cd8e82e65 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyStoreHelper.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/KeyStoreHelper.java @@ -18,6 +18,7 @@ package com.ohos.hapsigntool.utils; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.cert.X509v3CertificateBuilder; @@ -105,8 +106,8 @@ public class KeyStoreHelper { */ public KeyStoreHelper(String keyStorePath, char[] storePwd) { char[] pwd = storePwd; - ValidateUtils.throwIfMatches(StringUtils.isEmpty(keyStorePath), ERROR.COMMAND_ERROR, - "Missed params: 'keyStorePath'"); + ValidateUtils.throwIfMatches(StringUtils.isEmpty(keyStorePath), + ERROR.COMMAND_ERROR, SignToolErrMsg.MISSING_PARAM.toString("keyStorePath")); if (pwd == null) { pwd = new char[0]; } @@ -124,11 +125,8 @@ public class KeyStoreHelper { } } catch (IOException | NoSuchAlgorithmException | CertificateException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, "Init keystore failed: " + exception.getMessage() - + "\nSolutions:" - + "\n> The key store file does not exist, please check the key store file path." - + "\n> Incorrect keystore password, please input the correct plaintext password." - + "\n> The keystore was created by a newer JDK version, please use the same JDK version"); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.INIT_KEYSTORE_FAILED + .toString(exception.getMessage())); } finally { FileUtils.close(fis); } @@ -144,8 +142,8 @@ public class KeyStoreHelper { * @param alias alias of key */ public void errorOnExist(String alias) { - ValidateUtils.throwIfMatches(this.hasAlias(alias), ERROR.ACCESS_ERROR, - String.format("Could not overwrite! Already exist '%s' in %s", alias, this.keyStorePath)); + ValidateUtils.throwIfMatches(this.hasAlias(alias), + ERROR.ACCESS_ERROR, SignToolErrMsg.KEY_ALIAS_EXIST.toString(alias, this.keyStorePath)); } /** @@ -154,8 +152,8 @@ public class KeyStoreHelper { * @param alias alias of key */ public void errorIfNotExist(String alias) { - ValidateUtils.throwIfNotMatches(this.hasAlias(alias), ERROR.FILE_NOT_FOUND, - String.format("Not exist '%s' in %s", alias, this.keyStorePath)); + ValidateUtils.throwIfNotMatches(this.hasAlias(alias), + ERROR.FILE_NOT_FOUND, SignToolErrMsg.KEY_ALIAS_NOT_FOUND.toString(alias, this.keyStorePath)); } /** @@ -169,7 +167,8 @@ public class KeyStoreHelper { return keyStore.containsAlias(alias); } catch (KeyStoreException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.KEYSTORE_ERROR + .toString(exception.getMessage())); return false; } } @@ -206,10 +205,12 @@ public class KeyStoreHelper { } } catch (KeyStoreException | NoSuchAlgorithmException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.NO_SUCH_SIGNATURE + .toString(exception.getMessage())); } catch (UnrecoverableKeyException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.ACCESS_ERROR, "Password error of '" + alias + "'"); + CustomException.throwException(ERROR.ACCESS_ERROR, SignToolErrMsg.KEY_PASSWORD_ERROR + .toString(alias, exception)); } return null; } @@ -240,8 +241,8 @@ public class KeyStoreHelper { * @return certificates of alias */ public List loadCertificates(String alias) { - ValidateUtils.throwIfNotMatches(this.hasAlias(alias), ERROR.FILE_NOT_FOUND, - String.format("Not found '%s' in %s", alias, this.keyStorePath)); + ValidateUtils.throwIfNotMatches(this.hasAlias(alias), + ERROR.FILE_NOT_FOUND, SignToolErrMsg.KEY_ALIAS_NOT_FOUND.toString(alias, this.keyStorePath)); List certificates = new ArrayList<>(); try { @@ -258,11 +259,12 @@ public class KeyStoreHelper { } } catch (KeyStoreException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.KEYSTORE_OPERATION_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.KEYSTORE_OPERATION_ERROR, SignToolErrMsg.KEYSTORE_ERROR + .toString(exception.getMessage())); } - ValidateUtils.throwIfNotMatches(certificates.size() > 0, ERROR.ACCESS_ERROR, - "No usable cert found in " + this.keyStorePath); + ValidateUtils.throwIfNotMatches(!certificates.isEmpty(), ERROR.ACCESS_ERROR, SignToolErrMsg.NO_USABLE_CERT + .toString(this.keyStorePath)); return certificates; } @@ -293,7 +295,8 @@ public class KeyStoreHelper { fos.flush(); } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.WRITE_FILE_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.WRITE_FILE_ERROR, SignToolErrMsg.FILE_WRITE_FAILED + .toString(exception.getMessage())); return false; } return true; @@ -320,7 +323,8 @@ public class KeyStoreHelper { .getCertificate(certificateBuilder.build(contentSigner)); } catch (CertificateException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.IO_CERT_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.IO_CERT_ERROR, SignToolErrMsg.CERT_IO_FAILED + .toString(exception.getMessage())); return null; } } @@ -344,7 +348,8 @@ public class KeyStoreHelper { } } catch (KeyStoreException exception) { LOGGER.debug(exception.getMessage(), exception); - CustomException.throwException(ERROR.KEYSTORE_OPERATION_ERROR, exception.getMessage()); + CustomException.throwException(ERROR.KEYSTORE_OPERATION_ERROR, SignToolErrMsg.KEYSTORE_ERROR + .toString(exception.getMessage())); } return typeKeyStore; } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/LogUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/LogUtils.java index 825038ad8cb1dcaffad00bc9d15ed988efb71ef7..f02b06cbc02974c4c94848e02adfe4dfe1cd0412 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/LogUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/LogUtils.java @@ -191,7 +191,7 @@ public class LogUtils { * @param arg2 arg */ public void debug(String log, Object arg1, Object arg2) { - logger.warning(" WARN - " + replaceArgs(log, arg1, arg2)); + logger.config(" DEBUG - " + replaceArgs(log, arg1, arg2)); OUT_HANDLER.flush(); } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java index de8a21638847271a5c5e3eccf432c39de1f7663b..99a865353bf80a63b3cf14486cfe4b1457aab976 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.zip; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.ZipException; import com.ohos.hapsigntool.utils.FileUtils; @@ -95,7 +96,7 @@ public class Zip { // 4. file all data - eocd - cd - entry = sign block signingBlock = getSigningBlock(inputFile); } catch (IOException e) { - CustomException.throwException(ERROR.ZIP_ERROR, e.getMessage()); + CustomException.throwException(ERROR.ZIP_ERROR, SignToolErrMsg.READ_ZIP_FAILED.toString(e.getMessage())); } } @@ -213,7 +214,7 @@ public class Zip { } FileUtils.writeByteToOutFile(endOfCentralDirectory.toBytes(), fos); } catch (IOException e) { - CustomException.throwException(ERROR.ZIP_ERROR, e.getMessage()); + CustomException.throwException(ERROR.ZIP_ERROR, SignToolErrMsg.WRITE_ZIP_FAILED.toString(e.getMessage())); } } @@ -253,7 +254,8 @@ public class Zip { } } } catch (ZipException e) { - CustomException.throwException(ERROR.ZIP_ERROR, e.getMessage()); + CustomException.throwException(ERROR.ZIP_ERROR, SignToolErrMsg.ALIGNMENT_ZIP_FAILED + .toString(e.getMessage())); } } diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipUtils.java index fca69eb0b1b5cd8ddc31e329aafab75e46d3fa20..921bd0b49be3c180c504e318ef666912cef6d0f5 100644 --- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipUtils.java +++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipUtils.java @@ -17,6 +17,7 @@ package com.ohos.hapsigntool.zip; import com.ohos.hapsigntool.entity.Pair; import com.ohos.hapsigntool.error.HapFormatException; +import com.ohos.hapsigntool.error.SignToolErrMsg; import java.io.IOException; import java.nio.ByteBuffer; @@ -192,24 +193,28 @@ public class ZipUtils { public static ZipFileInfo findZipInfo(ZipDataInput in) throws IOException, HapFormatException { Pair eocdOffsetAndBuffer = findEocdInHap(in); if (eocdOffsetAndBuffer == null) { - throw new HapFormatException("ZIP End of Central Directory not found"); + throw new HapFormatException(SignToolErrMsg.ZIP_FORMAT_FAILED + .toString("ZIP End of Central Directory not found")); } long eocdOffset = eocdOffsetAndBuffer.getFirst(); ByteBuffer eocdBuffer = eocdOffsetAndBuffer.getSecond().order(ByteOrder.LITTLE_ENDIAN); long centralDirectoryStartOffset = ZipUtils.getCentralDirectoryOffset(eocdBuffer); if (centralDirectoryStartOffset > eocdOffset) { - throw new HapFormatException("ZIP Central Directory start offset(" + centralDirectoryStartOffset - + ") larger than ZIP End of Central Directory offset(" + eocdOffset + ")"); + throw new HapFormatException(SignToolErrMsg.ZIP_FORMAT_FAILED + .toString("ZIP Central Directory start offset(" + centralDirectoryStartOffset + + ") larger than ZIP End of Central Directory offset(" + eocdOffset + ")")); } long centralDirectorySizeLong = ZipUtils.getCentralDirectorySize(eocdBuffer); if (centralDirectorySizeLong > Integer.MAX_VALUE) { - throw new HapFormatException("ZIP Central Directory out of range: " + centralDirectorySizeLong); + throw new HapFormatException(SignToolErrMsg.ZIP_FORMAT_FAILED + .toString("ZIP Central Directory out of range: " + centralDirectorySizeLong)); } int centralDirectorySize = (int) centralDirectorySizeLong; long centralDirectoryEndOffset = centralDirectoryStartOffset + centralDirectorySizeLong; if (centralDirectoryEndOffset != eocdOffset) { - throw new HapFormatException("ZIP Central Directory end offset(" + centralDirectoryEndOffset + ") " - + " different from ZIP End of Central Directory offset(" + eocdOffset + ")"); + throw new HapFormatException(SignToolErrMsg.ZIP_FORMAT_FAILED + .toString("ZIP Central Directory end offset(" + centralDirectoryEndOffset + ") " + + " different from ZIP End of Central Directory offset(" + eocdOffset + ")")); } int centralDirectoryCount = ZipUtils.getCentralDirectoryCount(eocdBuffer); return new ZipFileInfo(centralDirectoryStartOffset, centralDirectorySize, centralDirectoryCount, eocdOffset, diff --git a/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java b/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java index a6366dd1b037364c2092173fff2c7e2936065b58..5cfc4f15d77def470cb98fa69abf9bced30b83e7 100644 --- a/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java +++ b/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java @@ -20,6 +20,7 @@ import com.ohos.hapsigntool.api.SignToolServiceImpl; import com.ohos.hapsigntool.entity.Options; import com.ohos.hapsigntool.error.CustomException; import com.ohos.hapsigntool.error.ERROR; +import com.ohos.hapsigntool.error.SignToolErrMsg; import com.ohos.hapsigntool.error.VerifyException; import com.ohos.hapsigntool.utils.KeyPairTools; import com.ohos.hapsigntool.profile.ProfileSignTool; @@ -148,7 +149,7 @@ public class ProfileTest { try { verificationResult = verifyHelper.verify(p7b); } catch (VerifyException e) { - CustomException.throwException(ERROR.VERIFY_ERROR, e.getMessage()); + CustomException.throwException(ERROR.VERIFY_ERROR, SignToolErrMsg.VERIFY_FAILED.toString(e.getMessage())); } assertTrue(verificationResult.isVerifiedPassed());