SSL/TLS Library

Dependents:  

CyaSSL is SSL/TLS library for embedded systems.

wolfssl.com

Committer:
wolfSSL
Date:
Sun Apr 20 12:40:57 2014 +0000
Revision:
0:9d17e4342598
CyaSSL SSL/TLS Library 2.9.4;

Who changed what in which revision?

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