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