1 Star 0 Fork 4.9K

bill / docs

forked from OpenHarmony / docs 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
development-guidelines-on-application-signature-verification.md 14.87 KB
一键复制 编辑 原始数据 按行查看 历史
NEEN 提交于 2021-04-08 16:33 . fixed bugs

Development Guidelines on Application Signature Verification

When to Use

You can call the APIs provided by the signature verification component to check integrity of a debugging, released, or OpenHarmony self-signed application. You can also call APIs of the signature verification component to obtain some information in the profile, for example, appid. In addition, you can call APIs to check whether the UDID of a debugging application matches that of the device to ensure that the application is installed on the right device.

Signature Verification Process

An unsigned HAP is in .zip format and consists of a file block, central directory, and end of central directory (EOCD).

After the HAP is signed, a signature block is added between the file block and the central directory. The signature block consists of a file signature block, profile signature block, and signature header. The following figure shows the structure of a signed HAP.

Figure 1 Structure of a signed HAP

The signature verification process consists of three steps: HAP signature verification, signature verification for the profile signature block, and profile content verification.

HAP signature verification

Use the preset root certificate of the device and the certificate chain to prove that the leaf certificate is trusted. Then use the digest obtained by decrypting the public key of the leaf certificate to prove that the HAP is not tampered with.

The process is as follows:

  1. Use the preset root certificate of the device to verify the certificate chain in the file signature block and prove that the leaf certificate is trusted.
  2. Use the public key in the leaf certificate to verify the file signature block and prove that this block is not tampered with.
  3. Calculate and merge the digests of the file block, central directory, and EOCD. Merge the calculation result with the digest of the profile signature block in the signature block. Then compare the merge result with the digest of the file signature block. If they are the same, the HAP signature verification is successful.

Signature verification for the profile signature block

First of all, check who issued the signature of the profile signature block. If the signature was issued by the application market, the signature is trusted and does not need to be verified. Otherwise, the signature needs to be verified. Next, verify the certificate chain and then use the leaf certificate to verify the signature of the profile signature block to prove that it is not tampered with.

Profile content verification

Obtain the profile and check the validity of its content. If the HAP is a debugging application, check whether the UDID of the current device is contained in the UDID list in the profile. If yes, the verification is successful. Then compare the certificate in the profile with the leaf certificate used for HAP verification (this is not required for a released or OpenHarmony self-signed application). If they are the same, the entire signature verification process is complete.

Available APIs

The following table lists the innerkits APIs provided by the signature verification component. These APIs are available only for system applications.

Table 1 APIs provided by the signature verification component

Function

Description

int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)

Verifies a signature by specifying the file path and returns the data obtained from the profile to the caller through verifyRst. This is the main entry function.

int APPVERI_SetDebugMode(bool mode)

Sets the debugging mode. If mode is set to true, certificate chain verification based on the debugging root key is enabled; if mode is set to false, it is disabled.

Note: Currently, no certificate based on the existing debugging root key is available. You can replace the debugging root key and perform related verification as required.

void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)

Releases memory in verifyRst.

Development Procedure (Scenario 1)

Signature Verification

Verification of applications released in the application market, debugging applications signed with debugging certificates of the application market, and OpenHarmony self-signed applications

  1. Construct the VerifyResult structure.

    VerifyResult verifyResult = {0};
  2. Call the APPVERI_AppVerify function by specifying the file path and VerifyResult to verify the application signature.

    int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult);
  3. Check the returned result. If the verification is successful, obtain and process the data in VerifyResult.

    signatureInfo.appId = verifyResult.profile.appid;
    signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName;
  4. Call the APPVERI_FreeVerifyRst function to release memory in VerifyResult.

    APPVERI_FreeVerifyRst(&verifyResult);

OpenHarmony Self-signed Application Generation

The OpenHarmony self-signed application generation procedure is as follows:

  1. Prepare required materials.

    Prepare the signature tool, system application HAP, system application profile (*.p7b), signing certificate (*.cer), and signing public/private key pair (*.jks).

  2. Place all the materials in the same directory and start the shell.

  3. Run the following command in the shell to sign the application:

    java -jar hapsigntoolv2.jar sign -mode localjks -privatekey "OpenHarmony Software Signature" -inputFile camera.hap -outputFile signed_camera.hap -signAlg SHA256withECDSA -keystore OpenHarmony.jks -keystorepasswd 123456 -keyaliaspasswd 123456 -profile camera_release.p7b -certpath OpenHarmony.cer -profileSigned 1

    Key fields:

    -jar: signature tool, which is hapsigntool

    -mode: local signature flag, which is fixed at localjks

    -privatekey: alias of the public/private key pair, which is OpenHarmony Software Signature

    -inputFile: application to be signed, which is generated through compilation

    -outputFile: signed application

    -signAlg: signing algorithm, which is fixed at SHA256withECDSA

    -keystore: public/private key pair, which is OpenHarmony.jks in the OpenHarmonyCer directory of the security_services_app_verify repository. The default password is 123456. You can use a tool (such as keytool) to change the password.

    -keystorepasswd: password of the public/private key pair, which is 123456 by default

    -keyaliaspasswd: password of the public/private key pair alias, which is 123456 by default

    -profile: application profile, which is stored in the code directory

    -certpath: signing certificate, which is OpenHarmony.cer in the OpenHarmonyCer directory of the security_services_app_verify repository.

    -profileSigned: whether the signature block contains the profile. The value is fixed at 1, indicating that the signature block contains the profile.

