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