verify cert path in dev mode

Change-Id: I98224d7cab9747d71a271f62e9cfb2bb7d5cd56d
Signed-off-by: lihehe <lihehao@huawei.com>
This commit is contained in:
lihehe
2023-11-13 21:06:39 +08:00
parent 10e2c7ade4
commit d56f3f5e5f
3 changed files with 42 additions and 34 deletions
+4 -4
View File
@@ -16,7 +16,7 @@
struct rb_root cert_chain_tree = RB_ROOT;
struct rb_root dev_cert_chain_tree = RB_ROOT;
struct cert_source *cert_chain_search(struct rb_root *root, char *subject, char *issuer)
struct cert_source *cert_chain_search(struct rb_root *root, const char *subject, const char *issuer)
{
struct rb_node **cur_node = &(root->rb_node);
@@ -44,12 +44,12 @@ struct cert_source *cert_chain_search(struct rb_root *root, char *subject, char
return NULL;
}
struct cert_source *find_match(struct x509_certificate *cert, bool is_dev)
struct cert_source *find_match(const char *subject, const char *issuer, bool is_dev)
{
if (is_dev)
return cert_chain_search(&dev_cert_chain_tree, cert->subject, cert->issuer);
return cert_chain_search(&dev_cert_chain_tree, subject, issuer);
else
return cert_chain_search(&cert_chain_tree, cert->subject, cert->issuer);
return cert_chain_search(&cert_chain_tree, subject, issuer);
}
int code_sign_check_caller(char *caller)
+1 -1
View File
@@ -39,7 +39,7 @@ struct cert_source {
/*
* cert_chain.c
*/
struct cert_source *find_match(struct x509_certificate *cert, bool is_dev);
struct cert_source *find_match(const char *subject, const char *issuer, bool is_dev);
int code_sign_avc_has_perm(u16 tclass, u32 requested);
+37 -29
View File
@@ -62,6 +62,20 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
return 0;
}
static struct cert_source *find_matched_source(const struct x509_certificate *signer, bool is_debug)
{
int block_type = is_debug ? DEBUG_BLOCK_CODE: RELEASE_BLOCK_CODE;
struct cert_source *source = find_match(signer->subject, signer->issuer, is_debug);
if (source == NULL) {
source = find_match("ALL", signer->issuer, is_debug);
} else if (source->path_type == block_type) {
code_sign_log_error("signer certificate's type not trusted");
return NULL;
}
return source;
}
void code_sign_verify_certchain(const void *raw_pkcs7, size_t pkcs7_len, int *ret)
{
struct pkcs7_message *pkcs7;
@@ -74,28 +88,24 @@ void code_sign_verify_certchain(const void *raw_pkcs7, size_t pkcs7_len, int *re
return;
}
if (!pkcs7->signed_infos) {
code_sign_log_error("signed info not found in pkcs7");
goto untrusted;
}
// no cert chain, verify by certificates in keyring
if (!pkcs7->certs) {
code_sign_log_warn("no certs in pkcs7, might be found in trust keyring");
*ret = MAY_LOCAL_CODE;
return;
goto exit;
}
if (!pkcs7->signed_infos) {
code_sign_log_error("signed info not found in pkcs7");
*ret = -EKEYREJECTED;
return;
}
bool is_dev_mode = false, is_dev_proc = false;
bool is_dev_mode = false;
// developer mode && developer proc
if (!strcmp(developer_mode_state(), DEVELOPER_STATUS_ON)) {
code_sign_log_info("developer mode on");
is_dev_mode = true;
if (!code_sign_avc_has_perm(SECCLASS_XPM, XPM__EXEC_NO_SIGN)) {
is_dev_proc = true;
}
}
for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
@@ -103,30 +113,26 @@ void code_sign_verify_certchain(const void *raw_pkcs7, size_t pkcs7_len, int *re
*ret = pkcs7_find_key(pkcs7, sinfo);
if (*ret) {
code_sign_log_error("key not find in pkcs7");
return;
goto exit;
}
struct x509_certificate *signer = sinfo->signer;
const struct x509_certificate *signer = sinfo->signer;
if (!signer) {
code_sign_log_error("signer cert not found in pkcs7");
*ret = -EINVAL;
return;
goto exit;
}
struct cert_source *source = find_match(signer, is_dev_proc);
if (source == NULL) {
signer->subject = "ALL";
source = find_match(signer, is_dev_proc);
if (source == NULL) {
code_sign_log_error("signer certificate's subject and issuer not trusted");
*ret = -EKEYREJECTED;
return;
struct cert_source *source = find_matched_source(signer, false);
if (!source) {
if (is_dev_mode) {
// find on dev trusted list
source = find_matched_source(signer, true);
if (!source)
goto untrusted;
} else {
goto untrusted;
}
} else if (source->path_type == RELEASE_BLOCK_CODE || source->path_type == DEBUG_BLOCK_CODE) {
code_sign_log_error("signer certificate's type not trusted");
*ret = -EKEYREJECTED;
return;
}
// cal cert chain depth
@@ -152,14 +158,16 @@ void code_sign_verify_certchain(const void *raw_pkcs7, size_t pkcs7_len, int *re
if (cert_chain_depth_without_root == (source->max_path_depth - 1)) {
code_sign_log_info("cert subject and issuer trusted");
*ret = source->path_type;
return;
goto exit;
} else {
code_sign_log_error("depth mismatch: cert chain depth without root is %d, max_path_depth is %d",
cert_chain_depth_without_root, source->max_path_depth);
}
}
untrusted:
code_sign_log_error("cert subject and issuer verify failed");
*ret = -EKEYREJECTED;
return;
exit:
pkcs7_free_message(pkcs7);
}