1 /* 2 * Copyright (c) 2020 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MBEDTLS_PKCS7_H 17 #define MBEDTLS_PKCS7_H 18 #include <stdbool.h> 19 #include <stdint.h> 20 #include <mbedtls/asn1.h> 21 #include <mbedtls/x509.h> 22 #include <mbedtls/x509_crt.h> 23 #include <mbedtls/x509_crl.h> 24 #include <mbedtls/pem.h> 25 #include <mbedtls/oid.h> 26 27 #ifdef __cplusplus 28 #if __cplusplus 29 extern "C" { 30 #endif 31 #endif 32 33 /* 34 * if the pkcs7 format is pem, add this define in this header file 35 * or in build env 36 * #define PARSE_PEM_FORMAT_SIGNED_DATA 1 37 */ 38 #define MAX_SIGNER_NAME_LEN 512 39 40 typedef enum { 41 PKCS7_SUCC = 0, 42 PKCS7_PARSING_ERROR, 43 PKCS7_INVALID_PARAM, 44 PKCS7_INVALID_VALUE, 45 PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT, 46 PKCS7_CERTIFICATE_NOT_FOUND, 47 PKCS7_INVALID_VERSION, 48 PKCS7_INVALID_DIGEST_ALG, 49 PKCS7_INVALID_SIGNING_ALG, 50 PKCS7_MEMORY_EXHAUST, 51 PKCS7_ROOT_CA_NOT_VALID, 52 PKCS7_BUILD_CERT_PATH_FAIL, 53 PKCS7_HAS_NO_AUTH_ATTR_IN_SIGNER, 54 PKCS7_HAS_NO_SIGNER_INFO, 55 PKCS7_HAS_NO_SIGNER_CRT, 56 PKCS7_IS_REVOKED, 57 PKCS7_VERIFY_FAIL, 58 } PKCS7_RetCode; 59 60 typedef struct { 61 char issuer[MAX_SIGNER_NAME_LEN]; 62 char subject[MAX_SIGNER_NAME_LEN]; 63 int32_t depth; 64 } SignerResovledInfo; 65 66 typedef struct { 67 SignerResovledInfo *signers; 68 int32_t nrOfSigners; 69 } SignersResovedInfo; 70 71 /* 72 * The structure bellow used the mbedtls open source structure which definition is kernel-like style, 73 * We do not redefine it to Camel style 74 * 75 * the PKCS7 signer's cert path header 76 * depth is the signer's cert path depth 77 * crt is the certs list header, the lower ca cert is at front 78 */ 79 typedef struct { 80 int32_t depth; 81 mbedtls_x509_crt *crt; 82 } SignerCertPath; 83 84 /* 85 * PKCS7 signer info structure, as defined in PKCS7 86 * rootCert is not defined in PKCS7, this is the signer's root cert preinstall in system 87 * certPath is for cert chain verify 88 * next is point to the next signer info, as PKCS7 definination, maybe there are multi signer 89 */ 90 typedef struct tagSignerInfo { 91 int32_t version; 92 mbedtls_x509_buf serial; 93 mbedtls_x509_name issuer; 94 mbedtls_x509_crt *rootCert; 95 mbedtls_x509_buf issuerRaw; 96 mbedtls_x509_buf digestAlgId; 97 mbedtls_x509_buf authAttr; 98 mbedtls_x509_buf authAttrRaw; 99 mbedtls_x509_buf digestEncAlgId; 100 mbedtls_x509_buf signature; 101 mbedtls_x509_buf unAuthAttr; 102 SignerCertPath certPath; 103 struct tagSignerInfo *next; 104 } SignerInfo; 105 106 /* 107 * PKCS7 signed data content info 108 */ 109 typedef struct tagContent { 110 mbedtls_asn1_buf oid; 111 mbedtls_asn1_buf data; 112 } Content; 113 114 /* 115 * PKCS7 signed data digest algorithm identifiers 116 */ 117 typedef struct tagDigestAlgId { 118 mbedtls_asn1_buf algBuf; 119 struct tagDigestAlgId *next; 120 } DigestAlgId; 121 122 /* 123 * PKCS7 signed-data structure 124 */ 125 typedef struct { 126 int32_t version; 127 DigestAlgId digestAlgIds; 128 Content content; 129 mbedtls_x509_crt *certs; 130 mbedtls_x509_crl crl; 131 SignerInfo signers; 132 } SignedData; 133 134 /* 135 * PKCS7 signed data total structure header 136 * contentTypeOid must be the pkcs7 signed-data oid 1.2.840.113549.1.7.2 137 */ 138 typedef struct { 139 mbedtls_asn1_buf contentTypeOid; 140 SignedData signedData; 141 #ifdef PARSE_PEM_FORMAT_SIGNED_DATA 142 mbedtls_pem_context pem; 143 #endif 144 } Pkcs7; 145 146 /******************************************************************************* 147 * Function : PKCS7_ParseSignedData 148 * Description : parse the pkcs7 signed data, store the resolved data to pkcs7 149 * Input : buf - pkcs7 signed data 150 * bufLen - pkcs7 signed data length 151 * Output : pkcs7 - resolved pkcs7 data, caller provide this arg, malloc 152 * from heap memory or use stack memory, if malloced 153 * from heap memory, caller must freed the memory after 154 * called PKCS7_FreeRes 155 * Return : 0 on success, others on fail 156 * Note : need to call PKCS7_FreeRes to free the resource when success 157 * parse and use, no need to call PKCS7_FreeRes when parse failed 158 *******************************************************************************/ 159 int32_t PKCS7_ParseSignedData(const unsigned char *buf, size_t bufLen, Pkcs7 *pkcs7); 160 161 /******************************************************************************* 162 * Function : PKCS7_VerifyCertsChain 163 * Description : Verify all signer's cert chain 164 * Input : pkcs7 -- the pkcs7 signed data header. 165 * Return : 0 on success, others on fail 166 *******************************************************************************/ 167 int32_t PKCS7_VerifyCertsChain(const Pkcs7 *pkcs7); 168 169 /******************************************************************************* 170 * Function : PKCS7_FreeRes 171 * Description : free the resource of resolved pkcs7 data 172 * Input : pkcs7 - resolved pkcs7 data 173 * Return : 0 on success, others on fail 174 * Note : need to call PKCS7_FreeRes to free the resource when success 175 * parse and use, no need to call PKCS7_FreeRes when parse failed 176 *******************************************************************************/ 177 void PKCS7_FreeRes(Pkcs7 *pkcs7); 178 179 /******************************************************************************* 180 * Function : PKCS7_CalcDigest 181 * Description : is a callback defined by upper layer user, calculate the 182 * digest for final verify the signed data signature. 183 * Input : pkcs7 - pkcs7 signed data header 184 * signer - pkcs7 signer info 185 * algType - digest algorithm type, defined in mbedtls, exp: 186 * MBEDTLS_MD_SHA256/MBEDTLS_MD_SHA512 187 * Output : hash - the calcuated digest hash 188 * hashLen - the length of calculated digest hash 189 * Return : 0 on success, others on fail 190 *******************************************************************************/ 191 typedef int32_t (*PKCS7_CalcDigest)(const Pkcs7 *pkcs7, const SignerInfo *signer, 192 mbedtls_md_type_t algType, unsigned char *hash, size_t *hashLen); 193 194 /******************************************************************************* 195 * Function : PKCS7_GetContentData 196 * Description : get the content data of PKCS#7 signed-data content 197 * Input : pkcs7 - pkcs7 signed data header 198 * Output : data - pointer to the content data 199 * user need not to free this var 200 * dataLen - the content data length 201 * Return : 0 on success, others on fail 202 *******************************************************************************/ 203 int32_t PKCS7_GetContentData(const Pkcs7 *pkcs7, unsigned char **data, size_t *dataLen); 204 205 /******************************************************************************* 206 * Function : PKCS7_GetDigestInSignerAuthAttr 207 * Description : get the digest which stored in signer's auth attribute. 208 * Input : signer - pkcs7 signer info 209 * Output : dig - pointer to the digest stored in signer's auth attribute 210 * user need not to free this var 211 * digLen - digest length 212 * Return : 0 on success, others on fail 213 *******************************************************************************/ 214 int32_t PKCS7_GetDigestInSignerAuthAttr(const SignerInfo *signer, unsigned char **dig, size_t *digLen); 215 216 /******************************************************************************* 217 * Function : PKCS7_GetSignerAuthAttr 218 * Description : get the signer's auth attribute content, which maybe signed by 219 * signer, so upper layer can call this to get to-be-signed data, 220 * then calculate digest of it for signature verification 221 * Input : signer - pkcs7 signer info 222 * Output : data - pointer to signer's auth attribute start location 223 * user need not to free this var 224 * dataLen - signer auth attribute data length 225 * Return : 0 on success, others on fail 226 *******************************************************************************/ 227 int32_t PKCS7_GetSignerAuthAttr(const SignerInfo *signer, unsigned char **data, size_t *dataLen); 228 229 /******************************************************************************* 230 * Function : PKCS7_VerifySignerSignature 231 * Description : Verify all of signer's signature 232 * Input : pkcs7 - pkcs7 signed data header 233 * calcDigest - callback function for upper layer user to calculate 234 * the digest of signature 235 * Output : NA 236 * Return : 0 on success, others on fail 237 *******************************************************************************/ 238 int32_t PKCS7_VerifySignerSignature(const Pkcs7 *pkcs7, PKCS7_CalcDigest calcDigest); 239 240 /******************************************************************************* 241 * Function : PKCS7_GetAllSignersResolvedInfo 242 * Description : Get all signer's associate info, now including subject/issuer/ 243 * cert depth, used it for trustlist match. 244 * Input : pkcs7 - pkcs7 signed data header 245 * Output : the structure of associate signer's info 246 * Return : non-NULL on success, and user need to call 247 * PKCS7_FreeAllSignersResolvedInfo to free resource 248 *******************************************************************************/ 249 SignersResovedInfo *PKCS7_GetAllSignersResolvedInfo(const Pkcs7 *pkcs7); 250 251 /******************************************************************************* 252 * Function : PKCS7_FreeAllSignersResolvedInfo 253 * Description : Free the signer associate info. 254 * Input : sri - signer associate info 255 * Output : NA 256 * Return : void 257 *******************************************************************************/ 258 void PKCS7_FreeAllSignersResolvedInfo(SignersResovedInfo *sri); 259 260 /******************************************************************************* 261 * Function : PKCS7_EnableDebugMode 262 * Description : Enable or disable debug mode, so it can install the app that 263 * signed by the test cert's private key. 264 * Input : mode - true:enable, false:disable 265 * Output : NA 266 * Return : 0 on success, others on error 267 *******************************************************************************/ 268 int32_t PKCS7_EnableDebugMode(bool mode); 269 270 #ifdef __cplusplus 271 #if __cplusplus 272 } 273 #endif 274 #endif 275 #endif // MBEDTLS_PKCS7_H 276