diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index fafaf3f21..e3ab7e545 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -646,6 +646,52 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx) return *number; } + + +/* Set small integer, 32 bits or less. DER encoding with no leading 0s + * returns total amount written including ASN tag and length byte on success */ +static int SetShortInt(byte* input, word32* inOutIdx, word32 number, + word32 maxIdx) +{ + word32 idx = *inOutIdx; + word32 len = 0; + int i; + byte ar[MAX_LENGTH_SZ]; + + /* check for room for type and length bytes */ + if ((idx + 2) > maxIdx) + return BUFFER_E; + + input[idx++] = ASN_INTEGER; + idx++; /* place holder for length byte */ + if (MAX_LENGTH_SZ + idx > maxIdx) + return ASN_PARSE_E; + + /* find first non zero byte */ + XMEMSET(ar, 0, MAX_LENGTH_SZ); + c32toa(number, ar); + for (i = 0; i < MAX_LENGTH_SZ; i++) { + if (ar[i] != 0) { + break; + } + } + + /* handle case of 0 */ + if (i == MAX_LENGTH_SZ) { + input[idx++] = 0; len++; + } + + for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) { + input[idx++] = ar[i]; len++; + } + + /* jump back to beginning of input buffer using unaltered inOutIdx value + * and set number of bytes for integer, then update the index value */ + input[*inOutIdx + 1] = (byte)len; + *inOutIdx = idx; + + return len + 2; /* size of integer bytes plus ASN TAG and length byte */ +} #endif /* !NO_PWDBASED */ /* May not have one, not an error */ @@ -2394,10 +2440,6 @@ static int CheckAlgo(int first, int second, int* id, int* version) return 0; #endif #ifndef NO_DES3 - case PBE_SHA1_DES: - *id = PBE_SHA1_DES; - *version = PKCS12v1; - return 0; case PBE_SHA1_DES3: *id = PBE_SHA1_DES3; *version = PKCS12v1; @@ -2595,11 +2637,9 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, MAX_LENGTH_SZ + MAX_SHORT_SZ + 1) return BUFFER_E; - sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0); - totalSz += sz; inOutIdx += sz; - if (version == PKCS5v2) { WOLFSSL_MSG("PKCS5v2 Not supported yet\n"); + return ASN_VERSION_E; } if (salt == NULL || saltSz <= 0) { @@ -2624,6 +2664,7 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, /* leave room for a sequence (contains salt and iterations int) */ inOutIdx += MAX_SEQ_SZ; sz = 0; + inOutIdx += MAX_ALGO_SZ; /* place salt in buffer */ out[inOutIdx++] = ASN_OCTET_STRING; sz++; @@ -2633,19 +2674,23 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, inOutIdx += saltSz; sz += saltSz; /* place iteration count in buffer */ - out[inOutIdx++] = ASN_INTEGER; sz++; - out[inOutIdx++] = sizeof(word32); sz++; - out[inOutIdx++] = (itt >> 24) & 0xFF; - out[inOutIdx++] = (itt >> 16) & 0xFF; - out[inOutIdx++] = (itt >> 8 ) & 0xFF; - out[inOutIdx++] = itt & 0xFF; - sz += 4; + ret = SetShortInt(out, &inOutIdx, itt, *outSz); + if (ret < 0) { + return ret; + } + sz += (word32)ret; /* wind back index and set sequence then clean up buffer */ inOutIdx -= (sz + MAX_SEQ_SZ); tmpSz = SetSequence(sz, out + inOutIdx); XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz); - inOutIdx += tmpSz + sz; totalSz += tmpSz + sz; + totalSz += tmpSz + sz; sz += tmpSz; + + /* add in algo ID */ + inOutIdx -= MAX_ALGO_SZ; + tmpSz = SetAlgoID(id, out + inOutIdx, oidPBEType, sz); + XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz); + totalSz += tmpSz; inOutIdx += tmpSz + sz; /* octet string containing encrypted key */ out[inOutIdx++] = ASN_OCTET_STRING; totalSz++; @@ -3036,12 +3081,13 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, tmpIdx += saltSz; /* place itteration setting in buffer */ - out[tmpIdx++] = ASN_INTEGER; - out[tmpIdx++] = sizeof(word32); - out[tmpIdx++] = (itt >> 24) & 0xFF; - out[tmpIdx++] = (itt >> 16) & 0xFF; - out[tmpIdx++] = (itt >> 8) & 0xFF; - out[tmpIdx++] = itt & 0xFF; + ret = SetShortInt(out, &tmpIdx, itt, *outSz); + if (ret < 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return ret; + } /* rewind and place sequence */ sz = tmpIdx - inOutIdx - MAX_SEQ_SZ; diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 80f80d5c5..aebf2ed58 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1150,7 +1150,7 @@ static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng, { void* heap; word32 tmpIdx = 0; - int vPKCS = 1; /* PKCS#12 is always set to 1 */ + int vPKCS = 1; /* PKCS#12 default set to 1 */ word32 sz; word32 totalSz = 0; int ret; @@ -1190,6 +1190,11 @@ static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng, else { WOLFSSL_MSG("creating PKCS12 Shrouded Key Bag"); + if (vAlgo == PBE_SHA1_DES) { + vPKCS = PKCS5; + vAlgo = 10; + } + ret = UnTraditionalEnc(key, keySz, out + tmpIdx, &sz, pass, passSz, vPKCS, vAlgo, NULL, 0, itt, rng, heap); }