A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* pkcs7.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 */
Vanger 0:b86d15c6ba29 21
Vanger 0:b86d15c6ba29 22 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 23 #include <config.h>
Vanger 0:b86d15c6ba29 24 #endif
Vanger 0:b86d15c6ba29 25
Vanger 0:b86d15c6ba29 26 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 27
Vanger 0:b86d15c6ba29 28 #ifdef HAVE_PKCS7
Vanger 0:b86d15c6ba29 29
Vanger 0:b86d15c6ba29 30 #include <cyassl/ctaocrypt/pkcs7.h>
Vanger 0:b86d15c6ba29 31 #include <cyassl/ctaocrypt/error-crypt.h>
Vanger 0:b86d15c6ba29 32 #include <cyassl/ctaocrypt/logging.h>
Vanger 0:b86d15c6ba29 33
Vanger 0:b86d15c6ba29 34 #ifndef min
Vanger 0:b86d15c6ba29 35 static INLINE word32 min(word32 a, word32 b)
Vanger 0:b86d15c6ba29 36 {
Vanger 0:b86d15c6ba29 37 return a > b ? b : a;
Vanger 0:b86d15c6ba29 38 }
Vanger 0:b86d15c6ba29 39 #endif
Vanger 0:b86d15c6ba29 40
Vanger 0:b86d15c6ba29 41
Vanger 0:b86d15c6ba29 42 /* placed ASN.1 contentType OID into *output, return idx on success,
Vanger 0:b86d15c6ba29 43 * 0 upon failure */
Vanger 0:b86d15c6ba29 44 CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output)
Vanger 0:b86d15c6ba29 45 {
Vanger 0:b86d15c6ba29 46 /* PKCS#7 content types, RFC 2315, section 14 */
Vanger 0:b86d15c6ba29 47 static const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 48 0x0D, 0x01, 0x07 };
Vanger 0:b86d15c6ba29 49 static const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 50 0x0D, 0x01, 0x07, 0x01 };
Vanger 0:b86d15c6ba29 51 static const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 52 0x0D, 0x01, 0x07, 0x02};
Vanger 0:b86d15c6ba29 53 static const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 54 0x0D, 0x01, 0x07, 0x03 };
Vanger 0:b86d15c6ba29 55 static const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 56 0x0D, 0x01, 0x07, 0x04 };
Vanger 0:b86d15c6ba29 57 static const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 58 0x0D, 0x01, 0x07, 0x05 };
Vanger 0:b86d15c6ba29 59 static const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 60 0x0D, 0x01, 0x07, 0x06 };
Vanger 0:b86d15c6ba29 61
Vanger 0:b86d15c6ba29 62 int idSz;
Vanger 0:b86d15c6ba29 63 int typeSz = 0, idx = 0;
Vanger 0:b86d15c6ba29 64 const byte* typeName = 0;
Vanger 0:b86d15c6ba29 65 byte ID_Length[MAX_LENGTH_SZ];
Vanger 0:b86d15c6ba29 66
Vanger 0:b86d15c6ba29 67 switch (pkcs7TypeOID) {
Vanger 0:b86d15c6ba29 68 case PKCS7_MSG:
Vanger 0:b86d15c6ba29 69 typeSz = sizeof(pkcs7);
Vanger 0:b86d15c6ba29 70 typeName = pkcs7;
Vanger 0:b86d15c6ba29 71 break;
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73 case DATA:
Vanger 0:b86d15c6ba29 74 typeSz = sizeof(data);
Vanger 0:b86d15c6ba29 75 typeName = data;
Vanger 0:b86d15c6ba29 76 break;
Vanger 0:b86d15c6ba29 77
Vanger 0:b86d15c6ba29 78 case SIGNED_DATA:
Vanger 0:b86d15c6ba29 79 typeSz = sizeof(signedData);
Vanger 0:b86d15c6ba29 80 typeName = signedData;
Vanger 0:b86d15c6ba29 81 break;
Vanger 0:b86d15c6ba29 82
Vanger 0:b86d15c6ba29 83 case ENVELOPED_DATA:
Vanger 0:b86d15c6ba29 84 typeSz = sizeof(envelopedData);
Vanger 0:b86d15c6ba29 85 typeName = envelopedData;
Vanger 0:b86d15c6ba29 86 break;
Vanger 0:b86d15c6ba29 87
Vanger 0:b86d15c6ba29 88 case SIGNED_AND_ENVELOPED_DATA:
Vanger 0:b86d15c6ba29 89 typeSz = sizeof(signedAndEnveloped);
Vanger 0:b86d15c6ba29 90 typeName = signedAndEnveloped;
Vanger 0:b86d15c6ba29 91 break;
Vanger 0:b86d15c6ba29 92
Vanger 0:b86d15c6ba29 93 case DIGESTED_DATA:
Vanger 0:b86d15c6ba29 94 typeSz = sizeof(digestedData);
Vanger 0:b86d15c6ba29 95 typeName = digestedData;
Vanger 0:b86d15c6ba29 96 break;
Vanger 0:b86d15c6ba29 97
Vanger 0:b86d15c6ba29 98 case ENCRYPTED_DATA:
Vanger 0:b86d15c6ba29 99 typeSz = sizeof(encryptedData);
Vanger 0:b86d15c6ba29 100 typeName = encryptedData;
Vanger 0:b86d15c6ba29 101 break;
Vanger 0:b86d15c6ba29 102
Vanger 0:b86d15c6ba29 103 default:
Vanger 0:b86d15c6ba29 104 CYASSL_MSG("Unknown PKCS#7 Type");
Vanger 0:b86d15c6ba29 105 return 0;
Vanger 0:b86d15c6ba29 106 };
Vanger 0:b86d15c6ba29 107
Vanger 0:b86d15c6ba29 108 idSz = SetLength(typeSz, ID_Length);
Vanger 0:b86d15c6ba29 109 output[idx++] = ASN_OBJECT_ID;
Vanger 0:b86d15c6ba29 110 XMEMCPY(output + idx, ID_Length, idSz);
Vanger 0:b86d15c6ba29 111 idx += idSz;
Vanger 0:b86d15c6ba29 112 XMEMCPY(output + idx, typeName, typeSz);
Vanger 0:b86d15c6ba29 113 idx += typeSz;
Vanger 0:b86d15c6ba29 114
Vanger 0:b86d15c6ba29 115 return idx;
Vanger 0:b86d15c6ba29 116
Vanger 0:b86d15c6ba29 117 }
Vanger 0:b86d15c6ba29 118
Vanger 0:b86d15c6ba29 119
Vanger 0:b86d15c6ba29 120 /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
Vanger 0:b86d15c6ba29 121 int GetContentType(const byte* input, word32* inOutIdx, word32* oid,
Vanger 0:b86d15c6ba29 122 word32 maxIdx)
Vanger 0:b86d15c6ba29 123 {
Vanger 0:b86d15c6ba29 124 int length;
Vanger 0:b86d15c6ba29 125 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 126 byte b;
Vanger 0:b86d15c6ba29 127 *oid = 0;
Vanger 0:b86d15c6ba29 128
Vanger 0:b86d15c6ba29 129 CYASSL_ENTER("GetContentType");
Vanger 0:b86d15c6ba29 130
Vanger 0:b86d15c6ba29 131 b = input[i++];
Vanger 0:b86d15c6ba29 132 if (b != ASN_OBJECT_ID)
Vanger 0:b86d15c6ba29 133 return ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 134
Vanger 0:b86d15c6ba29 135 if (GetLength(input, &i, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 136 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 137
Vanger 0:b86d15c6ba29 138 while(length--) {
Vanger 0:b86d15c6ba29 139 *oid += input[i];
Vanger 0:b86d15c6ba29 140 i++;
Vanger 0:b86d15c6ba29 141 }
Vanger 0:b86d15c6ba29 142
Vanger 0:b86d15c6ba29 143 *inOutIdx = i;
Vanger 0:b86d15c6ba29 144
Vanger 0:b86d15c6ba29 145 return 0;
Vanger 0:b86d15c6ba29 146 }
Vanger 0:b86d15c6ba29 147
Vanger 0:b86d15c6ba29 148
Vanger 0:b86d15c6ba29 149 /* init PKCS7 struct with recipient cert, decode into DecodedCert */
Vanger 0:b86d15c6ba29 150 int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
Vanger 0:b86d15c6ba29 151 {
Vanger 0:b86d15c6ba29 152 int ret = 0;
Vanger 0:b86d15c6ba29 153
Vanger 0:b86d15c6ba29 154 XMEMSET(pkcs7, 0, sizeof(PKCS7));
Vanger 0:b86d15c6ba29 155 if (cert != NULL && certSz > 0) {
Vanger 0:b86d15c6ba29 156 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 157 DecodedCert* dCert;
Vanger 0:b86d15c6ba29 158
Vanger 0:b86d15c6ba29 159 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
Vanger 0:b86d15c6ba29 160 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 161 if (dCert == NULL)
Vanger 0:b86d15c6ba29 162 return MEMORY_E;
Vanger 0:b86d15c6ba29 163 #else
Vanger 0:b86d15c6ba29 164 DecodedCert stack_dCert;
Vanger 0:b86d15c6ba29 165 DecodedCert* dCert = &stack_dCert;
Vanger 0:b86d15c6ba29 166 #endif
Vanger 0:b86d15c6ba29 167
Vanger 0:b86d15c6ba29 168 pkcs7->singleCert = cert;
Vanger 0:b86d15c6ba29 169 pkcs7->singleCertSz = certSz;
Vanger 0:b86d15c6ba29 170 InitDecodedCert(dCert, cert, certSz, 0);
Vanger 0:b86d15c6ba29 171
Vanger 0:b86d15c6ba29 172 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
Vanger 0:b86d15c6ba29 173 if (ret < 0) {
Vanger 0:b86d15c6ba29 174 FreeDecodedCert(dCert);
Vanger 0:b86d15c6ba29 175 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 176 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 177 #endif
Vanger 0:b86d15c6ba29 178 return ret;
Vanger 0:b86d15c6ba29 179 }
Vanger 0:b86d15c6ba29 180
Vanger 0:b86d15c6ba29 181 XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
Vanger 0:b86d15c6ba29 182 pkcs7->publicKeySz = dCert->pubKeySize;
Vanger 0:b86d15c6ba29 183 XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, SHA_SIZE);
Vanger 0:b86d15c6ba29 184 pkcs7->issuer = dCert->issuerRaw;
Vanger 0:b86d15c6ba29 185 pkcs7->issuerSz = dCert->issuerRawLen;
Vanger 0:b86d15c6ba29 186 XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
Vanger 0:b86d15c6ba29 187 pkcs7->issuerSnSz = dCert->serialSz;
Vanger 0:b86d15c6ba29 188 FreeDecodedCert(dCert);
Vanger 0:b86d15c6ba29 189
Vanger 0:b86d15c6ba29 190 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 191 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 192 #endif
Vanger 0:b86d15c6ba29 193 }
Vanger 0:b86d15c6ba29 194
Vanger 0:b86d15c6ba29 195 return ret;
Vanger 0:b86d15c6ba29 196 }
Vanger 0:b86d15c6ba29 197
Vanger 0:b86d15c6ba29 198
Vanger 0:b86d15c6ba29 199 /* releases any memory allocated by a PKCS7 initializer */
Vanger 0:b86d15c6ba29 200 void PKCS7_Free(PKCS7* pkcs7)
Vanger 0:b86d15c6ba29 201 {
Vanger 0:b86d15c6ba29 202 (void)pkcs7;
Vanger 0:b86d15c6ba29 203 }
Vanger 0:b86d15c6ba29 204
Vanger 0:b86d15c6ba29 205
Vanger 0:b86d15c6ba29 206 /* build PKCS#7 data content type */
Vanger 0:b86d15c6ba29 207 int PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
Vanger 0:b86d15c6ba29 208 {
Vanger 0:b86d15c6ba29 209 static const byte oid[] =
Vanger 0:b86d15c6ba29 210 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
Vanger 0:b86d15c6ba29 211 0x07, 0x01 };
Vanger 0:b86d15c6ba29 212 byte seq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 213 byte octetStr[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 214 word32 seqSz;
Vanger 0:b86d15c6ba29 215 word32 octetStrSz;
Vanger 0:b86d15c6ba29 216 word32 oidSz = (word32)sizeof(oid);
Vanger 0:b86d15c6ba29 217 int idx = 0;
Vanger 0:b86d15c6ba29 218
Vanger 0:b86d15c6ba29 219 octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
Vanger 0:b86d15c6ba29 220 seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
Vanger 0:b86d15c6ba29 221
Vanger 0:b86d15c6ba29 222 if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
Vanger 0:b86d15c6ba29 223 return BUFFER_E;
Vanger 0:b86d15c6ba29 224
Vanger 0:b86d15c6ba29 225 XMEMCPY(output, seq, seqSz);
Vanger 0:b86d15c6ba29 226 idx += seqSz;
Vanger 0:b86d15c6ba29 227 XMEMCPY(output + idx, oid, oidSz);
Vanger 0:b86d15c6ba29 228 idx += oidSz;
Vanger 0:b86d15c6ba29 229 XMEMCPY(output + idx, octetStr, octetStrSz);
Vanger 0:b86d15c6ba29 230 idx += octetStrSz;
Vanger 0:b86d15c6ba29 231 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
Vanger 0:b86d15c6ba29 232 idx += pkcs7->contentSz;
Vanger 0:b86d15c6ba29 233
Vanger 0:b86d15c6ba29 234 return idx;
Vanger 0:b86d15c6ba29 235 }
Vanger 0:b86d15c6ba29 236
Vanger 0:b86d15c6ba29 237
Vanger 0:b86d15c6ba29 238 typedef struct EncodedAttrib {
Vanger 0:b86d15c6ba29 239 byte valueSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 240 const byte* oid;
Vanger 0:b86d15c6ba29 241 byte valueSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 242 const byte* value;
Vanger 0:b86d15c6ba29 243 word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
Vanger 0:b86d15c6ba29 244 } EncodedAttrib;
Vanger 0:b86d15c6ba29 245
Vanger 0:b86d15c6ba29 246
Vanger 0:b86d15c6ba29 247 typedef struct ESD {
Vanger 0:b86d15c6ba29 248 Sha sha;
Vanger 0:b86d15c6ba29 249 byte contentDigest[SHA_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
Vanger 0:b86d15c6ba29 250 byte contentAttribsDigest[SHA_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 251 byte encContentDigest[512];
Vanger 0:b86d15c6ba29 252
Vanger 0:b86d15c6ba29 253 byte outerSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 254 byte outerContent[MAX_EXP_SZ];
Vanger 0:b86d15c6ba29 255 byte innerSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 256 byte version[MAX_VERSION_SZ];
Vanger 0:b86d15c6ba29 257 byte digAlgoIdSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 258 byte singleDigAlgoId[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 259
Vanger 0:b86d15c6ba29 260 byte contentInfoSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 261 byte innerContSeq[MAX_EXP_SZ];
Vanger 0:b86d15c6ba29 262 byte innerOctets[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 263
Vanger 0:b86d15c6ba29 264 byte certsSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 265
Vanger 0:b86d15c6ba29 266 byte signerInfoSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 267 byte signerInfoSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 268 byte signerVersion[MAX_VERSION_SZ];
Vanger 0:b86d15c6ba29 269 byte issuerSnSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 270 byte issuerName[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 271 byte issuerSn[MAX_SN_SZ];
Vanger 0:b86d15c6ba29 272 byte signerDigAlgoId[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 273 byte digEncAlgoId[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 274 byte signedAttribSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 275 EncodedAttrib signedAttribs[6];
Vanger 0:b86d15c6ba29 276 byte signerDigest[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 277 word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
Vanger 0:b86d15c6ba29 278 word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
Vanger 0:b86d15c6ba29 279 singleDigAlgoIdSz, certsSetSz;
Vanger 0:b86d15c6ba29 280 word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
Vanger 0:b86d15c6ba29 281 issuerSnSeqSz, issuerNameSz, issuerSnSz,
Vanger 0:b86d15c6ba29 282 signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
Vanger 0:b86d15c6ba29 283 word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
Vanger 0:b86d15c6ba29 284 signedAttribSetSz;
Vanger 0:b86d15c6ba29 285 } ESD;
Vanger 0:b86d15c6ba29 286
Vanger 0:b86d15c6ba29 287
Vanger 0:b86d15c6ba29 288 static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
Vanger 0:b86d15c6ba29 289 PKCS7Attrib* attribs, int attribsSz)
Vanger 0:b86d15c6ba29 290 {
Vanger 0:b86d15c6ba29 291 int i;
Vanger 0:b86d15c6ba29 292 int maxSz = min(eaSz, attribsSz);
Vanger 0:b86d15c6ba29 293 int allAttribsSz = 0;
Vanger 0:b86d15c6ba29 294
Vanger 0:b86d15c6ba29 295 for (i = 0; i < maxSz; i++)
Vanger 0:b86d15c6ba29 296 {
Vanger 0:b86d15c6ba29 297 int attribSz = 0;
Vanger 0:b86d15c6ba29 298
Vanger 0:b86d15c6ba29 299 ea[i].value = attribs[i].value;
Vanger 0:b86d15c6ba29 300 ea[i].valueSz = attribs[i].valueSz;
Vanger 0:b86d15c6ba29 301 attribSz += ea[i].valueSz;
Vanger 0:b86d15c6ba29 302 ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
Vanger 0:b86d15c6ba29 303 attribSz += ea[i].valueSetSz;
Vanger 0:b86d15c6ba29 304 ea[i].oid = attribs[i].oid;
Vanger 0:b86d15c6ba29 305 ea[i].oidSz = attribs[i].oidSz;
Vanger 0:b86d15c6ba29 306 attribSz += ea[i].oidSz;
Vanger 0:b86d15c6ba29 307 ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
Vanger 0:b86d15c6ba29 308 attribSz += ea[i].valueSeqSz;
Vanger 0:b86d15c6ba29 309 ea[i].totalSz = attribSz;
Vanger 0:b86d15c6ba29 310
Vanger 0:b86d15c6ba29 311 allAttribsSz += attribSz;
Vanger 0:b86d15c6ba29 312 }
Vanger 0:b86d15c6ba29 313 return allAttribsSz;
Vanger 0:b86d15c6ba29 314 }
Vanger 0:b86d15c6ba29 315
Vanger 0:b86d15c6ba29 316
Vanger 0:b86d15c6ba29 317 static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz)
Vanger 0:b86d15c6ba29 318 {
Vanger 0:b86d15c6ba29 319 int i, idx;
Vanger 0:b86d15c6ba29 320
Vanger 0:b86d15c6ba29 321 idx = 0;
Vanger 0:b86d15c6ba29 322 for (i = 0; i < eaSz; i++) {
Vanger 0:b86d15c6ba29 323 XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
Vanger 0:b86d15c6ba29 324 idx += ea[i].valueSeqSz;
Vanger 0:b86d15c6ba29 325 XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
Vanger 0:b86d15c6ba29 326 idx += ea[i].oidSz;
Vanger 0:b86d15c6ba29 327 XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
Vanger 0:b86d15c6ba29 328 idx += ea[i].valueSetSz;
Vanger 0:b86d15c6ba29 329 XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
Vanger 0:b86d15c6ba29 330 idx += ea[i].valueSz;
Vanger 0:b86d15c6ba29 331 }
Vanger 0:b86d15c6ba29 332 return 0;
Vanger 0:b86d15c6ba29 333 }
Vanger 0:b86d15c6ba29 334
Vanger 0:b86d15c6ba29 335
Vanger 0:b86d15c6ba29 336 /* build PKCS#7 signedData content type */
Vanger 0:b86d15c6ba29 337 int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
Vanger 0:b86d15c6ba29 338 {
Vanger 0:b86d15c6ba29 339 static const byte outerOid[] =
Vanger 0:b86d15c6ba29 340 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
Vanger 0:b86d15c6ba29 341 0x07, 0x02 };
Vanger 0:b86d15c6ba29 342 static const byte innerOid[] =
Vanger 0:b86d15c6ba29 343 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
Vanger 0:b86d15c6ba29 344 0x07, 0x01 };
Vanger 0:b86d15c6ba29 345
Vanger 0:b86d15c6ba29 346 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 347 ESD* esd = NULL;
Vanger 0:b86d15c6ba29 348 #else
Vanger 0:b86d15c6ba29 349 ESD stack_esd;
Vanger 0:b86d15c6ba29 350 ESD* esd = &stack_esd;
Vanger 0:b86d15c6ba29 351 #endif
Vanger 0:b86d15c6ba29 352
Vanger 0:b86d15c6ba29 353 word32 signerInfoSz = 0;
Vanger 0:b86d15c6ba29 354 word32 totalSz = 0;
Vanger 0:b86d15c6ba29 355 int idx = 0, ret = 0;
Vanger 0:b86d15c6ba29 356 byte* flatSignedAttribs = NULL;
Vanger 0:b86d15c6ba29 357 word32 flatSignedAttribsSz = 0;
Vanger 0:b86d15c6ba29 358 word32 innerOidSz = sizeof(innerOid);
Vanger 0:b86d15c6ba29 359 word32 outerOidSz = sizeof(outerOid);
Vanger 0:b86d15c6ba29 360
Vanger 0:b86d15c6ba29 361 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
Vanger 0:b86d15c6ba29 362 pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
Vanger 0:b86d15c6ba29 363 pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 ||
Vanger 0:b86d15c6ba29 364 pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 ||
Vanger 0:b86d15c6ba29 365 output == NULL || outputSz == 0)
Vanger 0:b86d15c6ba29 366 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 367
Vanger 0:b86d15c6ba29 368 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 369 esd = (ESD*)XMALLOC(sizeof(ESD), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 370 if (esd == NULL)
Vanger 0:b86d15c6ba29 371 return MEMORY_E;
Vanger 0:b86d15c6ba29 372 #endif
Vanger 0:b86d15c6ba29 373
Vanger 0:b86d15c6ba29 374 XMEMSET(esd, 0, sizeof(ESD));
Vanger 0:b86d15c6ba29 375 ret = InitSha(&esd->sha);
Vanger 0:b86d15c6ba29 376 if (ret != 0) {
Vanger 0:b86d15c6ba29 377 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 378 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 379 #endif
Vanger 0:b86d15c6ba29 380 return ret;
Vanger 0:b86d15c6ba29 381 }
Vanger 0:b86d15c6ba29 382
Vanger 0:b86d15c6ba29 383 if (pkcs7->contentSz != 0)
Vanger 0:b86d15c6ba29 384 {
Vanger 0:b86d15c6ba29 385 ShaUpdate(&esd->sha, pkcs7->content, pkcs7->contentSz);
Vanger 0:b86d15c6ba29 386 esd->contentDigest[0] = ASN_OCTET_STRING;
Vanger 0:b86d15c6ba29 387 esd->contentDigest[1] = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 388 ShaFinal(&esd->sha, &esd->contentDigest[2]);
Vanger 0:b86d15c6ba29 389 }
Vanger 0:b86d15c6ba29 390
Vanger 0:b86d15c6ba29 391 esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
Vanger 0:b86d15c6ba29 392 esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz,
Vanger 0:b86d15c6ba29 393 esd->innerContSeq);
Vanger 0:b86d15c6ba29 394 esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd->innerOctetsSz +
Vanger 0:b86d15c6ba29 395 innerOidSz + esd->innerContSeqSz,
Vanger 0:b86d15c6ba29 396 esd->contentInfoSeq);
Vanger 0:b86d15c6ba29 397
Vanger 0:b86d15c6ba29 398 esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
Vanger 0:b86d15c6ba29 399 esd->issuerSn);
Vanger 0:b86d15c6ba29 400 signerInfoSz += esd->issuerSnSz;
Vanger 0:b86d15c6ba29 401 esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
Vanger 0:b86d15c6ba29 402 signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
Vanger 0:b86d15c6ba29 403 esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
Vanger 0:b86d15c6ba29 404 signerInfoSz += esd->issuerSnSeqSz;
Vanger 0:b86d15c6ba29 405 esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
Vanger 0:b86d15c6ba29 406 signerInfoSz += esd->signerVersionSz;
Vanger 0:b86d15c6ba29 407 esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
Vanger 0:b86d15c6ba29 408 hashType, 0);
Vanger 0:b86d15c6ba29 409 signerInfoSz += esd->signerDigAlgoIdSz;
Vanger 0:b86d15c6ba29 410 esd->digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd->digEncAlgoId,
Vanger 0:b86d15c6ba29 411 keyType, 0);
Vanger 0:b86d15c6ba29 412 signerInfoSz += esd->digEncAlgoIdSz;
Vanger 0:b86d15c6ba29 413
Vanger 0:b86d15c6ba29 414 if (pkcs7->signedAttribsSz != 0) {
Vanger 0:b86d15c6ba29 415 byte contentTypeOid[] =
Vanger 0:b86d15c6ba29 416 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
Vanger 0:b86d15c6ba29 417 0x09, 0x03 };
Vanger 0:b86d15c6ba29 418 byte contentType[] =
Vanger 0:b86d15c6ba29 419 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
Vanger 0:b86d15c6ba29 420 0x07, 0x01 };
Vanger 0:b86d15c6ba29 421 byte messageDigestOid[] =
Vanger 0:b86d15c6ba29 422 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
Vanger 0:b86d15c6ba29 423 0x09, 0x04 };
Vanger 0:b86d15c6ba29 424
Vanger 0:b86d15c6ba29 425 PKCS7Attrib cannedAttribs[2] =
Vanger 0:b86d15c6ba29 426 {
Vanger 0:b86d15c6ba29 427 { contentTypeOid, sizeof(contentTypeOid),
Vanger 0:b86d15c6ba29 428 contentType, sizeof(contentType) },
Vanger 0:b86d15c6ba29 429 { messageDigestOid, sizeof(messageDigestOid),
Vanger 0:b86d15c6ba29 430 esd->contentDigest, sizeof(esd->contentDigest) }
Vanger 0:b86d15c6ba29 431 };
Vanger 0:b86d15c6ba29 432 word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
Vanger 0:b86d15c6ba29 433
Vanger 0:b86d15c6ba29 434 esd->signedAttribsCount += cannedAttribsCount;
Vanger 0:b86d15c6ba29 435 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2,
Vanger 0:b86d15c6ba29 436 cannedAttribs, cannedAttribsCount);
Vanger 0:b86d15c6ba29 437
Vanger 0:b86d15c6ba29 438 esd->signedAttribsCount += pkcs7->signedAttribsSz;
Vanger 0:b86d15c6ba29 439 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
Vanger 0:b86d15c6ba29 440 pkcs7->signedAttribs, pkcs7->signedAttribsSz);
Vanger 0:b86d15c6ba29 441
Vanger 0:b86d15c6ba29 442 flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, 0, NULL);
Vanger 0:b86d15c6ba29 443 flatSignedAttribsSz = esd->signedAttribsSz;
Vanger 0:b86d15c6ba29 444 if (flatSignedAttribs == NULL) {
Vanger 0:b86d15c6ba29 445 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 446 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 447 #endif
Vanger 0:b86d15c6ba29 448 return MEMORY_E;
Vanger 0:b86d15c6ba29 449 }
Vanger 0:b86d15c6ba29 450 FlattenAttributes(flatSignedAttribs,
Vanger 0:b86d15c6ba29 451 esd->signedAttribs, esd->signedAttribsCount);
Vanger 0:b86d15c6ba29 452 esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
Vanger 0:b86d15c6ba29 453 esd->signedAttribSet);
Vanger 0:b86d15c6ba29 454 }
Vanger 0:b86d15c6ba29 455 /* Calculate the final hash and encrypt it. */
Vanger 0:b86d15c6ba29 456 {
Vanger 0:b86d15c6ba29 457 int result;
Vanger 0:b86d15c6ba29 458 word32 scratch = 0;
Vanger 0:b86d15c6ba29 459
Vanger 0:b86d15c6ba29 460 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 461 byte* digestInfo;
Vanger 0:b86d15c6ba29 462 RsaKey* privKey;
Vanger 0:b86d15c6ba29 463 #else
Vanger 0:b86d15c6ba29 464 RsaKey stack_privKey;
Vanger 0:b86d15c6ba29 465 RsaKey* privKey = &stack_privKey;
Vanger 0:b86d15c6ba29 466 byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ +
Vanger 0:b86d15c6ba29 467 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 468 #endif
Vanger 0:b86d15c6ba29 469 byte digestInfoSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 470 byte digestStr[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 471 word32 digestInfoSeqSz, digestStrSz;
Vanger 0:b86d15c6ba29 472 int digIdx = 0;
Vanger 0:b86d15c6ba29 473
Vanger 0:b86d15c6ba29 474 if (pkcs7->signedAttribsSz != 0) {
Vanger 0:b86d15c6ba29 475 byte attribSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 476 word32 attribSetSz;
Vanger 0:b86d15c6ba29 477
Vanger 0:b86d15c6ba29 478 attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
Vanger 0:b86d15c6ba29 479
Vanger 0:b86d15c6ba29 480 ret = InitSha(&esd->sha);
Vanger 0:b86d15c6ba29 481 if (ret < 0) {
Vanger 0:b86d15c6ba29 482 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 483 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 484 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 485 #endif
Vanger 0:b86d15c6ba29 486 return ret;
Vanger 0:b86d15c6ba29 487 }
Vanger 0:b86d15c6ba29 488 ShaUpdate(&esd->sha, attribSet, attribSetSz);
Vanger 0:b86d15c6ba29 489 ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz);
Vanger 0:b86d15c6ba29 490 }
Vanger 0:b86d15c6ba29 491 ShaFinal(&esd->sha, esd->contentAttribsDigest);
Vanger 0:b86d15c6ba29 492
Vanger 0:b86d15c6ba29 493 digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr);
Vanger 0:b86d15c6ba29 494 digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz +
Vanger 0:b86d15c6ba29 495 digestStrSz + SHA_DIGEST_SIZE,
Vanger 0:b86d15c6ba29 496 digestInfoSeq);
Vanger 0:b86d15c6ba29 497
Vanger 0:b86d15c6ba29 498 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 499 digestInfo = (byte*)XMALLOC(MAX_SEQ_SZ + MAX_ALGO_SZ +
Vanger 0:b86d15c6ba29 500 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE,
Vanger 0:b86d15c6ba29 501 NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 502 if (digestInfo == NULL) {
Vanger 0:b86d15c6ba29 503 if (pkcs7->signedAttribsSz != 0)
Vanger 0:b86d15c6ba29 504 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 505 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 506 return MEMORY_E;
Vanger 0:b86d15c6ba29 507 }
Vanger 0:b86d15c6ba29 508 #endif
Vanger 0:b86d15c6ba29 509
Vanger 0:b86d15c6ba29 510 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
Vanger 0:b86d15c6ba29 511 digIdx += digestInfoSeqSz;
Vanger 0:b86d15c6ba29 512 XMEMCPY(digestInfo + digIdx,
Vanger 0:b86d15c6ba29 513 esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
Vanger 0:b86d15c6ba29 514 digIdx += esd->signerDigAlgoIdSz;
Vanger 0:b86d15c6ba29 515 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
Vanger 0:b86d15c6ba29 516 digIdx += digestStrSz;
Vanger 0:b86d15c6ba29 517 XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest,
Vanger 0:b86d15c6ba29 518 SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 519 digIdx += SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 520
Vanger 0:b86d15c6ba29 521 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 522 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
Vanger 0:b86d15c6ba29 523 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 524 if (privKey == NULL) {
Vanger 0:b86d15c6ba29 525 if (pkcs7->signedAttribsSz != 0)
Vanger 0:b86d15c6ba29 526 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 527 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 528 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 529 return MEMORY_E;
Vanger 0:b86d15c6ba29 530 }
Vanger 0:b86d15c6ba29 531 #endif
Vanger 0:b86d15c6ba29 532
Vanger 0:b86d15c6ba29 533 result = InitRsaKey(privKey, NULL);
Vanger 0:b86d15c6ba29 534 if (result == 0)
Vanger 0:b86d15c6ba29 535 result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, privKey,
Vanger 0:b86d15c6ba29 536 pkcs7->privateKeySz);
Vanger 0:b86d15c6ba29 537 if (result < 0) {
Vanger 0:b86d15c6ba29 538 if (pkcs7->signedAttribsSz != 0)
Vanger 0:b86d15c6ba29 539 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 540 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 541 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 542 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 543 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 544 #endif
Vanger 0:b86d15c6ba29 545 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 546 }
Vanger 0:b86d15c6ba29 547
Vanger 0:b86d15c6ba29 548 result = RsaSSL_Sign(digestInfo, digIdx,
Vanger 0:b86d15c6ba29 549 esd->encContentDigest,
Vanger 0:b86d15c6ba29 550 sizeof(esd->encContentDigest),
Vanger 0:b86d15c6ba29 551 privKey, pkcs7->rng);
Vanger 0:b86d15c6ba29 552
Vanger 0:b86d15c6ba29 553 FreeRsaKey(privKey);
Vanger 0:b86d15c6ba29 554
Vanger 0:b86d15c6ba29 555 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 556 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 557 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 558 #endif
Vanger 0:b86d15c6ba29 559
Vanger 0:b86d15c6ba29 560 if (result < 0) {
Vanger 0:b86d15c6ba29 561 if (pkcs7->signedAttribsSz != 0)
Vanger 0:b86d15c6ba29 562 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 563 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 564 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 565 #endif
Vanger 0:b86d15c6ba29 566 return result;
Vanger 0:b86d15c6ba29 567 }
Vanger 0:b86d15c6ba29 568 esd->encContentDigestSz = (word32)result;
Vanger 0:b86d15c6ba29 569 }
Vanger 0:b86d15c6ba29 570 signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
Vanger 0:b86d15c6ba29 571
Vanger 0:b86d15c6ba29 572 esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
Vanger 0:b86d15c6ba29 573 esd->signerDigest);
Vanger 0:b86d15c6ba29 574 signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
Vanger 0:b86d15c6ba29 575
Vanger 0:b86d15c6ba29 576 esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
Vanger 0:b86d15c6ba29 577 signerInfoSz += esd->signerInfoSeqSz;
Vanger 0:b86d15c6ba29 578 esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
Vanger 0:b86d15c6ba29 579 signerInfoSz += esd->signerInfoSetSz;
Vanger 0:b86d15c6ba29 580
Vanger 0:b86d15c6ba29 581 esd->certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz,
Vanger 0:b86d15c6ba29 582 esd->certsSet);
Vanger 0:b86d15c6ba29 583
Vanger 0:b86d15c6ba29 584 esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
Vanger 0:b86d15c6ba29 585 hashType, 0);
Vanger 0:b86d15c6ba29 586 esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
Vanger 0:b86d15c6ba29 587
Vanger 0:b86d15c6ba29 588
Vanger 0:b86d15c6ba29 589 esd->versionSz = SetMyVersion(1, esd->version, 0);
Vanger 0:b86d15c6ba29 590
Vanger 0:b86d15c6ba29 591 totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
Vanger 0:b86d15c6ba29 592 esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz +
Vanger 0:b86d15c6ba29 593 esd->innerOctetsSz + esd->innerContSeqSz +
Vanger 0:b86d15c6ba29 594 innerOidSz + pkcs7->contentSz +
Vanger 0:b86d15c6ba29 595 signerInfoSz;
Vanger 0:b86d15c6ba29 596 esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq);
Vanger 0:b86d15c6ba29 597 totalSz += esd->innerSeqSz;
Vanger 0:b86d15c6ba29 598 esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent);
Vanger 0:b86d15c6ba29 599 totalSz += esd->outerContentSz + outerOidSz;
Vanger 0:b86d15c6ba29 600 esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq);
Vanger 0:b86d15c6ba29 601 totalSz += esd->outerSeqSz;
Vanger 0:b86d15c6ba29 602
Vanger 0:b86d15c6ba29 603 if (outputSz < totalSz) {
Vanger 0:b86d15c6ba29 604 if (pkcs7->signedAttribsSz != 0)
Vanger 0:b86d15c6ba29 605 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 606 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 607 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 608 #endif
Vanger 0:b86d15c6ba29 609 return BUFFER_E;
Vanger 0:b86d15c6ba29 610 }
Vanger 0:b86d15c6ba29 611
Vanger 0:b86d15c6ba29 612 idx = 0;
Vanger 0:b86d15c6ba29 613 XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
Vanger 0:b86d15c6ba29 614 idx += esd->outerSeqSz;
Vanger 0:b86d15c6ba29 615 XMEMCPY(output + idx, outerOid, outerOidSz);
Vanger 0:b86d15c6ba29 616 idx += outerOidSz;
Vanger 0:b86d15c6ba29 617 XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
Vanger 0:b86d15c6ba29 618 idx += esd->outerContentSz;
Vanger 0:b86d15c6ba29 619 XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
Vanger 0:b86d15c6ba29 620 idx += esd->innerSeqSz;
Vanger 0:b86d15c6ba29 621 XMEMCPY(output + idx, esd->version, esd->versionSz);
Vanger 0:b86d15c6ba29 622 idx += esd->versionSz;
Vanger 0:b86d15c6ba29 623 XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
Vanger 0:b86d15c6ba29 624 idx += esd->digAlgoIdSetSz;
Vanger 0:b86d15c6ba29 625 XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
Vanger 0:b86d15c6ba29 626 idx += esd->singleDigAlgoIdSz;
Vanger 0:b86d15c6ba29 627 XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
Vanger 0:b86d15c6ba29 628 idx += esd->contentInfoSeqSz;
Vanger 0:b86d15c6ba29 629 XMEMCPY(output + idx, innerOid, innerOidSz);
Vanger 0:b86d15c6ba29 630 idx += innerOidSz;
Vanger 0:b86d15c6ba29 631 XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
Vanger 0:b86d15c6ba29 632 idx += esd->innerContSeqSz;
Vanger 0:b86d15c6ba29 633 XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
Vanger 0:b86d15c6ba29 634 idx += esd->innerOctetsSz;
Vanger 0:b86d15c6ba29 635 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
Vanger 0:b86d15c6ba29 636 idx += pkcs7->contentSz;
Vanger 0:b86d15c6ba29 637 XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz);
Vanger 0:b86d15c6ba29 638 idx += esd->certsSetSz;
Vanger 0:b86d15c6ba29 639 XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz);
Vanger 0:b86d15c6ba29 640 idx += pkcs7->singleCertSz;
Vanger 0:b86d15c6ba29 641 XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz);
Vanger 0:b86d15c6ba29 642 idx += esd->signerInfoSetSz;
Vanger 0:b86d15c6ba29 643 XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
Vanger 0:b86d15c6ba29 644 idx += esd->signerInfoSeqSz;
Vanger 0:b86d15c6ba29 645 XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz);
Vanger 0:b86d15c6ba29 646 idx += esd->signerVersionSz;
Vanger 0:b86d15c6ba29 647 XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
Vanger 0:b86d15c6ba29 648 idx += esd->issuerSnSeqSz;
Vanger 0:b86d15c6ba29 649 XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz);
Vanger 0:b86d15c6ba29 650 idx += esd->issuerNameSz;
Vanger 0:b86d15c6ba29 651 XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz);
Vanger 0:b86d15c6ba29 652 idx += pkcs7->issuerSz;
Vanger 0:b86d15c6ba29 653 XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz);
Vanger 0:b86d15c6ba29 654 idx += esd->issuerSnSz;
Vanger 0:b86d15c6ba29 655 XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
Vanger 0:b86d15c6ba29 656 idx += esd->signerDigAlgoIdSz;
Vanger 0:b86d15c6ba29 657
Vanger 0:b86d15c6ba29 658 /* SignerInfo:Attributes */
Vanger 0:b86d15c6ba29 659 if (pkcs7->signedAttribsSz != 0) {
Vanger 0:b86d15c6ba29 660 XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz);
Vanger 0:b86d15c6ba29 661 idx += esd->signedAttribSetSz;
Vanger 0:b86d15c6ba29 662 XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz);
Vanger 0:b86d15c6ba29 663 idx += flatSignedAttribsSz;
Vanger 0:b86d15c6ba29 664 XFREE(flatSignedAttribs, 0, NULL);
Vanger 0:b86d15c6ba29 665 }
Vanger 0:b86d15c6ba29 666
Vanger 0:b86d15c6ba29 667 XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
Vanger 0:b86d15c6ba29 668 idx += esd->digEncAlgoIdSz;
Vanger 0:b86d15c6ba29 669 XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz);
Vanger 0:b86d15c6ba29 670 idx += esd->signerDigestSz;
Vanger 0:b86d15c6ba29 671 XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz);
Vanger 0:b86d15c6ba29 672 idx += esd->encContentDigestSz;
Vanger 0:b86d15c6ba29 673
Vanger 0:b86d15c6ba29 674 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 675 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 676 #endif
Vanger 0:b86d15c6ba29 677
Vanger 0:b86d15c6ba29 678 return idx;
Vanger 0:b86d15c6ba29 679 }
Vanger 0:b86d15c6ba29 680
Vanger 0:b86d15c6ba29 681
Vanger 0:b86d15c6ba29 682 /* Finds the certificates in the message and saves it. */
Vanger 0:b86d15c6ba29 683 int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
Vanger 0:b86d15c6ba29 684 {
Vanger 0:b86d15c6ba29 685 word32 idx, contentType;
Vanger 0:b86d15c6ba29 686 int length, version, ret;
Vanger 0:b86d15c6ba29 687 byte* content = NULL;
Vanger 0:b86d15c6ba29 688 byte* sig = NULL;
Vanger 0:b86d15c6ba29 689 byte* cert = NULL;
Vanger 0:b86d15c6ba29 690 int contentSz = 0, sigSz = 0, certSz = 0;
Vanger 0:b86d15c6ba29 691
Vanger 0:b86d15c6ba29 692 if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
Vanger 0:b86d15c6ba29 693 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 694
Vanger 0:b86d15c6ba29 695 idx = 0;
Vanger 0:b86d15c6ba29 696
Vanger 0:b86d15c6ba29 697 /* Get the contentInfo sequence */
Vanger 0:b86d15c6ba29 698 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 699 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 700
Vanger 0:b86d15c6ba29 701 /* Get the contentInfo contentType */
Vanger 0:b86d15c6ba29 702 if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 703 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 704
Vanger 0:b86d15c6ba29 705 if (contentType != SIGNED_DATA) {
Vanger 0:b86d15c6ba29 706 CYASSL_MSG("PKCS#7 input not of type SignedData");
Vanger 0:b86d15c6ba29 707 return PKCS7_OID_E;
Vanger 0:b86d15c6ba29 708 }
Vanger 0:b86d15c6ba29 709
Vanger 0:b86d15c6ba29 710 /* get the ContentInfo content */
Vanger 0:b86d15c6ba29 711 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
Vanger 0:b86d15c6ba29 712 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 713
Vanger 0:b86d15c6ba29 714 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 715 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 716
Vanger 0:b86d15c6ba29 717 /* Get the signedData sequence */
Vanger 0:b86d15c6ba29 718 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 719 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 720
Vanger 0:b86d15c6ba29 721 /* Get the version */
Vanger 0:b86d15c6ba29 722 if (GetMyVersion(pkiMsg, &idx, &version) < 0)
Vanger 0:b86d15c6ba29 723 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 724
Vanger 0:b86d15c6ba29 725 if (version != 1) {
Vanger 0:b86d15c6ba29 726 CYASSL_MSG("PKCS#7 signedData needs to be of version 1");
Vanger 0:b86d15c6ba29 727 return ASN_VERSION_E;
Vanger 0:b86d15c6ba29 728 }
Vanger 0:b86d15c6ba29 729
Vanger 0:b86d15c6ba29 730 /* Get the set of DigestAlgorithmIdentifiers */
Vanger 0:b86d15c6ba29 731 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 732 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 733
Vanger 0:b86d15c6ba29 734 /* Skip the set. */
Vanger 0:b86d15c6ba29 735 idx += length;
Vanger 0:b86d15c6ba29 736
Vanger 0:b86d15c6ba29 737 /* Get the inner ContentInfo sequence */
Vanger 0:b86d15c6ba29 738 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 739 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 740
Vanger 0:b86d15c6ba29 741 /* Get the inner ContentInfo contentType */
Vanger 0:b86d15c6ba29 742 if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 743 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 744
Vanger 0:b86d15c6ba29 745 if (contentType != DATA) {
Vanger 0:b86d15c6ba29 746 CYASSL_MSG("PKCS#7 inner input not of type Data");
Vanger 0:b86d15c6ba29 747 return PKCS7_OID_E;
Vanger 0:b86d15c6ba29 748 }
Vanger 0:b86d15c6ba29 749
Vanger 0:b86d15c6ba29 750 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
Vanger 0:b86d15c6ba29 751 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 752
Vanger 0:b86d15c6ba29 753 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 754 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 755
Vanger 0:b86d15c6ba29 756 if (pkiMsg[idx++] != ASN_OCTET_STRING)
Vanger 0:b86d15c6ba29 757 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 758
Vanger 0:b86d15c6ba29 759 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 760 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 761
Vanger 0:b86d15c6ba29 762 /* Save the inner data as the content. */
Vanger 0:b86d15c6ba29 763 if (length > 0) {
Vanger 0:b86d15c6ba29 764 /* Local pointer for calculating hashes later */
Vanger 0:b86d15c6ba29 765 pkcs7->content = content = &pkiMsg[idx];
Vanger 0:b86d15c6ba29 766 pkcs7->contentSz = contentSz = length;
Vanger 0:b86d15c6ba29 767 idx += length;
Vanger 0:b86d15c6ba29 768 }
Vanger 0:b86d15c6ba29 769
Vanger 0:b86d15c6ba29 770 /* Get the implicit[0] set of certificates */
Vanger 0:b86d15c6ba29 771 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
Vanger 0:b86d15c6ba29 772 idx++;
Vanger 0:b86d15c6ba29 773 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 774 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 775
Vanger 0:b86d15c6ba29 776 if (length > 0) {
Vanger 0:b86d15c6ba29 777 /* At this point, idx is at the first certificate in
Vanger 0:b86d15c6ba29 778 * a set of certificates. There may be more than one,
Vanger 0:b86d15c6ba29 779 * or none, or they may be a PKCS 6 extended
Vanger 0:b86d15c6ba29 780 * certificate. We want to save the first cert if it
Vanger 0:b86d15c6ba29 781 * is X.509. */
Vanger 0:b86d15c6ba29 782
Vanger 0:b86d15c6ba29 783 word32 certIdx = idx;
Vanger 0:b86d15c6ba29 784
Vanger 0:b86d15c6ba29 785 if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
Vanger 0:b86d15c6ba29 786 if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 787 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 788
Vanger 0:b86d15c6ba29 789 cert = &pkiMsg[idx];
Vanger 0:b86d15c6ba29 790 certSz += (certIdx - idx);
Vanger 0:b86d15c6ba29 791 }
Vanger 0:b86d15c6ba29 792 PKCS7_InitWithCert(pkcs7, cert, certSz);
Vanger 0:b86d15c6ba29 793 }
Vanger 0:b86d15c6ba29 794 idx += length;
Vanger 0:b86d15c6ba29 795 }
Vanger 0:b86d15c6ba29 796
Vanger 0:b86d15c6ba29 797 /* Get the implicit[1] set of crls */
Vanger 0:b86d15c6ba29 798 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
Vanger 0:b86d15c6ba29 799 idx++;
Vanger 0:b86d15c6ba29 800 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 801 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 802
Vanger 0:b86d15c6ba29 803 /* Skip the set */
Vanger 0:b86d15c6ba29 804 idx += length;
Vanger 0:b86d15c6ba29 805 }
Vanger 0:b86d15c6ba29 806
Vanger 0:b86d15c6ba29 807 /* Get the set of signerInfos */
Vanger 0:b86d15c6ba29 808 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 809 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 810
Vanger 0:b86d15c6ba29 811 if (length > 0) {
Vanger 0:b86d15c6ba29 812 /* Get the sequence of the first signerInfo */
Vanger 0:b86d15c6ba29 813 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 814 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 815
Vanger 0:b86d15c6ba29 816 /* Get the version */
Vanger 0:b86d15c6ba29 817 if (GetMyVersion(pkiMsg, &idx, &version) < 0)
Vanger 0:b86d15c6ba29 818 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 819
Vanger 0:b86d15c6ba29 820 if (version != 1) {
Vanger 0:b86d15c6ba29 821 CYASSL_MSG("PKCS#7 signerInfo needs to be of version 1");
Vanger 0:b86d15c6ba29 822 return ASN_VERSION_E;
Vanger 0:b86d15c6ba29 823 }
Vanger 0:b86d15c6ba29 824
Vanger 0:b86d15c6ba29 825 /* Get the sequence of IssuerAndSerialNumber */
Vanger 0:b86d15c6ba29 826 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 827 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 828
Vanger 0:b86d15c6ba29 829 /* Skip it */
Vanger 0:b86d15c6ba29 830 idx += length;
Vanger 0:b86d15c6ba29 831
Vanger 0:b86d15c6ba29 832 /* Get the sequence of digestAlgorithm */
Vanger 0:b86d15c6ba29 833 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 834 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 835
Vanger 0:b86d15c6ba29 836 /* Skip it */
Vanger 0:b86d15c6ba29 837 idx += length;
Vanger 0:b86d15c6ba29 838
Vanger 0:b86d15c6ba29 839 /* Get the IMPLICIT[0] SET OF signedAttributes */
Vanger 0:b86d15c6ba29 840 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
Vanger 0:b86d15c6ba29 841 idx++;
Vanger 0:b86d15c6ba29 842
Vanger 0:b86d15c6ba29 843 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 844 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 845
Vanger 0:b86d15c6ba29 846 idx += length;
Vanger 0:b86d15c6ba29 847 }
Vanger 0:b86d15c6ba29 848
Vanger 0:b86d15c6ba29 849 /* Get the sequence of digestEncryptionAlgorithm */
Vanger 0:b86d15c6ba29 850 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 851 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 852
Vanger 0:b86d15c6ba29 853 /* Skip it */
Vanger 0:b86d15c6ba29 854 idx += length;
Vanger 0:b86d15c6ba29 855
Vanger 0:b86d15c6ba29 856 /* Get the signature */
Vanger 0:b86d15c6ba29 857 if (pkiMsg[idx] == ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 858 idx++;
Vanger 0:b86d15c6ba29 859
Vanger 0:b86d15c6ba29 860 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 861 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 862
Vanger 0:b86d15c6ba29 863 /* save pointer and length */
Vanger 0:b86d15c6ba29 864 sig = &pkiMsg[idx];
Vanger 0:b86d15c6ba29 865 sigSz = length;
Vanger 0:b86d15c6ba29 866
Vanger 0:b86d15c6ba29 867 idx += length;
Vanger 0:b86d15c6ba29 868 }
Vanger 0:b86d15c6ba29 869
Vanger 0:b86d15c6ba29 870 pkcs7->content = content;
Vanger 0:b86d15c6ba29 871 pkcs7->contentSz = contentSz;
Vanger 0:b86d15c6ba29 872
Vanger 0:b86d15c6ba29 873 {
Vanger 0:b86d15c6ba29 874 word32 scratch = 0;
Vanger 0:b86d15c6ba29 875 int plainSz = 0;
Vanger 0:b86d15c6ba29 876 int digestSz = MAX_SEQ_SZ + MAX_ALGO_SZ +
Vanger 0:b86d15c6ba29 877 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 878
Vanger 0:b86d15c6ba29 879 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 880 byte* digest;
Vanger 0:b86d15c6ba29 881 RsaKey* key;
Vanger 0:b86d15c6ba29 882
Vanger 0:b86d15c6ba29 883 digest = (byte*)XMALLOC(digestSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 884
Vanger 0:b86d15c6ba29 885 if (digest == NULL)
Vanger 0:b86d15c6ba29 886 return MEMORY_E;
Vanger 0:b86d15c6ba29 887
Vanger 0:b86d15c6ba29 888 key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
Vanger 0:b86d15c6ba29 889 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 890 if (key == NULL) {
Vanger 0:b86d15c6ba29 891 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 892 return MEMORY_E;
Vanger 0:b86d15c6ba29 893 }
Vanger 0:b86d15c6ba29 894 #else
Vanger 0:b86d15c6ba29 895 byte digest[digestSz];
Vanger 0:b86d15c6ba29 896 RsaKey stack_key;
Vanger 0:b86d15c6ba29 897 RsaKey* key = &stack_key;
Vanger 0:b86d15c6ba29 898 #endif
Vanger 0:b86d15c6ba29 899
Vanger 0:b86d15c6ba29 900 XMEMSET(digest, 0, digestSz);
Vanger 0:b86d15c6ba29 901
Vanger 0:b86d15c6ba29 902 ret = InitRsaKey(key, NULL);
Vanger 0:b86d15c6ba29 903 if (ret != 0) {
Vanger 0:b86d15c6ba29 904 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 905 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 906 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 907 #endif
Vanger 0:b86d15c6ba29 908 return ret;
Vanger 0:b86d15c6ba29 909 }
Vanger 0:b86d15c6ba29 910 if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key,
Vanger 0:b86d15c6ba29 911 pkcs7->publicKeySz) < 0) {
Vanger 0:b86d15c6ba29 912 CYASSL_MSG("ASN RSA key decode error");
Vanger 0:b86d15c6ba29 913 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 914 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 915 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 916 #endif
Vanger 0:b86d15c6ba29 917 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 918 }
Vanger 0:b86d15c6ba29 919
Vanger 0:b86d15c6ba29 920 plainSz = RsaSSL_Verify(sig, sigSz, digest, digestSz, key);
Vanger 0:b86d15c6ba29 921 FreeRsaKey(key);
Vanger 0:b86d15c6ba29 922
Vanger 0:b86d15c6ba29 923 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 924 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 925 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 926 #endif
Vanger 0:b86d15c6ba29 927
Vanger 0:b86d15c6ba29 928 if (plainSz < 0)
Vanger 0:b86d15c6ba29 929 return plainSz;
Vanger 0:b86d15c6ba29 930 }
Vanger 0:b86d15c6ba29 931 }
Vanger 0:b86d15c6ba29 932
Vanger 0:b86d15c6ba29 933 return 0;
Vanger 0:b86d15c6ba29 934 }
Vanger 0:b86d15c6ba29 935
Vanger 0:b86d15c6ba29 936
Vanger 0:b86d15c6ba29 937 /* create ASN.1 fomatted RecipientInfo structure, returns sequence size */
Vanger 0:b86d15c6ba29 938 CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
Vanger 0:b86d15c6ba29 939 int keyEncAlgo, int blockKeySz,
Vanger 0:b86d15c6ba29 940 RNG* rng, byte* contentKeyPlain,
Vanger 0:b86d15c6ba29 941 byte* contentKeyEnc,
Vanger 0:b86d15c6ba29 942 int* keyEncSz, byte* out, word32 outSz)
Vanger 0:b86d15c6ba29 943 {
Vanger 0:b86d15c6ba29 944 word32 idx = 0;
Vanger 0:b86d15c6ba29 945 int ret = 0, totalSz = 0;
Vanger 0:b86d15c6ba29 946 int verSz, issuerSz, snSz, keyEncAlgSz;
Vanger 0:b86d15c6ba29 947 int issuerSeqSz, recipSeqSz, issuerSerialSeqSz;
Vanger 0:b86d15c6ba29 948 int encKeyOctetStrSz;
Vanger 0:b86d15c6ba29 949
Vanger 0:b86d15c6ba29 950 byte ver[MAX_VERSION_SZ];
Vanger 0:b86d15c6ba29 951 byte issuerSerialSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 952 byte recipSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 953 byte issuerSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 954 byte encKeyOctetStr[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 955
Vanger 0:b86d15c6ba29 956 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 957 byte *serial;
Vanger 0:b86d15c6ba29 958 byte *keyAlgArray;
Vanger 0:b86d15c6ba29 959
Vanger 0:b86d15c6ba29 960 RsaKey* pubKey;
Vanger 0:b86d15c6ba29 961 DecodedCert* decoded;
Vanger 0:b86d15c6ba29 962
Vanger 0:b86d15c6ba29 963 serial = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 964 keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 965 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
Vanger 0:b86d15c6ba29 966 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 967
Vanger 0:b86d15c6ba29 968 if (decoded == NULL || serial == NULL || keyAlgArray == NULL) {
Vanger 0:b86d15c6ba29 969 if (serial) XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 970 if (keyAlgArray) XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 971 if (decoded) XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 972 return MEMORY_E;
Vanger 0:b86d15c6ba29 973 }
Vanger 0:b86d15c6ba29 974
Vanger 0:b86d15c6ba29 975 #else
Vanger 0:b86d15c6ba29 976 byte serial[MAX_SN_SZ];
Vanger 0:b86d15c6ba29 977 byte keyAlgArray[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 978
Vanger 0:b86d15c6ba29 979 RsaKey stack_pubKey;
Vanger 0:b86d15c6ba29 980 RsaKey* pubKey = &stack_pubKey;
Vanger 0:b86d15c6ba29 981 DecodedCert stack_decoded;
Vanger 0:b86d15c6ba29 982 DecodedCert* decoded = &stack_decoded;
Vanger 0:b86d15c6ba29 983 #endif
Vanger 0:b86d15c6ba29 984
Vanger 0:b86d15c6ba29 985 InitDecodedCert(decoded, (byte*)cert, certSz, 0);
Vanger 0:b86d15c6ba29 986 ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
Vanger 0:b86d15c6ba29 987 if (ret < 0) {
Vanger 0:b86d15c6ba29 988 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 989 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 990 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 991 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 992 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 993 #endif
Vanger 0:b86d15c6ba29 994 return ret;
Vanger 0:b86d15c6ba29 995 }
Vanger 0:b86d15c6ba29 996
Vanger 0:b86d15c6ba29 997 /* version */
Vanger 0:b86d15c6ba29 998 verSz = SetMyVersion(0, ver, 0);
Vanger 0:b86d15c6ba29 999
Vanger 0:b86d15c6ba29 1000 /* IssuerAndSerialNumber */
Vanger 0:b86d15c6ba29 1001 if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
Vanger 0:b86d15c6ba29 1002 CYASSL_MSG("DecodedCert lacks raw issuer pointer and length");
Vanger 0:b86d15c6ba29 1003 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1004 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1005 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1006 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1007 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1008 #endif
Vanger 0:b86d15c6ba29 1009 return -1;
Vanger 0:b86d15c6ba29 1010 }
Vanger 0:b86d15c6ba29 1011 issuerSz = decoded->issuerRawLen;
Vanger 0:b86d15c6ba29 1012 issuerSeqSz = SetSequence(issuerSz, issuerSeq);
Vanger 0:b86d15c6ba29 1013
Vanger 0:b86d15c6ba29 1014 if (decoded->serial == NULL || decoded->serialSz == 0) {
Vanger 0:b86d15c6ba29 1015 CYASSL_MSG("DecodedCert missing serial number");
Vanger 0:b86d15c6ba29 1016 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1017 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1018 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1019 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1020 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1021 #endif
Vanger 0:b86d15c6ba29 1022 return -1;
Vanger 0:b86d15c6ba29 1023 }
Vanger 0:b86d15c6ba29 1024 snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial);
Vanger 0:b86d15c6ba29 1025
Vanger 0:b86d15c6ba29 1026 issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
Vanger 0:b86d15c6ba29 1027 issuerSerialSeq);
Vanger 0:b86d15c6ba29 1028
Vanger 0:b86d15c6ba29 1029 /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
Vanger 0:b86d15c6ba29 1030 if (keyEncAlgo != RSAk) {
Vanger 0:b86d15c6ba29 1031 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1032 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1033 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1034 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1035 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1036 #endif
Vanger 0:b86d15c6ba29 1037 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 1038 }
Vanger 0:b86d15c6ba29 1039
Vanger 0:b86d15c6ba29 1040 keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
Vanger 0:b86d15c6ba29 1041 if (keyEncAlgSz == 0) {
Vanger 0:b86d15c6ba29 1042 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1043 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1044 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1045 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1046 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1047 #endif
Vanger 0:b86d15c6ba29 1048 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1049 }
Vanger 0:b86d15c6ba29 1050
Vanger 0:b86d15c6ba29 1051 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1052 pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1053 if (pubKey == NULL) {
Vanger 0:b86d15c6ba29 1054 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1055 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1056 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1057 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1058 return MEMORY_E;
Vanger 0:b86d15c6ba29 1059 }
Vanger 0:b86d15c6ba29 1060 #endif
Vanger 0:b86d15c6ba29 1061
Vanger 0:b86d15c6ba29 1062 /* EncryptedKey */
Vanger 0:b86d15c6ba29 1063 ret = InitRsaKey(pubKey, 0);
Vanger 0:b86d15c6ba29 1064 if (ret != 0) {
Vanger 0:b86d15c6ba29 1065 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1066 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1067 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1068 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1069 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1070 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1071 #endif
Vanger 0:b86d15c6ba29 1072 return ret;
Vanger 0:b86d15c6ba29 1073 }
Vanger 0:b86d15c6ba29 1074
Vanger 0:b86d15c6ba29 1075 if (RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
Vanger 0:b86d15c6ba29 1076 decoded->pubKeySize) < 0) {
Vanger 0:b86d15c6ba29 1077 CYASSL_MSG("ASN RSA key decode error");
Vanger 0:b86d15c6ba29 1078 FreeRsaKey(pubKey);
Vanger 0:b86d15c6ba29 1079 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1080 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1081 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1082 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1083 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1084 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1085 #endif
Vanger 0:b86d15c6ba29 1086 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 1087 }
Vanger 0:b86d15c6ba29 1088
Vanger 0:b86d15c6ba29 1089 *keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
Vanger 0:b86d15c6ba29 1090 MAX_ENCRYPTED_KEY_SZ, pubKey, rng);
Vanger 0:b86d15c6ba29 1091 FreeRsaKey(pubKey);
Vanger 0:b86d15c6ba29 1092
Vanger 0:b86d15c6ba29 1093 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1094 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1095 #endif
Vanger 0:b86d15c6ba29 1096
Vanger 0:b86d15c6ba29 1097 if (*keyEncSz < 0) {
Vanger 0:b86d15c6ba29 1098 CYASSL_MSG("RSA Public Encrypt failed");
Vanger 0:b86d15c6ba29 1099 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1100 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1101 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1102 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1103 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1104 #endif
Vanger 0:b86d15c6ba29 1105 return *keyEncSz;
Vanger 0:b86d15c6ba29 1106 }
Vanger 0:b86d15c6ba29 1107
Vanger 0:b86d15c6ba29 1108 encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr);
Vanger 0:b86d15c6ba29 1109
Vanger 0:b86d15c6ba29 1110 /* RecipientInfo */
Vanger 0:b86d15c6ba29 1111 recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
Vanger 0:b86d15c6ba29 1112 issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz +
Vanger 0:b86d15c6ba29 1113 *keyEncSz, recipSeq);
Vanger 0:b86d15c6ba29 1114
Vanger 0:b86d15c6ba29 1115 if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
Vanger 0:b86d15c6ba29 1116 keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
Vanger 0:b86d15c6ba29 1117 CYASSL_MSG("RecipientInfo output buffer too small");
Vanger 0:b86d15c6ba29 1118 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1119 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1120 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1121 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1122 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1123 #endif
Vanger 0:b86d15c6ba29 1124 return BUFFER_E;
Vanger 0:b86d15c6ba29 1125 }
Vanger 0:b86d15c6ba29 1126
Vanger 0:b86d15c6ba29 1127 XMEMCPY(out + totalSz, recipSeq, recipSeqSz);
Vanger 0:b86d15c6ba29 1128 totalSz += recipSeqSz;
Vanger 0:b86d15c6ba29 1129 XMEMCPY(out + totalSz, ver, verSz);
Vanger 0:b86d15c6ba29 1130 totalSz += verSz;
Vanger 0:b86d15c6ba29 1131 XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz);
Vanger 0:b86d15c6ba29 1132 totalSz += issuerSerialSeqSz;
Vanger 0:b86d15c6ba29 1133 XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
Vanger 0:b86d15c6ba29 1134 totalSz += issuerSeqSz;
Vanger 0:b86d15c6ba29 1135 XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz);
Vanger 0:b86d15c6ba29 1136 totalSz += issuerSz;
Vanger 0:b86d15c6ba29 1137 XMEMCPY(out + totalSz, serial, snSz);
Vanger 0:b86d15c6ba29 1138 totalSz += snSz;
Vanger 0:b86d15c6ba29 1139 XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz);
Vanger 0:b86d15c6ba29 1140 totalSz += keyEncAlgSz;
Vanger 0:b86d15c6ba29 1141 XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz);
Vanger 0:b86d15c6ba29 1142 totalSz += encKeyOctetStrSz;
Vanger 0:b86d15c6ba29 1143 XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
Vanger 0:b86d15c6ba29 1144 totalSz += *keyEncSz;
Vanger 0:b86d15c6ba29 1145
Vanger 0:b86d15c6ba29 1146 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 1147
Vanger 0:b86d15c6ba29 1148 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1149 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1150 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1151 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1152 #endif
Vanger 0:b86d15c6ba29 1153
Vanger 0:b86d15c6ba29 1154 return totalSz;
Vanger 0:b86d15c6ba29 1155 }
Vanger 0:b86d15c6ba29 1156
Vanger 0:b86d15c6ba29 1157
Vanger 0:b86d15c6ba29 1158 /* build PKCS#7 envelopedData content type, return enveloped size */
Vanger 0:b86d15c6ba29 1159 int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
Vanger 0:b86d15c6ba29 1160 {
Vanger 0:b86d15c6ba29 1161 int i, ret = 0, idx = 0;
Vanger 0:b86d15c6ba29 1162 int totalSz = 0, padSz = 0, desOutSz = 0;
Vanger 0:b86d15c6ba29 1163
Vanger 0:b86d15c6ba29 1164 int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
Vanger 0:b86d15c6ba29 1165 byte contentInfoSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 1166 byte outerContentType[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 1167 byte outerContent[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 1168
Vanger 0:b86d15c6ba29 1169 int envDataSeqSz, verSz;
Vanger 0:b86d15c6ba29 1170 byte envDataSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 1171 byte ver[MAX_VERSION_SZ];
Vanger 0:b86d15c6ba29 1172
Vanger 0:b86d15c6ba29 1173 RNG rng;
Vanger 0:b86d15c6ba29 1174 int contentKeyEncSz, blockKeySz;
Vanger 0:b86d15c6ba29 1175 int dynamicFlag = 0;
Vanger 0:b86d15c6ba29 1176 byte contentKeyPlain[MAX_CONTENT_KEY_LEN];
Vanger 0:b86d15c6ba29 1177 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1178 byte* contentKeyEnc;
Vanger 0:b86d15c6ba29 1179 #else
Vanger 0:b86d15c6ba29 1180 byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
Vanger 0:b86d15c6ba29 1181 #endif
Vanger 0:b86d15c6ba29 1182 byte* plain;
Vanger 0:b86d15c6ba29 1183 byte* encryptedContent;
Vanger 0:b86d15c6ba29 1184
Vanger 0:b86d15c6ba29 1185 int recipSz, recipSetSz;
Vanger 0:b86d15c6ba29 1186 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1187 byte* recip;
Vanger 0:b86d15c6ba29 1188 #else
Vanger 0:b86d15c6ba29 1189 byte recip[MAX_RECIP_SZ];
Vanger 0:b86d15c6ba29 1190 #endif
Vanger 0:b86d15c6ba29 1191 byte recipSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 1192
Vanger 0:b86d15c6ba29 1193 int encContentOctetSz, encContentSeqSz, contentTypeSz;
Vanger 0:b86d15c6ba29 1194 int contentEncAlgoSz, ivOctetStringSz;
Vanger 0:b86d15c6ba29 1195 byte encContentSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 1196 byte contentType[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 1197 byte contentEncAlgo[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 1198 byte tmpIv[DES_BLOCK_SIZE];
Vanger 0:b86d15c6ba29 1199 byte ivOctetString[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 1200 byte encContentOctet[MAX_OCTET_STR_SZ];
Vanger 0:b86d15c6ba29 1201
Vanger 0:b86d15c6ba29 1202 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
Vanger 0:b86d15c6ba29 1203 pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL)
Vanger 0:b86d15c6ba29 1204 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1205
Vanger 0:b86d15c6ba29 1206 if (output == NULL || outputSz == 0)
Vanger 0:b86d15c6ba29 1207 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1208
Vanger 0:b86d15c6ba29 1209 /* PKCS#7 only supports DES, 3DES for now */
Vanger 0:b86d15c6ba29 1210 switch (pkcs7->encryptOID) {
Vanger 0:b86d15c6ba29 1211 case DESb:
Vanger 0:b86d15c6ba29 1212 blockKeySz = DES_KEYLEN;
Vanger 0:b86d15c6ba29 1213 break;
Vanger 0:b86d15c6ba29 1214
Vanger 0:b86d15c6ba29 1215 case DES3b:
Vanger 0:b86d15c6ba29 1216 blockKeySz = DES3_KEYLEN;
Vanger 0:b86d15c6ba29 1217 break;
Vanger 0:b86d15c6ba29 1218
Vanger 0:b86d15c6ba29 1219 default:
Vanger 0:b86d15c6ba29 1220 CYASSL_MSG("Unsupported content cipher type");
Vanger 0:b86d15c6ba29 1221 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 1222 };
Vanger 0:b86d15c6ba29 1223
Vanger 0:b86d15c6ba29 1224 /* outer content type */
Vanger 0:b86d15c6ba29 1225 outerContentTypeSz = SetContentType(ENVELOPED_DATA, outerContentType);
Vanger 0:b86d15c6ba29 1226
Vanger 0:b86d15c6ba29 1227 /* version, defined as 0 in RFC 2315 */
Vanger 0:b86d15c6ba29 1228 verSz = SetMyVersion(0, ver, 0);
Vanger 0:b86d15c6ba29 1229
Vanger 0:b86d15c6ba29 1230 /* generate random content encryption key */
Vanger 0:b86d15c6ba29 1231 ret = InitRng(&rng);
Vanger 0:b86d15c6ba29 1232 if (ret != 0)
Vanger 0:b86d15c6ba29 1233 return ret;
Vanger 0:b86d15c6ba29 1234
Vanger 0:b86d15c6ba29 1235 ret = RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
Vanger 0:b86d15c6ba29 1236 if (ret != 0)
Vanger 0:b86d15c6ba29 1237 return ret;
Vanger 0:b86d15c6ba29 1238
Vanger 0:b86d15c6ba29 1239 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1240 recip = (byte*)XMALLOC(MAX_RECIP_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1241 contentKeyEnc = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL,
Vanger 0:b86d15c6ba29 1242 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1243 if (contentKeyEnc == NULL || recip == NULL) {
Vanger 0:b86d15c6ba29 1244 if (recip) XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1245 if (contentKeyEnc) XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1246 return MEMORY_E;
Vanger 0:b86d15c6ba29 1247 }
Vanger 0:b86d15c6ba29 1248
Vanger 0:b86d15c6ba29 1249 #endif
Vanger 0:b86d15c6ba29 1250
Vanger 0:b86d15c6ba29 1251 /* build RecipientInfo, only handle 1 for now */
Vanger 0:b86d15c6ba29 1252 recipSz = CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk,
Vanger 0:b86d15c6ba29 1253 blockKeySz, &rng, contentKeyPlain,
Vanger 0:b86d15c6ba29 1254 contentKeyEnc, &contentKeyEncSz, recip,
Vanger 0:b86d15c6ba29 1255 MAX_RECIP_SZ);
Vanger 0:b86d15c6ba29 1256
Vanger 0:b86d15c6ba29 1257 XMEMSET(contentKeyEnc, 0, MAX_ENCRYPTED_KEY_SZ);
Vanger 0:b86d15c6ba29 1258
Vanger 0:b86d15c6ba29 1259 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1260 XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1261 #endif
Vanger 0:b86d15c6ba29 1262
Vanger 0:b86d15c6ba29 1263 if (recipSz < 0) {
Vanger 0:b86d15c6ba29 1264 CYASSL_MSG("Failed to create RecipientInfo");
Vanger 0:b86d15c6ba29 1265 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1266 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1267 #endif
Vanger 0:b86d15c6ba29 1268 return recipSz;
Vanger 0:b86d15c6ba29 1269 }
Vanger 0:b86d15c6ba29 1270 recipSetSz = SetSet(recipSz, recipSet);
Vanger 0:b86d15c6ba29 1271
Vanger 0:b86d15c6ba29 1272 /* generate IV for block cipher */
Vanger 0:b86d15c6ba29 1273 ret = RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 1274 if (ret != 0) {
Vanger 0:b86d15c6ba29 1275 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1276 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1277 #endif
Vanger 0:b86d15c6ba29 1278 return ret;
Vanger 0:b86d15c6ba29 1279 }
Vanger 0:b86d15c6ba29 1280
Vanger 0:b86d15c6ba29 1281 /* EncryptedContentInfo */
Vanger 0:b86d15c6ba29 1282 contentTypeSz = SetContentType(pkcs7->contentOID, contentType);
Vanger 0:b86d15c6ba29 1283 if (contentTypeSz == 0) {
Vanger 0:b86d15c6ba29 1284 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1285 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1286 #endif
Vanger 0:b86d15c6ba29 1287 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1288 }
Vanger 0:b86d15c6ba29 1289
Vanger 0:b86d15c6ba29 1290 /* allocate encrypted content buffer, pad if necessary, PKCS#7 padding */
Vanger 0:b86d15c6ba29 1291 padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 1292 desOutSz = pkcs7->contentSz + padSz;
Vanger 0:b86d15c6ba29 1293
Vanger 0:b86d15c6ba29 1294 if (padSz != 0) {
Vanger 0:b86d15c6ba29 1295 plain = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1296 if (plain == NULL) {
Vanger 0:b86d15c6ba29 1297 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1298 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1299 #endif
Vanger 0:b86d15c6ba29 1300 return MEMORY_E;
Vanger 0:b86d15c6ba29 1301 }
Vanger 0:b86d15c6ba29 1302 XMEMCPY(plain, pkcs7->content, pkcs7->contentSz);
Vanger 0:b86d15c6ba29 1303 dynamicFlag = 1;
Vanger 0:b86d15c6ba29 1304
Vanger 0:b86d15c6ba29 1305 for (i = 0; i < padSz; i++) {
Vanger 0:b86d15c6ba29 1306 plain[pkcs7->contentSz + i] = padSz;
Vanger 0:b86d15c6ba29 1307 }
Vanger 0:b86d15c6ba29 1308
Vanger 0:b86d15c6ba29 1309 } else {
Vanger 0:b86d15c6ba29 1310 plain = pkcs7->content;
Vanger 0:b86d15c6ba29 1311 desOutSz = pkcs7->contentSz;
Vanger 0:b86d15c6ba29 1312 }
Vanger 0:b86d15c6ba29 1313
Vanger 0:b86d15c6ba29 1314 encryptedContent = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1315 if (encryptedContent == NULL) {
Vanger 0:b86d15c6ba29 1316 if (dynamicFlag)
Vanger 0:b86d15c6ba29 1317 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1318 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1319 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1320 #endif
Vanger 0:b86d15c6ba29 1321 return MEMORY_E;
Vanger 0:b86d15c6ba29 1322 }
Vanger 0:b86d15c6ba29 1323
Vanger 0:b86d15c6ba29 1324 /* put together IV OCTET STRING */
Vanger 0:b86d15c6ba29 1325 ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString);
Vanger 0:b86d15c6ba29 1326
Vanger 0:b86d15c6ba29 1327 /* build up our ContentEncryptionAlgorithmIdentifier sequence,
Vanger 0:b86d15c6ba29 1328 * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */
Vanger 0:b86d15c6ba29 1329 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
Vanger 0:b86d15c6ba29 1330 blkType, ivOctetStringSz + DES_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 1331
Vanger 0:b86d15c6ba29 1332 if (contentEncAlgoSz == 0) {
Vanger 0:b86d15c6ba29 1333 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1334 if (dynamicFlag)
Vanger 0:b86d15c6ba29 1335 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1336 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1337 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1338 #endif
Vanger 0:b86d15c6ba29 1339 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1340 }
Vanger 0:b86d15c6ba29 1341
Vanger 0:b86d15c6ba29 1342 /* encrypt content */
Vanger 0:b86d15c6ba29 1343 if (pkcs7->encryptOID == DESb) {
Vanger 0:b86d15c6ba29 1344 Des des;
Vanger 0:b86d15c6ba29 1345
Vanger 0:b86d15c6ba29 1346 ret = Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
Vanger 0:b86d15c6ba29 1347
Vanger 0:b86d15c6ba29 1348 if (ret == 0)
Vanger 0:b86d15c6ba29 1349 Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
Vanger 0:b86d15c6ba29 1350
Vanger 0:b86d15c6ba29 1351 if (ret != 0) {
Vanger 0:b86d15c6ba29 1352 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1353 if (dynamicFlag)
Vanger 0:b86d15c6ba29 1354 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1355 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1356 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1357 #endif
Vanger 0:b86d15c6ba29 1358 return ret;
Vanger 0:b86d15c6ba29 1359 }
Vanger 0:b86d15c6ba29 1360 }
Vanger 0:b86d15c6ba29 1361 else if (pkcs7->encryptOID == DES3b) {
Vanger 0:b86d15c6ba29 1362 Des3 des3;
Vanger 0:b86d15c6ba29 1363
Vanger 0:b86d15c6ba29 1364 ret = Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);
Vanger 0:b86d15c6ba29 1365
Vanger 0:b86d15c6ba29 1366 if (ret == 0)
Vanger 0:b86d15c6ba29 1367 ret = Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);
Vanger 0:b86d15c6ba29 1368
Vanger 0:b86d15c6ba29 1369 if (ret != 0) {
Vanger 0:b86d15c6ba29 1370 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1371 if (dynamicFlag)
Vanger 0:b86d15c6ba29 1372 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1373 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1374 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1375 #endif
Vanger 0:b86d15c6ba29 1376 return ret;
Vanger 0:b86d15c6ba29 1377 }
Vanger 0:b86d15c6ba29 1378 }
Vanger 0:b86d15c6ba29 1379
Vanger 0:b86d15c6ba29 1380 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
Vanger 0:b86d15c6ba29 1381 desOutSz, encContentOctet);
Vanger 0:b86d15c6ba29 1382
Vanger 0:b86d15c6ba29 1383 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
Vanger 0:b86d15c6ba29 1384 ivOctetStringSz + DES_BLOCK_SIZE +
Vanger 0:b86d15c6ba29 1385 encContentOctetSz + desOutSz, encContentSeq);
Vanger 0:b86d15c6ba29 1386
Vanger 0:b86d15c6ba29 1387 /* keep track of sizes for outer wrapper layering */
Vanger 0:b86d15c6ba29 1388 totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
Vanger 0:b86d15c6ba29 1389 contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE +
Vanger 0:b86d15c6ba29 1390 encContentOctetSz + desOutSz;
Vanger 0:b86d15c6ba29 1391
Vanger 0:b86d15c6ba29 1392 /* EnvelopedData */
Vanger 0:b86d15c6ba29 1393 envDataSeqSz = SetSequence(totalSz, envDataSeq);
Vanger 0:b86d15c6ba29 1394 totalSz += envDataSeqSz;
Vanger 0:b86d15c6ba29 1395
Vanger 0:b86d15c6ba29 1396 /* outer content */
Vanger 0:b86d15c6ba29 1397 outerContentSz = SetExplicit(0, totalSz, outerContent);
Vanger 0:b86d15c6ba29 1398 totalSz += outerContentTypeSz;
Vanger 0:b86d15c6ba29 1399 totalSz += outerContentSz;
Vanger 0:b86d15c6ba29 1400
Vanger 0:b86d15c6ba29 1401 /* ContentInfo */
Vanger 0:b86d15c6ba29 1402 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
Vanger 0:b86d15c6ba29 1403 totalSz += contentInfoSeqSz;
Vanger 0:b86d15c6ba29 1404
Vanger 0:b86d15c6ba29 1405 if (totalSz > (int)outputSz) {
Vanger 0:b86d15c6ba29 1406 CYASSL_MSG("Pkcs7_encrypt output buffer too small");
Vanger 0:b86d15c6ba29 1407 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1408 if (dynamicFlag)
Vanger 0:b86d15c6ba29 1409 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1410 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1411 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1412 #endif
Vanger 0:b86d15c6ba29 1413 return BUFFER_E;
Vanger 0:b86d15c6ba29 1414 }
Vanger 0:b86d15c6ba29 1415
Vanger 0:b86d15c6ba29 1416 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
Vanger 0:b86d15c6ba29 1417 idx += contentInfoSeqSz;
Vanger 0:b86d15c6ba29 1418 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
Vanger 0:b86d15c6ba29 1419 idx += outerContentTypeSz;
Vanger 0:b86d15c6ba29 1420 XMEMCPY(output + idx, outerContent, outerContentSz);
Vanger 0:b86d15c6ba29 1421 idx += outerContentSz;
Vanger 0:b86d15c6ba29 1422 XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
Vanger 0:b86d15c6ba29 1423 idx += envDataSeqSz;
Vanger 0:b86d15c6ba29 1424 XMEMCPY(output + idx, ver, verSz);
Vanger 0:b86d15c6ba29 1425 idx += verSz;
Vanger 0:b86d15c6ba29 1426 XMEMCPY(output + idx, recipSet, recipSetSz);
Vanger 0:b86d15c6ba29 1427 idx += recipSetSz;
Vanger 0:b86d15c6ba29 1428 XMEMCPY(output + idx, recip, recipSz);
Vanger 0:b86d15c6ba29 1429 idx += recipSz;
Vanger 0:b86d15c6ba29 1430 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
Vanger 0:b86d15c6ba29 1431 idx += encContentSeqSz;
Vanger 0:b86d15c6ba29 1432 XMEMCPY(output + idx, contentType, contentTypeSz);
Vanger 0:b86d15c6ba29 1433 idx += contentTypeSz;
Vanger 0:b86d15c6ba29 1434 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
Vanger 0:b86d15c6ba29 1435 idx += contentEncAlgoSz;
Vanger 0:b86d15c6ba29 1436 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
Vanger 0:b86d15c6ba29 1437 idx += ivOctetStringSz;
Vanger 0:b86d15c6ba29 1438 XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE);
Vanger 0:b86d15c6ba29 1439 idx += DES_BLOCK_SIZE;
Vanger 0:b86d15c6ba29 1440 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
Vanger 0:b86d15c6ba29 1441 idx += encContentOctetSz;
Vanger 0:b86d15c6ba29 1442 XMEMCPY(output + idx, encryptedContent, desOutSz);
Vanger 0:b86d15c6ba29 1443 idx += desOutSz;
Vanger 0:b86d15c6ba29 1444
Vanger 0:b86d15c6ba29 1445 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
Vanger 0:b86d15c6ba29 1446 FreeRng(&rng);
Vanger 0:b86d15c6ba29 1447 #endif
Vanger 0:b86d15c6ba29 1448
Vanger 0:b86d15c6ba29 1449 XMEMSET(contentKeyPlain, 0, MAX_CONTENT_KEY_LEN);
Vanger 0:b86d15c6ba29 1450
Vanger 0:b86d15c6ba29 1451 if (dynamicFlag)
Vanger 0:b86d15c6ba29 1452 XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1453 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1454
Vanger 0:b86d15c6ba29 1455 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1456 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1457 #endif
Vanger 0:b86d15c6ba29 1458
Vanger 0:b86d15c6ba29 1459 return idx;
Vanger 0:b86d15c6ba29 1460 }
Vanger 0:b86d15c6ba29 1461
Vanger 0:b86d15c6ba29 1462 /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
Vanger 0:b86d15c6ba29 1463 CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
Vanger 0:b86d15c6ba29 1464 word32 pkiMsgSz, byte* output,
Vanger 0:b86d15c6ba29 1465 word32 outputSz)
Vanger 0:b86d15c6ba29 1466 {
Vanger 0:b86d15c6ba29 1467 int recipFound = 0;
Vanger 0:b86d15c6ba29 1468 int ret, version, length;
Vanger 0:b86d15c6ba29 1469 word32 savedIdx = 0, idx = 0;
Vanger 0:b86d15c6ba29 1470 word32 contentType, encOID;
Vanger 0:b86d15c6ba29 1471 byte issuerHash[SHA_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 1472
Vanger 0:b86d15c6ba29 1473 int encryptedKeySz, keySz;
Vanger 0:b86d15c6ba29 1474 byte tmpIv[DES_BLOCK_SIZE];
Vanger 0:b86d15c6ba29 1475 byte* decryptedKey = NULL;
Vanger 0:b86d15c6ba29 1476
Vanger 0:b86d15c6ba29 1477 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1478 mp_int* serialNum;
Vanger 0:b86d15c6ba29 1479 byte* encryptedKey;
Vanger 0:b86d15c6ba29 1480 RsaKey* privKey;
Vanger 0:b86d15c6ba29 1481 #else
Vanger 0:b86d15c6ba29 1482 mp_int stack_serialNum;
Vanger 0:b86d15c6ba29 1483 mp_int* serialNum = &stack_serialNum;
Vanger 0:b86d15c6ba29 1484 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
Vanger 0:b86d15c6ba29 1485
Vanger 0:b86d15c6ba29 1486 RsaKey stack_privKey;
Vanger 0:b86d15c6ba29 1487 RsaKey* privKey = &stack_privKey;
Vanger 0:b86d15c6ba29 1488 #endif
Vanger 0:b86d15c6ba29 1489 int encryptedContentSz;
Vanger 0:b86d15c6ba29 1490 byte padLen;
Vanger 0:b86d15c6ba29 1491 byte* encryptedContent = NULL;
Vanger 0:b86d15c6ba29 1492
Vanger 0:b86d15c6ba29 1493 if (pkcs7 == NULL || pkcs7->singleCert == NULL ||
Vanger 0:b86d15c6ba29 1494 pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL ||
Vanger 0:b86d15c6ba29 1495 pkcs7->privateKeySz == 0)
Vanger 0:b86d15c6ba29 1496 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1497
Vanger 0:b86d15c6ba29 1498 if (pkiMsg == NULL || pkiMsgSz == 0 ||
Vanger 0:b86d15c6ba29 1499 output == NULL || outputSz == 0)
Vanger 0:b86d15c6ba29 1500 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1501
Vanger 0:b86d15c6ba29 1502 /* read past ContentInfo, verify type is envelopedData */
Vanger 0:b86d15c6ba29 1503 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 1504 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1505
Vanger 0:b86d15c6ba29 1506 if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 1507 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1508
Vanger 0:b86d15c6ba29 1509 if (contentType != ENVELOPED_DATA) {
Vanger 0:b86d15c6ba29 1510 CYASSL_MSG("PKCS#7 input not of type EnvelopedData");
Vanger 0:b86d15c6ba29 1511 return PKCS7_OID_E;
Vanger 0:b86d15c6ba29 1512 }
Vanger 0:b86d15c6ba29 1513
Vanger 0:b86d15c6ba29 1514 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
Vanger 0:b86d15c6ba29 1515 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1516
Vanger 0:b86d15c6ba29 1517 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 1518 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1519
Vanger 0:b86d15c6ba29 1520 /* remove EnvelopedData and version */
Vanger 0:b86d15c6ba29 1521 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 1522 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1523
Vanger 0:b86d15c6ba29 1524 if (GetMyVersion(pkiMsg, &idx, &version) < 0)
Vanger 0:b86d15c6ba29 1525 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1526
Vanger 0:b86d15c6ba29 1527 if (version != 0) {
Vanger 0:b86d15c6ba29 1528 CYASSL_MSG("PKCS#7 envelopedData needs to be of version 0");
Vanger 0:b86d15c6ba29 1529 return ASN_VERSION_E;
Vanger 0:b86d15c6ba29 1530 }
Vanger 0:b86d15c6ba29 1531
Vanger 0:b86d15c6ba29 1532 /* walk through RecipientInfo set, find correct recipient */
Vanger 0:b86d15c6ba29 1533 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
Vanger 0:b86d15c6ba29 1534 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1535
Vanger 0:b86d15c6ba29 1536 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1537 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL,
Vanger 0:b86d15c6ba29 1538 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1539 if (encryptedKey == NULL)
Vanger 0:b86d15c6ba29 1540 return MEMORY_E;
Vanger 0:b86d15c6ba29 1541 #endif
Vanger 0:b86d15c6ba29 1542
Vanger 0:b86d15c6ba29 1543 savedIdx = idx;
Vanger 0:b86d15c6ba29 1544 recipFound = 0;
Vanger 0:b86d15c6ba29 1545
Vanger 0:b86d15c6ba29 1546 /* when looking for next recipient, use first sequence and version to
Vanger 0:b86d15c6ba29 1547 * indicate there is another, if not, move on */
Vanger 0:b86d15c6ba29 1548 while(recipFound == 0) {
Vanger 0:b86d15c6ba29 1549
Vanger 0:b86d15c6ba29 1550 /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
Vanger 0:b86d15c6ba29 1551 * last good saved one */
Vanger 0:b86d15c6ba29 1552 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1553 idx = savedIdx;
Vanger 0:b86d15c6ba29 1554 break;
Vanger 0:b86d15c6ba29 1555 }
Vanger 0:b86d15c6ba29 1556
Vanger 0:b86d15c6ba29 1557 if (GetMyVersion(pkiMsg, &idx, &version) < 0) {
Vanger 0:b86d15c6ba29 1558 idx = savedIdx;
Vanger 0:b86d15c6ba29 1559 break;
Vanger 0:b86d15c6ba29 1560 }
Vanger 0:b86d15c6ba29 1561
Vanger 0:b86d15c6ba29 1562 if (version != 0) {
Vanger 0:b86d15c6ba29 1563 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1564 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1565 #endif
Vanger 0:b86d15c6ba29 1566 return ASN_VERSION_E;
Vanger 0:b86d15c6ba29 1567 }
Vanger 0:b86d15c6ba29 1568
Vanger 0:b86d15c6ba29 1569 /* remove IssuerAndSerialNumber */
Vanger 0:b86d15c6ba29 1570 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1571 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1572 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1573 #endif
Vanger 0:b86d15c6ba29 1574 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1575 }
Vanger 0:b86d15c6ba29 1576
Vanger 0:b86d15c6ba29 1577 if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1578 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1579 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1580 #endif
Vanger 0:b86d15c6ba29 1581 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1582 }
Vanger 0:b86d15c6ba29 1583
Vanger 0:b86d15c6ba29 1584 /* if we found correct recipient, issuer hashes will match */
Vanger 0:b86d15c6ba29 1585 if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) {
Vanger 0:b86d15c6ba29 1586 recipFound = 1;
Vanger 0:b86d15c6ba29 1587 }
Vanger 0:b86d15c6ba29 1588
Vanger 0:b86d15c6ba29 1589 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1590 serialNum = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
Vanger 0:b86d15c6ba29 1591 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1592 if (serialNum == NULL) {
Vanger 0:b86d15c6ba29 1593 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1594 return MEMORY_E;
Vanger 0:b86d15c6ba29 1595 }
Vanger 0:b86d15c6ba29 1596 #endif
Vanger 0:b86d15c6ba29 1597
Vanger 0:b86d15c6ba29 1598 if (GetInt(serialNum, pkiMsg, &idx, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1599 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1600 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1601 XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1602 #endif
Vanger 0:b86d15c6ba29 1603 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1604 }
Vanger 0:b86d15c6ba29 1605
Vanger 0:b86d15c6ba29 1606 mp_clear(serialNum);
Vanger 0:b86d15c6ba29 1607
Vanger 0:b86d15c6ba29 1608 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1609 XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1610 #endif
Vanger 0:b86d15c6ba29 1611
Vanger 0:b86d15c6ba29 1612 if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1613 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1614 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1615 #endif
Vanger 0:b86d15c6ba29 1616 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1617 }
Vanger 0:b86d15c6ba29 1618
Vanger 0:b86d15c6ba29 1619 /* key encryption algorithm must be RSA for now */
Vanger 0:b86d15c6ba29 1620 if (encOID != RSAk) {
Vanger 0:b86d15c6ba29 1621 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1622 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1623 #endif
Vanger 0:b86d15c6ba29 1624 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 1625 }
Vanger 0:b86d15c6ba29 1626
Vanger 0:b86d15c6ba29 1627 /* read encryptedKey */
Vanger 0:b86d15c6ba29 1628 if (pkiMsg[idx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 1629 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1630 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1631 #endif
Vanger 0:b86d15c6ba29 1632 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1633 }
Vanger 0:b86d15c6ba29 1634
Vanger 0:b86d15c6ba29 1635 if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1636 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1637 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1638 #endif
Vanger 0:b86d15c6ba29 1639 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1640 }
Vanger 0:b86d15c6ba29 1641
Vanger 0:b86d15c6ba29 1642 if (recipFound == 1)
Vanger 0:b86d15c6ba29 1643 XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz);
Vanger 0:b86d15c6ba29 1644 idx += encryptedKeySz;
Vanger 0:b86d15c6ba29 1645
Vanger 0:b86d15c6ba29 1646 /* update good idx */
Vanger 0:b86d15c6ba29 1647 savedIdx = idx;
Vanger 0:b86d15c6ba29 1648 }
Vanger 0:b86d15c6ba29 1649
Vanger 0:b86d15c6ba29 1650 if (recipFound == 0) {
Vanger 0:b86d15c6ba29 1651 CYASSL_MSG("No recipient found in envelopedData that matches input");
Vanger 0:b86d15c6ba29 1652 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1653 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1654 #endif
Vanger 0:b86d15c6ba29 1655 return PKCS7_RECIP_E;
Vanger 0:b86d15c6ba29 1656 }
Vanger 0:b86d15c6ba29 1657
Vanger 0:b86d15c6ba29 1658 /* remove EncryptedContentInfo */
Vanger 0:b86d15c6ba29 1659 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1660 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1661 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1662 #endif
Vanger 0:b86d15c6ba29 1663 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1664 }
Vanger 0:b86d15c6ba29 1665
Vanger 0:b86d15c6ba29 1666 if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1667 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1668 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1669 #endif
Vanger 0:b86d15c6ba29 1670 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1671 }
Vanger 0:b86d15c6ba29 1672
Vanger 0:b86d15c6ba29 1673 if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1674 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1675 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1676 #endif
Vanger 0:b86d15c6ba29 1677 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1678 }
Vanger 0:b86d15c6ba29 1679
Vanger 0:b86d15c6ba29 1680 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
Vanger 0:b86d15c6ba29 1681 if (pkiMsg[idx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 1682 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1683 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1684 #endif
Vanger 0:b86d15c6ba29 1685 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1686 }
Vanger 0:b86d15c6ba29 1687
Vanger 0:b86d15c6ba29 1688 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1689 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1690 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1691 #endif
Vanger 0:b86d15c6ba29 1692 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1693 }
Vanger 0:b86d15c6ba29 1694
Vanger 0:b86d15c6ba29 1695 if (length != DES_BLOCK_SIZE) {
Vanger 0:b86d15c6ba29 1696 CYASSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE");
Vanger 0:b86d15c6ba29 1697 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1698 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1699 #endif
Vanger 0:b86d15c6ba29 1700 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1701 }
Vanger 0:b86d15c6ba29 1702
Vanger 0:b86d15c6ba29 1703 XMEMCPY(tmpIv, &pkiMsg[idx], length);
Vanger 0:b86d15c6ba29 1704 idx += length;
Vanger 0:b86d15c6ba29 1705
Vanger 0:b86d15c6ba29 1706 /* read encryptedContent, cont[0] */
Vanger 0:b86d15c6ba29 1707 if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
Vanger 0:b86d15c6ba29 1708 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1709 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1710 #endif
Vanger 0:b86d15c6ba29 1711 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1712 }
Vanger 0:b86d15c6ba29 1713
Vanger 0:b86d15c6ba29 1714 if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) {
Vanger 0:b86d15c6ba29 1715 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1716 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1717 #endif
Vanger 0:b86d15c6ba29 1718 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1719 }
Vanger 0:b86d15c6ba29 1720
Vanger 0:b86d15c6ba29 1721 encryptedContent = (byte*)XMALLOC(encryptedContentSz, NULL,
Vanger 0:b86d15c6ba29 1722 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1723 if (encryptedContent == NULL) {
Vanger 0:b86d15c6ba29 1724 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1725 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1726 #endif
Vanger 0:b86d15c6ba29 1727 return MEMORY_E;
Vanger 0:b86d15c6ba29 1728 }
Vanger 0:b86d15c6ba29 1729
Vanger 0:b86d15c6ba29 1730 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
Vanger 0:b86d15c6ba29 1731
Vanger 0:b86d15c6ba29 1732 /* load private key */
Vanger 0:b86d15c6ba29 1733 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1734 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1735 if (privKey == NULL) {
Vanger 0:b86d15c6ba29 1736 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1737 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E;
Vanger 0:b86d15c6ba29 1738 }
Vanger 0:b86d15c6ba29 1739 #endif
Vanger 0:b86d15c6ba29 1740
Vanger 0:b86d15c6ba29 1741 ret = InitRsaKey(privKey, 0);
Vanger 0:b86d15c6ba29 1742 if (ret != 0) {
Vanger 0:b86d15c6ba29 1743 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1744 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1745 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1746 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1747 #endif
Vanger 0:b86d15c6ba29 1748 return ret;
Vanger 0:b86d15c6ba29 1749 }
Vanger 0:b86d15c6ba29 1750
Vanger 0:b86d15c6ba29 1751 idx = 0;
Vanger 0:b86d15c6ba29 1752
Vanger 0:b86d15c6ba29 1753 ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
Vanger 0:b86d15c6ba29 1754 pkcs7->privateKeySz);
Vanger 0:b86d15c6ba29 1755 if (ret != 0) {
Vanger 0:b86d15c6ba29 1756 CYASSL_MSG("Failed to decode RSA private key");
Vanger 0:b86d15c6ba29 1757 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1758 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1759 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1760 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1761 #endif
Vanger 0:b86d15c6ba29 1762 return ret;
Vanger 0:b86d15c6ba29 1763 }
Vanger 0:b86d15c6ba29 1764
Vanger 0:b86d15c6ba29 1765 /* decrypt encryptedKey */
Vanger 0:b86d15c6ba29 1766 keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
Vanger 0:b86d15c6ba29 1767 &decryptedKey, privKey);
Vanger 0:b86d15c6ba29 1768 FreeRsaKey(privKey);
Vanger 0:b86d15c6ba29 1769
Vanger 0:b86d15c6ba29 1770 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1771 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1772 #endif
Vanger 0:b86d15c6ba29 1773
Vanger 0:b86d15c6ba29 1774 if (keySz <= 0) {
Vanger 0:b86d15c6ba29 1775 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1776 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1777 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1778 #endif
Vanger 0:b86d15c6ba29 1779 return keySz;
Vanger 0:b86d15c6ba29 1780 }
Vanger 0:b86d15c6ba29 1781
Vanger 0:b86d15c6ba29 1782 /* decrypt encryptedContent */
Vanger 0:b86d15c6ba29 1783 if (encOID == DESb) {
Vanger 0:b86d15c6ba29 1784 Des des;
Vanger 0:b86d15c6ba29 1785 ret = Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
Vanger 0:b86d15c6ba29 1786
Vanger 0:b86d15c6ba29 1787 if (ret == 0)
Vanger 0:b86d15c6ba29 1788 Des_CbcDecrypt(&des, encryptedContent, encryptedContent,
Vanger 0:b86d15c6ba29 1789 encryptedContentSz);
Vanger 0:b86d15c6ba29 1790
Vanger 0:b86d15c6ba29 1791 if (ret != 0) {
Vanger 0:b86d15c6ba29 1792 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1793 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1794 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1795 #endif
Vanger 0:b86d15c6ba29 1796 return ret;
Vanger 0:b86d15c6ba29 1797 }
Vanger 0:b86d15c6ba29 1798 }
Vanger 0:b86d15c6ba29 1799 else if (encOID == DES3b) {
Vanger 0:b86d15c6ba29 1800 Des3 des;
Vanger 0:b86d15c6ba29 1801 ret = Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
Vanger 0:b86d15c6ba29 1802 if (ret == 0)
Vanger 0:b86d15c6ba29 1803 ret = Des3_CbcDecrypt(&des, encryptedContent, encryptedContent,
Vanger 0:b86d15c6ba29 1804 encryptedContentSz);
Vanger 0:b86d15c6ba29 1805
Vanger 0:b86d15c6ba29 1806 if (ret != 0) {
Vanger 0:b86d15c6ba29 1807 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1808 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1809 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1810 #endif
Vanger 0:b86d15c6ba29 1811 return ret;
Vanger 0:b86d15c6ba29 1812 }
Vanger 0:b86d15c6ba29 1813 } else {
Vanger 0:b86d15c6ba29 1814 CYASSL_MSG("Unsupported content encryption OID type");
Vanger 0:b86d15c6ba29 1815 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1816 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1817 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1818 #endif
Vanger 0:b86d15c6ba29 1819 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 1820 }
Vanger 0:b86d15c6ba29 1821
Vanger 0:b86d15c6ba29 1822 padLen = encryptedContent[encryptedContentSz-1];
Vanger 0:b86d15c6ba29 1823
Vanger 0:b86d15c6ba29 1824 /* copy plaintext to output */
Vanger 0:b86d15c6ba29 1825 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
Vanger 0:b86d15c6ba29 1826
Vanger 0:b86d15c6ba29 1827 /* free memory, zero out keys */
Vanger 0:b86d15c6ba29 1828 XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
Vanger 0:b86d15c6ba29 1829 XMEMSET(encryptedContent, 0, encryptedContentSz);
Vanger 0:b86d15c6ba29 1830 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1831 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1832 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1833 #endif
Vanger 0:b86d15c6ba29 1834
Vanger 0:b86d15c6ba29 1835 return encryptedContentSz - padLen;
Vanger 0:b86d15c6ba29 1836 }
Vanger 0:b86d15c6ba29 1837
Vanger 0:b86d15c6ba29 1838
Vanger 0:b86d15c6ba29 1839 #else /* HAVE_PKCS7 */
Vanger 0:b86d15c6ba29 1840
Vanger 0:b86d15c6ba29 1841
Vanger 0:b86d15c6ba29 1842 #ifdef _MSC_VER
Vanger 0:b86d15c6ba29 1843 /* 4206 warning for blank file */
Vanger 0:b86d15c6ba29 1844 #pragma warning(disable: 4206)
Vanger 0:b86d15c6ba29 1845 #endif
Vanger 0:b86d15c6ba29 1846
Vanger 0:b86d15c6ba29 1847
Vanger 0:b86d15c6ba29 1848 #endif /* HAVE_PKCS7 */
Vanger 0:b86d15c6ba29 1849