Linux pkcs7_parse_message DER解码与signer_info

Linux pkcs7_parse_message DER解码与signer_info Linux pkcs7_parse_message DER解码与signer_infoPKCS#7解析器位于crypto/asymmetric_keys/pkcs7_parser.c负责将DER编码的PKCS#7签名消息解码为struct pkcs7_message。该结构体包含签名者信息、证书链和被签名内容。入口函数pkcs7_parse_message接收原始DER数据struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen){struct pkcs7_parse_ctx *ctx;struct pkcs7_message *msg;int ret;msg kzalloc(sizeof(*msg), GFP_KERNEL);if (!msg)return ERR_PTR(-ENOMEM);ctx kzalloc(sizeof(*ctx), GFP_KERNEL);if (!ctx) {pkcs7_free_message(msg);return ERR_PTR(-ENOMEM);}ctx-msg msg;ret asn1_ber_decoder(pkcs7_decoder, ctx, data, datalen);if (ret 0) {pkcs7_free_message(msg);msg ERR_PTR(ret);}kfree(ctx);return msg;}asn1_ber_decoder是内核的ASN.1 BER/DER解码器通过预编译的pkcs7_decoder动作表驱动解析。该动作表由crypto/asymmetric_keys/pkcs7.asn1使用asn1_compiler生成。解析过程中关键的数据结构struct pkcs7_signed_info存储签名者信息struct pkcs7_signed_info {struct pkcs7_signed_info *next;struct x509_certificate *signer;struct asymmetric_key_id *sig_issuer;struct asymmetric_key_id *sig_key;unsigned int index;bool unsupported_crypto;bool blacklisted;bool verified;time64_t signing_time;enum hash_algo hash_algo;enum pkey_algo pkey_algo;enum rsa_padding_type padding_algo;const void *authattrs;size_t authattrs_len;struct public_key_signature *sig;struct pkcs7_message *msg;};PKCS#7的SignedData结构包含多个SignerInfo。解析器处理每个SignerInfo时调用pkcs7_extract_signatorystatic int pkcs7_extract_signatory(struct pkcs7_parse_ctx *ctx, const u8 *data, size_t datalen){struct pkcs7_signed_info *si;int ret;si kzalloc(sizeof(*si), GFP_KERNEL);if (!si)return -ENOMEM;si-msg ctx-msg;si-index ctx-msg-num_signed_info;ret asn1_ber_decoder(pkcs7_signed_info_decoder, si, data, datalen);if (ret 0) {kfree(si);return ret;}si-next ctx-msg-signed_infos;ctx-msg-signed_infos si;return 0;}签名信息解析的详细动作在pkcs7_signed_info_decoder中处理包含IssuerAndSerialNumber或SubjectKeyIdentifier的提取static int pkcs7_parse_issuer_and_sn(struct pkcs7_parse_ctx *ctx, const u8 *data, size_t datalen){struct asn1_hdr hdr;const u8 *end;int ret;ret asn1_find_indefinite_length(data, datalen, hdr);if (ret 0)return ret;end hdr.data hdr.len;ctx-sinfo-sig_issuer kzalloc(sizeof(struct asymmetric_key_id), GFP_KERNEL);if (!ctx-sinfo-sig_issuer)return -ENOMEM;ctx-sinfo-sig_issuer-data kmemdup(hdr.data, hdr.len, GFP_KERNEL);ctx-sinfo-sig_issuer-datalen hdr.len;return 0;}digest算法和digest值通过pkcs7_parse_digest提取static int pkcs7_parse_digest(struct pkcs7_parse_ctx *ctx, const u8 *data, size_t datalen){struct asn1_hdr hdr;int ret;ret asn1_find_indefinite_length(data, datalen, hdr);if (ret 0)return ret;ctx-sinfo-sig-digest kmemdup(hdr.data, hdr.len, GFP_KERNEL);ctx-sinfo-sig-digest_size hdr.len;switch (hdr.len) {case 32:ctx-sinfo-hash_algo HASH_ALGO_SHA256;break;case 48:ctx-sinfo-hash_algo HASH_ALGO_SHA384;break;case 64:ctx-sinfo-hash_algo HASH_ALGO_SHA512;break;default:return -ENOPKG;}return 0;}签名算法OID到pkey_algo的映射在pkcs7_parse_signing_algo中完成static int pkcs7_parse_signing_algo(struct pkcs7_parse_ctx *ctx, const u8 *data, size_t datalen){struct asn1_hdr hdr;const u8 *end;const struct oid_lookup *lookup;int ret;ret asn1_find_indefinite_length(data, datalen, hdr);if (ret 0)return ret;lookup oid_lookup(hdr.data, hdr.len);if (!lookup)return -ENOPKG;switch (lookup-oid) {case OID_rsaEncryption:case OID_sha1WithRSAEncryption:case OID_sha256WithRSAEncryption:case OID_sha384WithRSAEncryption:case OID_sha512WithRSAEncryption:ctx-sinfo-pkey_algo PKEY_ALGO_RSA;break;case OID_id_ecdsa_with_sha256:ctx-sinfo-pkey_algo PKEY_ALGO_ECDSA;break;default:return -ENOPKG;}return 0;}解析完成后pkcs7_verify函数遍历signed_infos链表对每个签名者执行验证int pkcs7_verify(struct pkcs7_message *pkcs7, enum key_being_used_for usage){struct pkcs7_signed_info *sinfo;int ret;for (sinfo pkcs7-signed_infos; sinfo; sinfo sinfo-next) {ret pkcs7_verify_one(pkcs7, sinfo);if (ret 0)return ret;sinfo-verified true;}return 0;}pkcs7_validate_trust负责将每个签名者的证书链锚定到系统信任密钥环通过keyring_search在.builtin_trusted_keys中查找匹配的X.509证书。