Fork of CyaSSL for my specific settings

Dependents:   CyaSSL_Example

Fork of CyaSSL by wolf SSL

Committer:
wolfSSL
Date:
Sat Jul 12 07:18:23 2014 +0000
Revision:
0:1239e9b70ca2
CyaSSL 3.0.0;

Who changed what in which revision?

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