Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
pkcs7.c
00001 /* pkcs7.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 #ifdef HAVE_PKCS7 00030 00031 #include <wolfssl/wolfcrypt/pkcs7.h> 00032 #include <wolfssl/wolfcrypt/error-crypt.h> 00033 #include <wolfssl/wolfcrypt/logging.h> 00034 #ifdef NO_INLINE 00035 #include <wolfssl/wolfcrypt/misc.h> 00036 #else 00037 #include <wolfcrypt/src/misc.c> 00038 #endif 00039 00040 #ifndef WOLFSSL_HAVE_MIN 00041 #define WOLFSSL_HAVE_MIN 00042 00043 static INLINE word32 min(word32 a, word32 b) 00044 { 00045 return a > b ? b : a; 00046 } 00047 00048 #endif /* WOLFSSL_HAVE_MIN */ 00049 00050 00051 /* placed ASN.1 contentType OID into *output, return idx on success, 00052 * 0 upon failure */ 00053 WOLFSSL_LOCAL int wc_SetContentType(int pkcs7TypeOID, byte* output) 00054 { 00055 /* PKCS#7 content types, RFC 2315, section 14 */ 00056 const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00057 0x0D, 0x01, 0x07 }; 00058 const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00059 0x0D, 0x01, 0x07, 0x01 }; 00060 const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00061 0x0D, 0x01, 0x07, 0x02}; 00062 const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00063 0x0D, 0x01, 0x07, 0x03 }; 00064 const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00065 0x0D, 0x01, 0x07, 0x04 }; 00066 const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00067 0x0D, 0x01, 0x07, 0x05 }; 00068 const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 00069 0x0D, 0x01, 0x07, 0x06 }; 00070 00071 int idSz; 00072 int typeSz = 0, idx = 0; 00073 const byte* typeName = 0; 00074 byte ID_Length[MAX_LENGTH_SZ]; 00075 00076 switch (pkcs7TypeOID) { 00077 case PKCS7_MSG: 00078 typeSz = sizeof(pkcs7); 00079 typeName = pkcs7; 00080 break; 00081 00082 case DATA: 00083 typeSz = sizeof(data); 00084 typeName = data; 00085 break; 00086 00087 case SIGNED_DATA: 00088 typeSz = sizeof(signedData); 00089 typeName = signedData; 00090 break; 00091 00092 case ENVELOPED_DATA: 00093 typeSz = sizeof(envelopedData); 00094 typeName = envelopedData; 00095 break; 00096 00097 case SIGNED_AND_ENVELOPED_DATA: 00098 typeSz = sizeof(signedAndEnveloped); 00099 typeName = signedAndEnveloped; 00100 break; 00101 00102 case DIGESTED_DATA: 00103 typeSz = sizeof(digestedData); 00104 typeName = digestedData; 00105 break; 00106 00107 case ENCRYPTED_DATA: 00108 typeSz = sizeof(encryptedData); 00109 typeName = encryptedData; 00110 break; 00111 00112 default: 00113 WOLFSSL_MSG("Unknown PKCS#7 Type"); 00114 return 0; 00115 }; 00116 00117 idSz = SetLength(typeSz, ID_Length); 00118 output[idx++] = ASN_OBJECT_ID; 00119 XMEMCPY(output + idx, ID_Length, idSz); 00120 idx += idSz; 00121 XMEMCPY(output + idx, typeName, typeSz); 00122 idx += typeSz; 00123 00124 return idx; 00125 00126 } 00127 00128 00129 /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */ 00130 int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid, 00131 word32 maxIdx) 00132 { 00133 WOLFSSL_ENTER("wc_GetContentType"); 00134 if (GetObjectId(input, inOutIdx, oid, ignoreType, maxIdx) < 0) 00135 return ASN_PARSE_E; 00136 00137 return 0; 00138 } 00139 00140 00141 /* init PKCS7 struct with recipient cert, decode into DecodedCert */ 00142 int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz) 00143 { 00144 int ret = 0; 00145 00146 XMEMSET(pkcs7, 0, sizeof(PKCS7)); 00147 if (cert != NULL && certSz > 0) { 00148 #ifdef WOLFSSL_SMALL_STACK 00149 DecodedCert* dCert; 00150 00151 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, 00152 DYNAMIC_TYPE_TMP_BUFFER); 00153 if (dCert == NULL) 00154 return MEMORY_E; 00155 #else 00156 DecodedCert stack_dCert; 00157 DecodedCert* dCert = &stack_dCert; 00158 #endif 00159 00160 pkcs7->singleCert = cert; 00161 pkcs7->singleCertSz = certSz; 00162 InitDecodedCert(dCert, cert, certSz, 0); 00163 00164 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0); 00165 if (ret < 0) { 00166 FreeDecodedCert(dCert); 00167 #ifdef WOLFSSL_SMALL_STACK 00168 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00169 #endif 00170 return ret; 00171 } 00172 00173 XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize); 00174 pkcs7->publicKeySz = dCert->pubKeySize; 00175 XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE); 00176 pkcs7->issuer = dCert->issuerRaw; 00177 pkcs7->issuerSz = dCert->issuerRawLen; 00178 XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz); 00179 pkcs7->issuerSnSz = dCert->serialSz; 00180 FreeDecodedCert(dCert); 00181 00182 #ifdef WOLFSSL_SMALL_STACK 00183 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00184 #endif 00185 } 00186 00187 return ret; 00188 } 00189 00190 00191 /* releases any memory allocated by a PKCS7 initializer */ 00192 void wc_PKCS7_Free(PKCS7* pkcs7) 00193 { 00194 (void)pkcs7; 00195 } 00196 00197 00198 /* build PKCS#7 data content type */ 00199 int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz) 00200 { 00201 static const byte oid[] = 00202 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 00203 0x07, 0x01 }; 00204 byte seq[MAX_SEQ_SZ]; 00205 byte octetStr[MAX_OCTET_STR_SZ]; 00206 word32 seqSz; 00207 word32 octetStrSz; 00208 word32 oidSz = (word32)sizeof(oid); 00209 int idx = 0; 00210 00211 octetStrSz = SetOctetString(pkcs7->contentSz, octetStr); 00212 seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq); 00213 00214 if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz) 00215 return BUFFER_E; 00216 00217 XMEMCPY(output, seq, seqSz); 00218 idx += seqSz; 00219 XMEMCPY(output + idx, oid, oidSz); 00220 idx += oidSz; 00221 XMEMCPY(output + idx, octetStr, octetStrSz); 00222 idx += octetStrSz; 00223 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); 00224 idx += pkcs7->contentSz; 00225 00226 return idx; 00227 } 00228 00229 00230 typedef struct EncodedAttrib { 00231 byte valueSeq[MAX_SEQ_SZ]; 00232 const byte* oid; 00233 byte valueSet[MAX_SET_SZ]; 00234 const byte* value; 00235 word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz; 00236 } EncodedAttrib; 00237 00238 00239 typedef struct ESD { 00240 Sha sha; 00241 byte contentDigest[SHA_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */ 00242 byte contentAttribsDigest[SHA_DIGEST_SIZE]; 00243 byte encContentDigest[512]; 00244 00245 byte outerSeq[MAX_SEQ_SZ]; 00246 byte outerContent[MAX_EXP_SZ]; 00247 byte innerSeq[MAX_SEQ_SZ]; 00248 byte version[MAX_VERSION_SZ]; 00249 byte digAlgoIdSet[MAX_SET_SZ]; 00250 byte singleDigAlgoId[MAX_ALGO_SZ]; 00251 00252 byte contentInfoSeq[MAX_SEQ_SZ]; 00253 byte innerContSeq[MAX_EXP_SZ]; 00254 byte innerOctets[MAX_OCTET_STR_SZ]; 00255 00256 byte certsSet[MAX_SET_SZ]; 00257 00258 byte signerInfoSet[MAX_SET_SZ]; 00259 byte signerInfoSeq[MAX_SEQ_SZ]; 00260 byte signerVersion[MAX_VERSION_SZ]; 00261 byte issuerSnSeq[MAX_SEQ_SZ]; 00262 byte issuerName[MAX_SEQ_SZ]; 00263 byte issuerSn[MAX_SN_SZ]; 00264 byte signerDigAlgoId[MAX_ALGO_SZ]; 00265 byte digEncAlgoId[MAX_ALGO_SZ]; 00266 byte signedAttribSet[MAX_SET_SZ]; 00267 EncodedAttrib signedAttribs[6]; 00268 byte signerDigest[MAX_OCTET_STR_SZ]; 00269 word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz; 00270 word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz, 00271 singleDigAlgoIdSz, certsSetSz; 00272 word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz, 00273 issuerSnSeqSz, issuerNameSz, issuerSnSz, 00274 signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz; 00275 word32 encContentDigestSz, signedAttribsSz, signedAttribsCount, 00276 signedAttribSetSz; 00277 } ESD; 00278 00279 00280 static int EncodeAttributes(EncodedAttrib* ea, int eaSz, 00281 PKCS7Attrib* attribs, int attribsSz) 00282 { 00283 int i; 00284 int maxSz = min(eaSz, attribsSz); 00285 int allAttribsSz = 0; 00286 00287 for (i = 0; i < maxSz; i++) 00288 { 00289 int attribSz = 0; 00290 00291 ea[i].value = attribs[i].value; 00292 ea[i].valueSz = attribs[i].valueSz; 00293 attribSz += ea[i].valueSz; 00294 ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet); 00295 attribSz += ea[i].valueSetSz; 00296 ea[i].oid = attribs[i].oid; 00297 ea[i].oidSz = attribs[i].oidSz; 00298 attribSz += ea[i].oidSz; 00299 ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq); 00300 attribSz += ea[i].valueSeqSz; 00301 ea[i].totalSz = attribSz; 00302 00303 allAttribsSz += attribSz; 00304 } 00305 return allAttribsSz; 00306 } 00307 00308 00309 static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz) 00310 { 00311 int i, idx; 00312 00313 idx = 0; 00314 for (i = 0; i < eaSz; i++) { 00315 XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz); 00316 idx += ea[i].valueSeqSz; 00317 XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz); 00318 idx += ea[i].oidSz; 00319 XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz); 00320 idx += ea[i].valueSetSz; 00321 XMEMCPY(output + idx, ea[i].value, ea[i].valueSz); 00322 idx += ea[i].valueSz; 00323 } 00324 return 0; 00325 } 00326 00327 00328 /* build PKCS#7 signedData content type */ 00329 int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) 00330 { 00331 static const byte outerOid[] = 00332 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 00333 0x07, 0x02 }; 00334 static const byte innerOid[] = 00335 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 00336 0x07, 0x01 }; 00337 00338 #ifdef WOLFSSL_SMALL_STACK 00339 ESD* esd = NULL; 00340 #else 00341 ESD stack_esd; 00342 ESD* esd = &stack_esd; 00343 #endif 00344 00345 word32 signerInfoSz = 0; 00346 word32 totalSz = 0; 00347 int idx = 0, ret = 0; 00348 byte* flatSignedAttribs = NULL; 00349 word32 flatSignedAttribsSz = 0; 00350 word32 innerOidSz = sizeof(innerOid); 00351 word32 outerOidSz = sizeof(outerOid); 00352 00353 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || 00354 pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 || 00355 pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 || 00356 pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 || 00357 output == NULL || outputSz == 0) 00358 return BAD_FUNC_ARG; 00359 00360 #ifdef WOLFSSL_SMALL_STACK 00361 esd = (ESD*)XMALLOC(sizeof(ESD), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00362 if (esd == NULL) 00363 return MEMORY_E; 00364 #endif 00365 00366 XMEMSET(esd, 0, sizeof(ESD)); 00367 ret = wc_InitSha(&esd->sha); 00368 if (ret != 0) { 00369 #ifdef WOLFSSL_SMALL_STACK 00370 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00371 #endif 00372 return ret; 00373 } 00374 00375 if (pkcs7->contentSz != 0) 00376 { 00377 wc_ShaUpdate(&esd->sha, pkcs7->content, pkcs7->contentSz); 00378 esd->contentDigest[0] = ASN_OCTET_STRING; 00379 esd->contentDigest[1] = SHA_DIGEST_SIZE; 00380 wc_ShaFinal(&esd->sha, &esd->contentDigest[2]); 00381 } 00382 00383 esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); 00384 esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz, 00385 esd->innerContSeq); 00386 esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd->innerOctetsSz + 00387 innerOidSz + esd->innerContSeqSz, 00388 esd->contentInfoSeq); 00389 00390 esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, 00391 esd->issuerSn); 00392 signerInfoSz += esd->issuerSnSz; 00393 esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName); 00394 signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz; 00395 esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq); 00396 signerInfoSz += esd->issuerSnSeqSz; 00397 esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0); 00398 signerInfoSz += esd->signerVersionSz; 00399 esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId, 00400 hashType, 0); 00401 signerInfoSz += esd->signerDigAlgoIdSz; 00402 esd->digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd->digEncAlgoId, 00403 keyType, 0); 00404 signerInfoSz += esd->digEncAlgoIdSz; 00405 00406 if (pkcs7->signedAttribsSz != 0) { 00407 byte contentTypeOid[] = 00408 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, 00409 0x09, 0x03 }; 00410 byte contentType[] = 00411 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 00412 0x07, 0x01 }; 00413 byte messageDigestOid[] = 00414 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 00415 0x09, 0x04 }; 00416 00417 PKCS7Attrib cannedAttribs[2] ; 00418 00419 word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); 00420 cannedAttribs[0].oid = contentTypeOid ; 00421 cannedAttribs[0].oidSz = sizeof(contentTypeOid) ; 00422 cannedAttribs[0].value = contentType ; 00423 cannedAttribs[0].valueSz = sizeof(contentType) ; 00424 cannedAttribs[1].oid = messageDigestOid ; 00425 cannedAttribs[1].oidSz = sizeof(messageDigestOid) ; 00426 cannedAttribs[1].value = esd->contentDigest ; 00427 cannedAttribs[1].valueSz = sizeof(esd->contentDigest) ; 00428 00429 esd->signedAttribsCount += cannedAttribsCount; 00430 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2, 00431 cannedAttribs, cannedAttribsCount); 00432 00433 esd->signedAttribsCount += pkcs7->signedAttribsSz; 00434 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4, 00435 pkcs7->signedAttribs, pkcs7->signedAttribsSz); 00436 00437 flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, 0, NULL); 00438 flatSignedAttribsSz = esd->signedAttribsSz; 00439 if (flatSignedAttribs == NULL) { 00440 #ifdef WOLFSSL_SMALL_STACK 00441 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00442 #endif 00443 return MEMORY_E; 00444 } 00445 FlattenAttributes(flatSignedAttribs, 00446 esd->signedAttribs, esd->signedAttribsCount); 00447 esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz, 00448 esd->signedAttribSet); 00449 } 00450 /* Calculate the final hash and encrypt it. */ 00451 { 00452 int result; 00453 word32 scratch = 0; 00454 00455 #ifdef WOLFSSL_SMALL_STACK 00456 byte* digestInfo; 00457 RsaKey* privKey; 00458 #else 00459 RsaKey stack_privKey; 00460 RsaKey* privKey = &stack_privKey; 00461 byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ + 00462 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE]; 00463 #endif 00464 byte digestInfoSeq[MAX_SEQ_SZ]; 00465 byte digestStr[MAX_OCTET_STR_SZ]; 00466 word32 digestInfoSeqSz, digestStrSz; 00467 int digIdx = 0; 00468 00469 if (pkcs7->signedAttribsSz != 0) { 00470 byte attribSet[MAX_SET_SZ]; 00471 word32 attribSetSz; 00472 00473 attribSetSz = SetSet(flatSignedAttribsSz, attribSet); 00474 00475 ret = wc_InitSha(&esd->sha); 00476 if (ret < 0) { 00477 XFREE(flatSignedAttribs, 0, NULL); 00478 #ifdef WOLFSSL_SMALL_STACK 00479 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00480 #endif 00481 return ret; 00482 } 00483 wc_ShaUpdate(&esd->sha, attribSet, attribSetSz); 00484 wc_ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz); 00485 } 00486 wc_ShaFinal(&esd->sha, esd->contentAttribsDigest); 00487 00488 digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr); 00489 digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz + 00490 digestStrSz + SHA_DIGEST_SIZE, 00491 digestInfoSeq); 00492 00493 #ifdef WOLFSSL_SMALL_STACK 00494 digestInfo = (byte*)XMALLOC(MAX_SEQ_SZ + MAX_ALGO_SZ + 00495 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE, 00496 NULL, DYNAMIC_TYPE_TMP_BUFFER); 00497 if (digestInfo == NULL) { 00498 if (pkcs7->signedAttribsSz != 0) 00499 XFREE(flatSignedAttribs, 0, NULL); 00500 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00501 return MEMORY_E; 00502 } 00503 #endif 00504 00505 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz); 00506 digIdx += digestInfoSeqSz; 00507 XMEMCPY(digestInfo + digIdx, 00508 esd->signerDigAlgoId, esd->signerDigAlgoIdSz); 00509 digIdx += esd->signerDigAlgoIdSz; 00510 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz); 00511 digIdx += digestStrSz; 00512 XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, 00513 SHA_DIGEST_SIZE); 00514 digIdx += SHA_DIGEST_SIZE; 00515 00516 #ifdef WOLFSSL_SMALL_STACK 00517 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, 00518 DYNAMIC_TYPE_TMP_BUFFER); 00519 if (privKey == NULL) { 00520 if (pkcs7->signedAttribsSz != 0) 00521 XFREE(flatSignedAttribs, 0, NULL); 00522 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00523 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00524 return MEMORY_E; 00525 } 00526 #endif 00527 00528 result = wc_InitRsaKey(privKey, NULL); 00529 if (result == 0) 00530 result = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, privKey, 00531 pkcs7->privateKeySz); 00532 if (result < 0) { 00533 if (pkcs7->signedAttribsSz != 0) 00534 XFREE(flatSignedAttribs, 0, NULL); 00535 #ifdef WOLFSSL_SMALL_STACK 00536 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00537 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00538 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00539 #endif 00540 return PUBLIC_KEY_E; 00541 } 00542 00543 result = wc_RsaSSL_Sign(digestInfo, digIdx, 00544 esd->encContentDigest, 00545 sizeof(esd->encContentDigest), 00546 privKey, pkcs7->rng); 00547 00548 wc_FreeRsaKey(privKey); 00549 00550 #ifdef WOLFSSL_SMALL_STACK 00551 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00552 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00553 #endif 00554 00555 if (result < 0) { 00556 if (pkcs7->signedAttribsSz != 0) 00557 XFREE(flatSignedAttribs, 0, NULL); 00558 #ifdef WOLFSSL_SMALL_STACK 00559 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00560 #endif 00561 return result; 00562 } 00563 esd->encContentDigestSz = (word32)result; 00564 } 00565 signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz; 00566 00567 esd->signerDigestSz = SetOctetString(esd->encContentDigestSz, 00568 esd->signerDigest); 00569 signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz; 00570 00571 esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq); 00572 signerInfoSz += esd->signerInfoSeqSz; 00573 esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet); 00574 signerInfoSz += esd->signerInfoSetSz; 00575 00576 esd->certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz, 00577 esd->certsSet); 00578 00579 esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId, 00580 hashType, 0); 00581 esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet); 00582 00583 00584 esd->versionSz = SetMyVersion(1, esd->version, 0); 00585 00586 totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz + 00587 esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz + 00588 esd->innerOctetsSz + esd->innerContSeqSz + 00589 innerOidSz + pkcs7->contentSz + 00590 signerInfoSz; 00591 esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq); 00592 totalSz += esd->innerSeqSz; 00593 esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent); 00594 totalSz += esd->outerContentSz + outerOidSz; 00595 esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq); 00596 totalSz += esd->outerSeqSz; 00597 00598 if (outputSz < totalSz) { 00599 if (pkcs7->signedAttribsSz != 0) 00600 XFREE(flatSignedAttribs, 0, NULL); 00601 #ifdef WOLFSSL_SMALL_STACK 00602 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00603 #endif 00604 return BUFFER_E; 00605 } 00606 00607 idx = 0; 00608 XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz); 00609 idx += esd->outerSeqSz; 00610 XMEMCPY(output + idx, outerOid, outerOidSz); 00611 idx += outerOidSz; 00612 XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz); 00613 idx += esd->outerContentSz; 00614 XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz); 00615 idx += esd->innerSeqSz; 00616 XMEMCPY(output + idx, esd->version, esd->versionSz); 00617 idx += esd->versionSz; 00618 XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz); 00619 idx += esd->digAlgoIdSetSz; 00620 XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz); 00621 idx += esd->singleDigAlgoIdSz; 00622 XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz); 00623 idx += esd->contentInfoSeqSz; 00624 XMEMCPY(output + idx, innerOid, innerOidSz); 00625 idx += innerOidSz; 00626 XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz); 00627 idx += esd->innerContSeqSz; 00628 XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz); 00629 idx += esd->innerOctetsSz; 00630 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); 00631 idx += pkcs7->contentSz; 00632 XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz); 00633 idx += esd->certsSetSz; 00634 XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz); 00635 idx += pkcs7->singleCertSz; 00636 XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz); 00637 idx += esd->signerInfoSetSz; 00638 XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz); 00639 idx += esd->signerInfoSeqSz; 00640 XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz); 00641 idx += esd->signerVersionSz; 00642 XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz); 00643 idx += esd->issuerSnSeqSz; 00644 XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz); 00645 idx += esd->issuerNameSz; 00646 XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz); 00647 idx += pkcs7->issuerSz; 00648 XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz); 00649 idx += esd->issuerSnSz; 00650 XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz); 00651 idx += esd->signerDigAlgoIdSz; 00652 00653 /* SignerInfo:Attributes */ 00654 if (pkcs7->signedAttribsSz != 0) { 00655 XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz); 00656 idx += esd->signedAttribSetSz; 00657 XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz); 00658 idx += flatSignedAttribsSz; 00659 XFREE(flatSignedAttribs, 0, NULL); 00660 } 00661 00662 XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz); 00663 idx += esd->digEncAlgoIdSz; 00664 XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz); 00665 idx += esd->signerDigestSz; 00666 XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz); 00667 idx += esd->encContentDigestSz; 00668 00669 #ifdef WOLFSSL_SMALL_STACK 00670 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00671 #endif 00672 00673 return idx; 00674 } 00675 00676 00677 /* Finds the certificates in the message and saves it. */ 00678 int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) 00679 { 00680 word32 idx, contentType; 00681 int length, version, ret; 00682 byte* content = NULL; 00683 byte* sig = NULL; 00684 byte* cert = NULL; 00685 int contentSz = 0, sigSz = 0, certSz = 0; 00686 00687 if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0) 00688 return BAD_FUNC_ARG; 00689 00690 idx = 0; 00691 00692 /* Get the contentInfo sequence */ 00693 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00694 return ASN_PARSE_E; 00695 00696 /* Get the contentInfo contentType */ 00697 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) 00698 return ASN_PARSE_E; 00699 00700 if (contentType != SIGNED_DATA) { 00701 WOLFSSL_MSG("PKCS#7 input not of type SignedData"); 00702 return PKCS7_OID_E; 00703 } 00704 00705 /* get the ContentInfo content */ 00706 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) 00707 return ASN_PARSE_E; 00708 00709 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00710 return ASN_PARSE_E; 00711 00712 /* Get the signedData sequence */ 00713 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00714 return ASN_PARSE_E; 00715 00716 /* Get the version */ 00717 if (GetMyVersion(pkiMsg, &idx, &version) < 0) 00718 return ASN_PARSE_E; 00719 00720 if (version != 1) { 00721 WOLFSSL_MSG("PKCS#7 signedData needs to be of version 1"); 00722 return ASN_VERSION_E; 00723 } 00724 00725 /* Get the set of DigestAlgorithmIdentifiers */ 00726 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00727 return ASN_PARSE_E; 00728 00729 /* Skip the set. */ 00730 idx += length; 00731 00732 /* Get the inner ContentInfo sequence */ 00733 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00734 return ASN_PARSE_E; 00735 00736 /* Get the inner ContentInfo contentType */ 00737 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) 00738 return ASN_PARSE_E; 00739 00740 if (contentType != DATA) { 00741 WOLFSSL_MSG("PKCS#7 inner input not of type Data"); 00742 return PKCS7_OID_E; 00743 } 00744 00745 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) 00746 return ASN_PARSE_E; 00747 00748 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00749 return ASN_PARSE_E; 00750 00751 if (pkiMsg[idx++] != ASN_OCTET_STRING) 00752 return ASN_PARSE_E; 00753 00754 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00755 return ASN_PARSE_E; 00756 00757 /* Save the inner data as the content. */ 00758 if (length > 0) { 00759 /* Local pointer for calculating hashes later */ 00760 pkcs7->content = content = &pkiMsg[idx]; 00761 pkcs7->contentSz = contentSz = length; 00762 idx += length; 00763 } 00764 00765 /* Get the implicit[0] set of certificates */ 00766 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { 00767 idx++; 00768 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00769 return ASN_PARSE_E; 00770 00771 if (length > 0) { 00772 /* At this point, idx is at the first certificate in 00773 * a set of certificates. There may be more than one, 00774 * or none, or they may be a PKCS 6 extended 00775 * certificate. We want to save the first cert if it 00776 * is X.509. */ 00777 00778 word32 certIdx = idx; 00779 00780 if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) { 00781 if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0) 00782 return ASN_PARSE_E; 00783 00784 cert = &pkiMsg[idx]; 00785 certSz += (certIdx - idx); 00786 } 00787 wc_PKCS7_InitWithCert(pkcs7, cert, certSz); 00788 } 00789 idx += length; 00790 } 00791 00792 /* Get the implicit[1] set of crls */ 00793 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { 00794 idx++; 00795 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00796 return ASN_PARSE_E; 00797 00798 /* Skip the set */ 00799 idx += length; 00800 } 00801 00802 /* Get the set of signerInfos */ 00803 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00804 return ASN_PARSE_E; 00805 00806 if (length > 0) { 00807 /* Get the sequence of the first signerInfo */ 00808 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00809 return ASN_PARSE_E; 00810 00811 /* Get the version */ 00812 if (GetMyVersion(pkiMsg, &idx, &version) < 0) 00813 return ASN_PARSE_E; 00814 00815 if (version != 1) { 00816 WOLFSSL_MSG("PKCS#7 signerInfo needs to be of version 1"); 00817 return ASN_VERSION_E; 00818 } 00819 00820 /* Get the sequence of IssuerAndSerialNumber */ 00821 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00822 return ASN_PARSE_E; 00823 00824 /* Skip it */ 00825 idx += length; 00826 00827 /* Get the sequence of digestAlgorithm */ 00828 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00829 return ASN_PARSE_E; 00830 00831 /* Skip it */ 00832 idx += length; 00833 00834 /* Get the IMPLICIT[0] SET OF signedAttributes */ 00835 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { 00836 idx++; 00837 00838 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00839 return ASN_PARSE_E; 00840 00841 idx += length; 00842 } 00843 00844 /* Get the sequence of digestEncryptionAlgorithm */ 00845 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00846 return ASN_PARSE_E; 00847 00848 /* Skip it */ 00849 idx += length; 00850 00851 /* Get the signature */ 00852 if (pkiMsg[idx] == ASN_OCTET_STRING) { 00853 idx++; 00854 00855 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 00856 return ASN_PARSE_E; 00857 00858 /* save pointer and length */ 00859 sig = &pkiMsg[idx]; 00860 sigSz = length; 00861 00862 idx += length; 00863 } 00864 00865 pkcs7->content = content; 00866 pkcs7->contentSz = contentSz; 00867 00868 { 00869 word32 scratch = 0; 00870 int plainSz = 0; 00871 #define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ +\ 00872 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE) 00873 00874 #ifdef WOLFSSL_SMALL_STACK 00875 byte* digest; 00876 RsaKey* key; 00877 00878 digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, NULL, 00879 DYNAMIC_TYPE_TMP_BUFFER); 00880 00881 if (digest == NULL) 00882 return MEMORY_E; 00883 00884 key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, 00885 DYNAMIC_TYPE_TMP_BUFFER); 00886 if (key == NULL) { 00887 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00888 return MEMORY_E; 00889 } 00890 #else 00891 byte digest[MAX_PKCS7_DIGEST_SZ]; 00892 RsaKey stack_key; 00893 RsaKey* key = &stack_key; 00894 #endif 00895 00896 XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ); 00897 00898 ret = wc_InitRsaKey(key, NULL); 00899 if (ret != 0) { 00900 #ifdef WOLFSSL_SMALL_STACK 00901 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00902 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00903 #endif 00904 return ret; 00905 } 00906 if (wc_RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key, 00907 pkcs7->publicKeySz) < 0) { 00908 WOLFSSL_MSG("ASN RSA key decode error"); 00909 #ifdef WOLFSSL_SMALL_STACK 00910 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00911 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00912 #endif 00913 return PUBLIC_KEY_E; 00914 } 00915 00916 plainSz = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ, 00917 key); 00918 wc_FreeRsaKey(key); 00919 00920 #ifdef WOLFSSL_SMALL_STACK 00921 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00922 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00923 #endif 00924 00925 if (plainSz < 0) 00926 return plainSz; 00927 } 00928 } 00929 00930 return 0; 00931 } 00932 00933 00934 /* create ASN.1 formatted RecipientInfo structure, returns sequence size */ 00935 WOLFSSL_LOCAL int wc_CreateRecipientInfo(const byte* cert, word32 certSz, 00936 int keyEncAlgo, int blockKeySz, 00937 WC_RNG* rng, byte* contentKeyPlain, 00938 byte* contentKeyEnc, 00939 int* keyEncSz, byte* out, word32 outSz) 00940 { 00941 word32 idx = 0; 00942 int ret = 0, totalSz = 0; 00943 int verSz, issuerSz, snSz, keyEncAlgSz; 00944 int issuerSeqSz, recipSeqSz, issuerSerialSeqSz; 00945 int encKeyOctetStrSz; 00946 00947 byte ver[MAX_VERSION_SZ]; 00948 byte issuerSerialSeq[MAX_SEQ_SZ]; 00949 byte recipSeq[MAX_SEQ_SZ]; 00950 byte issuerSeq[MAX_SEQ_SZ]; 00951 byte encKeyOctetStr[MAX_OCTET_STR_SZ]; 00952 00953 #ifdef WOLFSSL_SMALL_STACK 00954 byte *serial; 00955 byte *keyAlgArray; 00956 00957 RsaKey* pubKey; 00958 DecodedCert* decoded; 00959 00960 serial = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00961 keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00962 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, 00963 DYNAMIC_TYPE_TMP_BUFFER); 00964 00965 if (decoded == NULL || serial == NULL || keyAlgArray == NULL) { 00966 if (serial) XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00967 if (keyAlgArray) XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00968 if (decoded) XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00969 return MEMORY_E; 00970 } 00971 00972 #else 00973 byte serial[MAX_SN_SZ]; 00974 byte keyAlgArray[MAX_ALGO_SZ]; 00975 00976 RsaKey stack_pubKey; 00977 RsaKey* pubKey = &stack_pubKey; 00978 DecodedCert stack_decoded; 00979 DecodedCert* decoded = &stack_decoded; 00980 #endif 00981 00982 InitDecodedCert(decoded, (byte*)cert, certSz, 0); 00983 ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0); 00984 if (ret < 0) { 00985 FreeDecodedCert(decoded); 00986 #ifdef WOLFSSL_SMALL_STACK 00987 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00988 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00989 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00990 #endif 00991 return ret; 00992 } 00993 00994 /* version */ 00995 verSz = SetMyVersion(0, ver, 0); 00996 00997 /* IssuerAndSerialNumber */ 00998 if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) { 00999 WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length"); 01000 FreeDecodedCert(decoded); 01001 #ifdef WOLFSSL_SMALL_STACK 01002 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01003 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01004 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01005 #endif 01006 return -1; 01007 } 01008 issuerSz = decoded->issuerRawLen; 01009 issuerSeqSz = SetSequence(issuerSz, issuerSeq); 01010 01011 if (decoded->serialSz == 0) { 01012 WOLFSSL_MSG("DecodedCert missing serial number"); 01013 FreeDecodedCert(decoded); 01014 #ifdef WOLFSSL_SMALL_STACK 01015 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01016 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01017 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01018 #endif 01019 return -1; 01020 } 01021 snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial); 01022 01023 issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz, 01024 issuerSerialSeq); 01025 01026 /* KeyEncryptionAlgorithmIdentifier, only support RSA now */ 01027 if (keyEncAlgo != RSAk) { 01028 FreeDecodedCert(decoded); 01029 #ifdef WOLFSSL_SMALL_STACK 01030 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01031 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01032 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01033 #endif 01034 return ALGO_ID_E; 01035 } 01036 01037 keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0); 01038 if (keyEncAlgSz == 0) { 01039 FreeDecodedCert(decoded); 01040 #ifdef WOLFSSL_SMALL_STACK 01041 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01042 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01043 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01044 #endif 01045 return BAD_FUNC_ARG; 01046 } 01047 01048 #ifdef WOLFSSL_SMALL_STACK 01049 pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); 01050 if (pubKey == NULL) { 01051 FreeDecodedCert(decoded); 01052 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01053 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01054 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01055 return MEMORY_E; 01056 } 01057 #endif 01058 01059 /* EncryptedKey */ 01060 ret = wc_InitRsaKey(pubKey, 0); 01061 if (ret != 0) { 01062 FreeDecodedCert(decoded); 01063 #ifdef WOLFSSL_SMALL_STACK 01064 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01065 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01066 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01067 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01068 #endif 01069 return ret; 01070 } 01071 01072 if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey, 01073 decoded->pubKeySize) < 0) { 01074 WOLFSSL_MSG("ASN RSA key decode error"); 01075 wc_FreeRsaKey(pubKey); 01076 FreeDecodedCert(decoded); 01077 #ifdef WOLFSSL_SMALL_STACK 01078 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01079 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01080 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01081 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01082 #endif 01083 return PUBLIC_KEY_E; 01084 } 01085 01086 *keyEncSz = wc_RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc, 01087 MAX_ENCRYPTED_KEY_SZ, pubKey, rng); 01088 wc_FreeRsaKey(pubKey); 01089 01090 #ifdef WOLFSSL_SMALL_STACK 01091 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01092 #endif 01093 01094 if (*keyEncSz < 0) { 01095 WOLFSSL_MSG("RSA Public Encrypt failed"); 01096 FreeDecodedCert(decoded); 01097 #ifdef WOLFSSL_SMALL_STACK 01098 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01099 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01100 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01101 #endif 01102 return *keyEncSz; 01103 } 01104 01105 encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr); 01106 01107 /* RecipientInfo */ 01108 recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz + 01109 issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz + 01110 *keyEncSz, recipSeq); 01111 01112 if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz + 01113 keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) { 01114 WOLFSSL_MSG("RecipientInfo output buffer too small"); 01115 FreeDecodedCert(decoded); 01116 #ifdef WOLFSSL_SMALL_STACK 01117 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01118 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01119 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01120 #endif 01121 return BUFFER_E; 01122 } 01123 01124 XMEMCPY(out + totalSz, recipSeq, recipSeqSz); 01125 totalSz += recipSeqSz; 01126 XMEMCPY(out + totalSz, ver, verSz); 01127 totalSz += verSz; 01128 XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz); 01129 totalSz += issuerSerialSeqSz; 01130 XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz); 01131 totalSz += issuerSeqSz; 01132 XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz); 01133 totalSz += issuerSz; 01134 XMEMCPY(out + totalSz, serial, snSz); 01135 totalSz += snSz; 01136 XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz); 01137 totalSz += keyEncAlgSz; 01138 XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz); 01139 totalSz += encKeyOctetStrSz; 01140 XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz); 01141 totalSz += *keyEncSz; 01142 01143 FreeDecodedCert(decoded); 01144 01145 #ifdef WOLFSSL_SMALL_STACK 01146 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01147 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01148 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01149 #endif 01150 01151 return totalSz; 01152 } 01153 01154 01155 /* build PKCS#7 envelopedData content type, return enveloped size */ 01156 int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) 01157 { 01158 int i, ret, idx = 0; 01159 int totalSz, padSz, desOutSz; 01160 01161 int contentInfoSeqSz, outerContentTypeSz, outerContentSz; 01162 byte contentInfoSeq[MAX_SEQ_SZ]; 01163 byte outerContentType[MAX_ALGO_SZ]; 01164 byte outerContent[MAX_SEQ_SZ]; 01165 01166 int envDataSeqSz, verSz; 01167 byte envDataSeq[MAX_SEQ_SZ]; 01168 byte ver[MAX_VERSION_SZ]; 01169 01170 WC_RNG rng; 01171 int contentKeyEncSz, blockKeySz; 01172 byte contentKeyPlain[MAX_CONTENT_KEY_LEN]; 01173 #ifdef WOLFSSL_SMALL_STACK 01174 byte* contentKeyEnc; 01175 #else 01176 byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ]; 01177 #endif 01178 byte* plain; 01179 byte* encryptedContent; 01180 01181 int recipSz, recipSetSz; 01182 #ifdef WOLFSSL_SMALL_STACK 01183 byte* recip; 01184 #else 01185 byte recip[MAX_RECIP_SZ]; 01186 #endif 01187 byte recipSet[MAX_SET_SZ]; 01188 01189 int encContentOctetSz, encContentSeqSz, contentTypeSz; 01190 int contentEncAlgoSz, ivOctetStringSz; 01191 byte encContentSeq[MAX_SEQ_SZ]; 01192 byte contentType[MAX_ALGO_SZ]; 01193 byte contentEncAlgo[MAX_ALGO_SZ]; 01194 byte tmpIv[DES_BLOCK_SIZE]; 01195 byte ivOctetString[MAX_OCTET_STR_SZ]; 01196 byte encContentOctet[MAX_OCTET_STR_SZ]; 01197 01198 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || 01199 pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL) 01200 return BAD_FUNC_ARG; 01201 01202 if (output == NULL || outputSz == 0) 01203 return BAD_FUNC_ARG; 01204 01205 /* PKCS#7 only supports DES, 3DES for now */ 01206 switch (pkcs7->encryptOID) { 01207 case DESb: 01208 blockKeySz = DES_KEYLEN; 01209 break; 01210 01211 case DES3b: 01212 blockKeySz = DES3_KEYLEN; 01213 break; 01214 01215 default: 01216 WOLFSSL_MSG("Unsupported content cipher type"); 01217 return ALGO_ID_E; 01218 }; 01219 01220 /* outer content type */ 01221 outerContentTypeSz = wc_SetContentType(ENVELOPED_DATA, outerContentType); 01222 01223 /* version, defined as 0 in RFC 2315 */ 01224 verSz = SetMyVersion(0, ver, 0); 01225 01226 /* generate random content encryption key */ 01227 ret = wc_InitRng(&rng); 01228 if (ret != 0) 01229 return ret; 01230 01231 ret = wc_RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz); 01232 if (ret != 0) { 01233 wc_FreeRng(&rng); 01234 return ret; 01235 } 01236 01237 #ifdef WOLFSSL_SMALL_STACK 01238 recip = (byte*)XMALLOC(MAX_RECIP_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01239 contentKeyEnc = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL, 01240 DYNAMIC_TYPE_TMP_BUFFER); 01241 if (contentKeyEnc == NULL || recip == NULL) { 01242 if (recip) XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01243 if (contentKeyEnc) XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01244 wc_FreeRng(&rng); 01245 return MEMORY_E; 01246 } 01247 01248 #endif 01249 01250 /* build RecipientInfo, only handle 1 for now */ 01251 recipSz = wc_CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk, 01252 blockKeySz, &rng, contentKeyPlain, 01253 contentKeyEnc, &contentKeyEncSz, recip, 01254 MAX_RECIP_SZ); 01255 01256 ForceZero(contentKeyEnc, MAX_ENCRYPTED_KEY_SZ); 01257 01258 #ifdef WOLFSSL_SMALL_STACK 01259 XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01260 #endif 01261 01262 if (recipSz < 0) { 01263 WOLFSSL_MSG("Failed to create RecipientInfo"); 01264 wc_FreeRng(&rng); 01265 #ifdef WOLFSSL_SMALL_STACK 01266 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01267 #endif 01268 return recipSz; 01269 } 01270 recipSetSz = SetSet(recipSz, recipSet); 01271 01272 /* generate IV for block cipher */ 01273 ret = wc_RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE); 01274 wc_FreeRng(&rng); 01275 if (ret != 0) { 01276 #ifdef WOLFSSL_SMALL_STACK 01277 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01278 #endif 01279 return ret; 01280 } 01281 01282 /* EncryptedContentInfo */ 01283 contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType); 01284 if (contentTypeSz == 0) { 01285 #ifdef WOLFSSL_SMALL_STACK 01286 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01287 #endif 01288 return BAD_FUNC_ARG; 01289 } 01290 01291 /* allocate encrypted content buffer and PKCS#7 padding */ 01292 padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE); 01293 desOutSz = pkcs7->contentSz + padSz; 01294 01295 plain = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01296 if (plain == NULL) { 01297 #ifdef WOLFSSL_SMALL_STACK 01298 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01299 #endif 01300 return MEMORY_E; 01301 } 01302 XMEMCPY(plain, pkcs7->content, pkcs7->contentSz); 01303 01304 for (i = 0; i < padSz; i++) { 01305 plain[pkcs7->contentSz + i] = (byte)padSz; 01306 } 01307 01308 encryptedContent = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01309 if (encryptedContent == NULL) { 01310 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01311 #ifdef WOLFSSL_SMALL_STACK 01312 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01313 #endif 01314 return MEMORY_E; 01315 } 01316 01317 /* put together IV OCTET STRING */ 01318 ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString); 01319 01320 /* build up our ContentEncryptionAlgorithmIdentifier sequence, 01321 * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */ 01322 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo, 01323 blkType, ivOctetStringSz + DES_BLOCK_SIZE); 01324 01325 if (contentEncAlgoSz == 0) { 01326 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01327 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01328 #ifdef WOLFSSL_SMALL_STACK 01329 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01330 #endif 01331 return BAD_FUNC_ARG; 01332 } 01333 01334 /* encrypt content */ 01335 if (pkcs7->encryptOID == DESb) { 01336 Des des; 01337 01338 ret = wc_Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION); 01339 01340 if (ret == 0) 01341 wc_Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz); 01342 01343 if (ret != 0) { 01344 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01345 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01346 #ifdef WOLFSSL_SMALL_STACK 01347 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01348 #endif 01349 return ret; 01350 } 01351 } 01352 else if (pkcs7->encryptOID == DES3b) { 01353 Des3 des3; 01354 01355 ret = wc_Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION); 01356 01357 if (ret == 0) 01358 ret = wc_Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz); 01359 01360 if (ret != 0) { 01361 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01362 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01363 #ifdef WOLFSSL_SMALL_STACK 01364 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01365 #endif 01366 return ret; 01367 } 01368 } 01369 01370 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, 01371 desOutSz, encContentOctet); 01372 01373 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + 01374 ivOctetStringSz + DES_BLOCK_SIZE + 01375 encContentOctetSz + desOutSz, encContentSeq); 01376 01377 /* keep track of sizes for outer wrapper layering */ 01378 totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + 01379 contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE + 01380 encContentOctetSz + desOutSz; 01381 01382 /* EnvelopedData */ 01383 envDataSeqSz = SetSequence(totalSz, envDataSeq); 01384 totalSz += envDataSeqSz; 01385 01386 /* outer content */ 01387 outerContentSz = SetExplicit(0, totalSz, outerContent); 01388 totalSz += outerContentTypeSz; 01389 totalSz += outerContentSz; 01390 01391 /* ContentInfo */ 01392 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); 01393 totalSz += contentInfoSeqSz; 01394 01395 if (totalSz > (int)outputSz) { 01396 WOLFSSL_MSG("Pkcs7_encrypt output buffer too small"); 01397 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01398 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01399 #ifdef WOLFSSL_SMALL_STACK 01400 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01401 #endif 01402 return BUFFER_E; 01403 } 01404 01405 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz); 01406 idx += contentInfoSeqSz; 01407 XMEMCPY(output + idx, outerContentType, outerContentTypeSz); 01408 idx += outerContentTypeSz; 01409 XMEMCPY(output + idx, outerContent, outerContentSz); 01410 idx += outerContentSz; 01411 XMEMCPY(output + idx, envDataSeq, envDataSeqSz); 01412 idx += envDataSeqSz; 01413 XMEMCPY(output + idx, ver, verSz); 01414 idx += verSz; 01415 XMEMCPY(output + idx, recipSet, recipSetSz); 01416 idx += recipSetSz; 01417 XMEMCPY(output + idx, recip, recipSz); 01418 idx += recipSz; 01419 XMEMCPY(output + idx, encContentSeq, encContentSeqSz); 01420 idx += encContentSeqSz; 01421 XMEMCPY(output + idx, contentType, contentTypeSz); 01422 idx += contentTypeSz; 01423 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz); 01424 idx += contentEncAlgoSz; 01425 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz); 01426 idx += ivOctetStringSz; 01427 XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE); 01428 idx += DES_BLOCK_SIZE; 01429 XMEMCPY(output + idx, encContentOctet, encContentOctetSz); 01430 idx += encContentOctetSz; 01431 XMEMCPY(output + idx, encryptedContent, desOutSz); 01432 idx += desOutSz; 01433 01434 ForceZero(contentKeyPlain, MAX_CONTENT_KEY_LEN); 01435 01436 XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01437 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01438 01439 #ifdef WOLFSSL_SMALL_STACK 01440 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); 01441 #endif 01442 01443 return idx; 01444 } 01445 01446 /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */ 01447 WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, 01448 word32 pkiMsgSz, byte* output, 01449 word32 outputSz) 01450 { 01451 int recipFound = 0; 01452 int ret, version, length; 01453 word32 savedIdx = 0, idx = 0; 01454 word32 contentType, encOID; 01455 byte issuerHash[SHA_DIGEST_SIZE]; 01456 01457 int encryptedKeySz, keySz; 01458 byte tmpIv[DES_BLOCK_SIZE]; 01459 byte* decryptedKey = NULL; 01460 01461 #ifdef WOLFSSL_SMALL_STACK 01462 mp_int* serialNum; 01463 byte* encryptedKey; 01464 RsaKey* privKey; 01465 #else 01466 mp_int stack_serialNum; 01467 mp_int* serialNum = &stack_serialNum; 01468 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ]; 01469 01470 RsaKey stack_privKey; 01471 RsaKey* privKey = &stack_privKey; 01472 #endif 01473 int encryptedContentSz; 01474 byte padLen; 01475 byte* encryptedContent = NULL; 01476 01477 if (pkcs7 == NULL || pkcs7->singleCert == NULL || 01478 pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL || 01479 pkcs7->privateKeySz == 0) 01480 return BAD_FUNC_ARG; 01481 01482 if (pkiMsg == NULL || pkiMsgSz == 0 || 01483 output == NULL || outputSz == 0) 01484 return BAD_FUNC_ARG; 01485 01486 /* read past ContentInfo, verify type is envelopedData */ 01487 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 01488 return ASN_PARSE_E; 01489 01490 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) 01491 return ASN_PARSE_E; 01492 01493 if (contentType != ENVELOPED_DATA) { 01494 WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData"); 01495 return PKCS7_OID_E; 01496 } 01497 01498 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) 01499 return ASN_PARSE_E; 01500 01501 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) 01502 return ASN_PARSE_E; 01503 01504 /* remove EnvelopedData and version */ 01505 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) 01506 return ASN_PARSE_E; 01507 01508 if (GetMyVersion(pkiMsg, &idx, &version) < 0) 01509 return ASN_PARSE_E; 01510 01511 if (version != 0) { 01512 WOLFSSL_MSG("PKCS#7 envelopedData needs to be of version 0"); 01513 return ASN_VERSION_E; 01514 } 01515 01516 /* walk through RecipientInfo set, find correct recipient */ 01517 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) 01518 return ASN_PARSE_E; 01519 01520 #ifdef WOLFSSL_SMALL_STACK 01521 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL, 01522 DYNAMIC_TYPE_TMP_BUFFER); 01523 if (encryptedKey == NULL) 01524 return MEMORY_E; 01525 #endif 01526 01527 savedIdx = idx; 01528 recipFound = 0; 01529 01530 /* when looking for next recipient, use first sequence and version to 01531 * indicate there is another, if not, move on */ 01532 while(recipFound == 0) { 01533 01534 /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to 01535 * last good saved one */ 01536 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { 01537 idx = savedIdx; 01538 break; 01539 } 01540 01541 if (GetMyVersion(pkiMsg, &idx, &version) < 0) { 01542 idx = savedIdx; 01543 break; 01544 } 01545 01546 if (version != 0) { 01547 #ifdef WOLFSSL_SMALL_STACK 01548 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01549 #endif 01550 return ASN_VERSION_E; 01551 } 01552 01553 /* remove IssuerAndSerialNumber */ 01554 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { 01555 #ifdef WOLFSSL_SMALL_STACK 01556 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01557 #endif 01558 return ASN_PARSE_E; 01559 } 01560 01561 if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) { 01562 #ifdef WOLFSSL_SMALL_STACK 01563 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01564 #endif 01565 return ASN_PARSE_E; 01566 } 01567 01568 /* if we found correct recipient, issuer hashes will match */ 01569 if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) { 01570 recipFound = 1; 01571 } 01572 01573 #ifdef WOLFSSL_SMALL_STACK 01574 serialNum = (mp_int*)XMALLOC(sizeof(mp_int), NULL, 01575 DYNAMIC_TYPE_TMP_BUFFER); 01576 if (serialNum == NULL) { 01577 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01578 return MEMORY_E; 01579 } 01580 #endif 01581 01582 if (GetInt(serialNum, pkiMsg, &idx, pkiMsgSz) < 0) { 01583 #ifdef WOLFSSL_SMALL_STACK 01584 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01585 XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01586 #endif 01587 return ASN_PARSE_E; 01588 } 01589 01590 mp_clear(serialNum); 01591 01592 #ifdef WOLFSSL_SMALL_STACK 01593 XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01594 #endif 01595 01596 if (GetAlgoId(pkiMsg, &idx, &encOID, keyType, pkiMsgSz) < 0) { 01597 #ifdef WOLFSSL_SMALL_STACK 01598 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01599 #endif 01600 return ASN_PARSE_E; 01601 } 01602 01603 /* key encryption algorithm must be RSA for now */ 01604 if (encOID != RSAk) { 01605 #ifdef WOLFSSL_SMALL_STACK 01606 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01607 #endif 01608 return ALGO_ID_E; 01609 } 01610 01611 /* read encryptedKey */ 01612 if (pkiMsg[idx++] != ASN_OCTET_STRING) { 01613 #ifdef WOLFSSL_SMALL_STACK 01614 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01615 #endif 01616 return ASN_PARSE_E; 01617 } 01618 01619 if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) { 01620 #ifdef WOLFSSL_SMALL_STACK 01621 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01622 #endif 01623 return ASN_PARSE_E; 01624 } 01625 01626 if (recipFound == 1) 01627 XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz); 01628 idx += encryptedKeySz; 01629 01630 /* update good idx */ 01631 savedIdx = idx; 01632 } 01633 01634 if (recipFound == 0) { 01635 WOLFSSL_MSG("No recipient found in envelopedData that matches input"); 01636 #ifdef WOLFSSL_SMALL_STACK 01637 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01638 #endif 01639 return PKCS7_RECIP_E; 01640 } 01641 01642 /* remove EncryptedContentInfo */ 01643 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { 01644 #ifdef WOLFSSL_SMALL_STACK 01645 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01646 #endif 01647 return ASN_PARSE_E; 01648 } 01649 01650 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) { 01651 #ifdef WOLFSSL_SMALL_STACK 01652 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01653 #endif 01654 return ASN_PARSE_E; 01655 } 01656 01657 if (GetAlgoId(pkiMsg, &idx, &encOID, blkType, pkiMsgSz) < 0) { 01658 #ifdef WOLFSSL_SMALL_STACK 01659 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01660 #endif 01661 return ASN_PARSE_E; 01662 } 01663 01664 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */ 01665 if (pkiMsg[idx++] != ASN_OCTET_STRING) { 01666 #ifdef WOLFSSL_SMALL_STACK 01667 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01668 #endif 01669 return ASN_PARSE_E; 01670 } 01671 01672 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) { 01673 #ifdef WOLFSSL_SMALL_STACK 01674 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01675 #endif 01676 return ASN_PARSE_E; 01677 } 01678 01679 if (length != DES_BLOCK_SIZE) { 01680 WOLFSSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE"); 01681 #ifdef WOLFSSL_SMALL_STACK 01682 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01683 #endif 01684 return ASN_PARSE_E; 01685 } 01686 01687 XMEMCPY(tmpIv, &pkiMsg[idx], length); 01688 idx += length; 01689 01690 /* read encryptedContent, cont[0] */ 01691 if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { 01692 #ifdef WOLFSSL_SMALL_STACK 01693 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01694 #endif 01695 return ASN_PARSE_E; 01696 } 01697 01698 if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) { 01699 #ifdef WOLFSSL_SMALL_STACK 01700 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01701 #endif 01702 return ASN_PARSE_E; 01703 } 01704 01705 encryptedContent = (byte*)XMALLOC(encryptedContentSz, NULL, 01706 DYNAMIC_TYPE_TMP_BUFFER); 01707 if (encryptedContent == NULL) { 01708 #ifdef WOLFSSL_SMALL_STACK 01709 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01710 #endif 01711 return MEMORY_E; 01712 } 01713 01714 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz); 01715 01716 /* load private key */ 01717 #ifdef WOLFSSL_SMALL_STACK 01718 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); 01719 if (privKey == NULL) { 01720 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01721 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; 01722 } 01723 #endif 01724 01725 ret = wc_InitRsaKey(privKey, 0); 01726 if (ret != 0) { 01727 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01728 #ifdef WOLFSSL_SMALL_STACK 01729 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01730 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01731 #endif 01732 return ret; 01733 } 01734 01735 idx = 0; 01736 01737 ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey, 01738 pkcs7->privateKeySz); 01739 if (ret != 0) { 01740 WOLFSSL_MSG("Failed to decode RSA private key"); 01741 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01742 #ifdef WOLFSSL_SMALL_STACK 01743 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01744 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01745 #endif 01746 return ret; 01747 } 01748 01749 /* decrypt encryptedKey */ 01750 keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz, 01751 &decryptedKey, privKey); 01752 wc_FreeRsaKey(privKey); 01753 01754 #ifdef WOLFSSL_SMALL_STACK 01755 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01756 #endif 01757 01758 if (keySz <= 0) { 01759 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01760 #ifdef WOLFSSL_SMALL_STACK 01761 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01762 #endif 01763 return keySz; 01764 } 01765 01766 /* decrypt encryptedContent */ 01767 if (encOID == DESb) { 01768 Des des; 01769 ret = wc_Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); 01770 01771 if (ret == 0) 01772 wc_Des_CbcDecrypt(&des, encryptedContent, encryptedContent, 01773 encryptedContentSz); 01774 01775 if (ret != 0) { 01776 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01777 #ifdef WOLFSSL_SMALL_STACK 01778 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01779 #endif 01780 return ret; 01781 } 01782 } 01783 else if (encOID == DES3b) { 01784 Des3 des; 01785 ret = wc_Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); 01786 if (ret == 0) 01787 ret = wc_Des3_CbcDecrypt(&des, encryptedContent, encryptedContent, 01788 encryptedContentSz); 01789 01790 if (ret != 0) { 01791 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01792 #ifdef WOLFSSL_SMALL_STACK 01793 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01794 #endif 01795 return ret; 01796 } 01797 } else { 01798 WOLFSSL_MSG("Unsupported content encryption OID type"); 01799 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01800 #ifdef WOLFSSL_SMALL_STACK 01801 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01802 #endif 01803 return ALGO_ID_E; 01804 } 01805 01806 padLen = encryptedContent[encryptedContentSz-1]; 01807 01808 /* copy plaintext to output */ 01809 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen); 01810 01811 /* free memory, zero out keys */ 01812 ForceZero(encryptedKey, MAX_ENCRYPTED_KEY_SZ); 01813 ForceZero(encryptedContent, encryptedContentSz); 01814 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01815 #ifdef WOLFSSL_SMALL_STACK 01816 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01817 #endif 01818 01819 return encryptedContentSz - padLen; 01820 } 01821 01822 01823 #else /* HAVE_PKCS7 */ 01824 01825 01826 #ifdef _MSC_VER 01827 /* 4206 warning for blank file */ 01828 #pragma warning(disable: 4206) 01829 #endif 01830 01831 01832 #endif /* HAVE_PKCS7 */ 01833 01834
Generated on Tue Jul 12 2022 15:55:20 by
1.7.2