Development Examples

The following example describes how the application management framework component verifies the signature of an application during its installation.

uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo)
{
	bool mode = ManagerService::GetInstance().IsDebugMode();
	HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode);
        // Construct the VerifyResult structure.
	VerifyResult verifyResult = {0};
        // Verify the signature by specifying the file path.
	int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); 
	uint8_t errorCode = SwitchErrorCode(ret);
	if (errorCode != ERR_OK) {
		return errorCode;
	}
        // Obtain appid from the VerifyResult structure.
	signatureInfo.appId = verifyResult.profile.appid; 
        // Obtain the application name written in the profile from the VerifyResult structure.
	signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; 
	int32_t restricNum = verifyResult.profile.permission.restricNum;
	for (int32_t i = 0; i < restricNum; i++) {
		signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]);
	}
        // Release memory in VerifyResult.
	APPVERI_FreeVerifyRst(&verifyResult); 
	return ERR_OK;
}

Development Procedure (Scenario 2)

Signature Verification

The procedure is as follows:

  1. Call the APPVERI_SetDebugMode(true) function to enable the debugging mode.

    	ManagerService::SetDebugMode(true);
    ...
    uint8_t ManagerService::SetDebugMode(bool enable)
    {
    	int32_t ret = APPVERI_SetDebugMode(enable);
    	if (ret < 0) {
    		HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed");
    		return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR;
    	}
    	isDebugMode_ = enable;
    	HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_);
    	return ERR_OK;
    }
  2. Construct the VerifyResult structure, verify the application signature, and release memory in VerifyResult.

  3. Call the APPVERI_SetDebugMode(false) function to disable the debugging mode.

            ManagerService::SetDebugMode(false);

Development Examples

The following is the example code (supplemented based on the example code for scenario 1):

uint8_t ManagerService::SetDebugMode(bool enable)
{
	int32_t ret = APPVERI_SetDebugMode(enable);
	if (ret < 0) {
		HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed");
		return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR;
	}
	isDebugMode_ = enable;
	HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_);
	return ERR_OK;
}
uint8_t HapSignVerify::VerifySignature(const std::string &hapFilepath, SignatureInfo &signatureInfo)
{
        // Enable debugging mode.
        ManagerService::SetDebugMode(true); 
	bool mode = ManagerService::GetInstance().IsDebugMode();
	HILOG_INFO(HILOG_MODULE_APP, "current mode is %d!", mode);
        // Construct the VerifyResult structure.
	VerifyResult verifyResult = {0}; 
        // Verify the signature by specifying the file path.
	int32_t ret = APPVERI_AppVerify(hapFilepath.c_str(), &verifyResult); 
	uint8_t errorCode = SwitchErrorCode(ret);
	if (errorCode != ERR_OK) {
		return errorCode;
	}
        // Obtain appid from the VerifyResult structure.
	signatureInfo.appId = verifyResult.profile.appid; 
        // Obtain the application name written in the profile from the VerifyResult structure.
	signatureInfo.provisionBundleName = verifyResult.profile.bundleInfo.bundleName; 
	int32_t restricNum = verifyResult.profile.permission.restricNum;
	for (int32_t i = 0; i < restricNum; i++) {
		signatureInfo.restrictedPermissions.emplace_back((verifyResult.profile.permission.restricPermission)[i]);
	}
        // Release memory in VerifyResult.
        APPVERI_FreeVerifyRst(&verifyResult); 
        // Disable debugging mode.
        ManagerService::SetDebugMode(false); 
	return ERR_OK;
}

Debugging and Verification

  1. Choose an application that can be properly installed on OpenHarmony.
  2. Develop the application based on the development guidelines.
  3. Use a self-developed program to verify the signature of the developed application. If the verification is successful and appid can be obtained, the development is successful.
1
https://gitee.com/ximeibaba/docs.git
git@gitee.com:ximeibaba/docs.git
ximeibaba
docs
docs
master

搜索帮助