@@ -3460,6 +3460,70 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output)
34603460#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
34613461
34623462#ifdef ASN_BER_TO_DER
3463+
3464+ #define BER_OCTET_LENGTH 4096
3465+
3466+ /* sets the terminating 0x00 0x00 at the end of an indefinite length
3467+ * returns the number of bytes written */
3468+ word32 SetIndefEnd(byte* output)
3469+ {
3470+ byte terminate[ASN_INDEF_END_SZ] = { 0x00, 0x00 };
3471+
3472+ if (output != NULL) {
3473+ XMEMCPY(output, terminate, ASN_INDEF_END_SZ);
3474+ }
3475+
3476+ return (word32)ASN_INDEF_END_SZ;
3477+ }
3478+
3479+
3480+ /* Breaks an octet string up into chunks for use with streaming
3481+ * returns 0 on success and updates idx */
3482+ int StreamOctetString(const byte* inBuf, word32 inBufSz, byte* out, word32* outSz,
3483+ word32* idx)
3484+ {
3485+ word32 i = 0;
3486+ word32 outIdx = *idx;
3487+ byte* tmp = out;
3488+
3489+ if (tmp) tmp += outIdx;
3490+
3491+ while (i < inBufSz) {
3492+ word32 ret, sz;
3493+
3494+ sz = BER_OCTET_LENGTH;
3495+
3496+ if ((sz + i) > inBufSz) {
3497+ sz = inBufSz - i;
3498+ }
3499+
3500+ ret = SetOctetString(sz, tmp);
3501+ if (ret > 0) {
3502+ outIdx += ret;
3503+ }
3504+
3505+ if (tmp) {
3506+ if ((word32)ret + sz + i + outIdx > *outSz) {
3507+ return BUFFER_E;
3508+ }
3509+ XMEMCPY(tmp + ret, inBuf + i, sz);
3510+ tmp += sz + ret;
3511+ }
3512+ outIdx += sz;
3513+ i += sz;
3514+ }
3515+
3516+ if (tmp) {
3517+ *idx = outIdx;
3518+ return 0;
3519+ }
3520+ else {
3521+ *outSz = outIdx;
3522+ return LENGTH_ONLY_E;
3523+ }
3524+ }
3525+
3526+
34633527/* Convert BER to DER */
34643528
34653529/* Pull informtation from the ASN.1 BER encoded item header */
@@ -15334,21 +15398,34 @@ word32 SetLength(word32 length, byte* output)
1533415398 return i;
1533515399}
1533615400
15401+ word32 SetLengthEx(word32 length, byte* output, byte isIndef)
15402+ {
15403+ if (isIndef) {
15404+ if (output != NULL) {
15405+ output[0] = ASN_INDEF_LENGTH;
15406+ }
15407+ return 1;
15408+ }
15409+ else {
15410+ return SetLength(length, output);
15411+ }
15412+ }
1533715413/* Encode a DER header - type/tag and length.
1533815414 *
1533915415 * @param [in] tag DER tag of ASN.1 item.
1534015416 * @param [in] len Length of data in ASN.1 item.
1534115417 * @param [out] output Buffer to encode into.
1534215418 * @return Number of bytes encoded.
1534315419 */
15344- static word32 SetHeader(byte tag, word32 len, byte* output)
15420+ static word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef )
1534515421{
1534615422 if (output) {
1534715423 /* Encode tag first. */
1534815424 output[0] = tag;
1534915425 }
1535015426 /* Encode the length. */
15351- return SetLength(len, output ? output + ASN_TAG_SZ : NULL) + ASN_TAG_SZ;
15427+ return SetLengthEx(len, output ? output + ASN_TAG_SZ : NULL, isIndef) +
15428+ ASN_TAG_SZ;
1535215429}
1535315430
1535415431/* Encode a SEQUENCE header in DER.
@@ -15359,7 +15436,12 @@ static word32 SetHeader(byte tag, word32 len, byte* output)
1535915436 */
1536015437word32 SetSequence(word32 len, byte* output)
1536115438{
15362- return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output);
15439+ return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, 0);
15440+ }
15441+
15442+ word32 SetSequenceEx(word32 len, byte* output, byte isIndef)
15443+ {
15444+ return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, isIndef);
1536315445}
1536415446
1536515447/* Encode an OCTET STRING header in DER.
@@ -15370,7 +15452,14 @@ word32 SetSequence(word32 len, byte* output)
1537015452 */
1537115453word32 SetOctetString(word32 len, byte* output)
1537215454{
15373- return SetHeader(ASN_OCTET_STRING, len, output);
15455+ return SetHeader(ASN_OCTET_STRING, len, output, 0);
15456+ }
15457+
15458+ word32 SetOctetStringEx(word32 len, byte* output, byte indef)
15459+ {
15460+ if (indef)
15461+ return SetHeader(ASN_OCTET_STRING | ASN_CONSTRUCTED, len, output, indef);
15462+ return SetOctetString(len, output);
1537415463}
1537515464
1537615465/* Encode a SET header in DER.
@@ -15381,7 +15470,7 @@ word32 SetOctetString(word32 len, byte* output)
1538115470 */
1538215471word32 SetSet(word32 len, byte* output)
1538315472{
15384- return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output);
15473+ return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output, 0 );
1538515474}
1538615475
1538715476/* Encode an implicit context specific header in DER.
@@ -15394,11 +15483,23 @@ word32 SetSet(word32 len, byte* output)
1539415483 * @param [out] output Buffer to encode into.
1539515484 * @return Number of bytes encoded.
1539615485 */
15397- word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
15486+ word32 SetImplicit(byte tag, byte number, word32 len, byte* output, byte isIndef )
1539815487{
15399- tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
15400- | ASN_CONTEXT_SPECIFIC | number);
15401- return SetHeader(tag, len, output);
15488+ byte useIndef = 0;
15489+
15490+ if ((tag == ASN_OCTET_STRING) && isIndef) {
15491+ tag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
15492+ }
15493+ else {
15494+ tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ?
15495+ ASN_CONSTRUCTED : 0) | ASN_CONTEXT_SPECIFIC | number);
15496+ }
15497+
15498+ if (isIndef && (tag & ASN_CONSTRUCTED)) {
15499+ useIndef = 1;
15500+ }
15501+
15502+ return SetHeader(tag, len, output, useIndef);
1540215503}
1540315504
1540415505/* Encode an explicit context specific header in DER.
@@ -15410,10 +15511,10 @@ word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
1541015511 * @param [out] output Buffer to encode into.
1541115512 * @return Number of bytes encoded.
1541215513 */
15413- word32 SetExplicit(byte number, word32 len, byte* output)
15514+ word32 SetExplicit(byte number, word32 len, byte* output, byte isIndef )
1541415515{
1541515516 return SetHeader((byte)(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number),
15416- len, output);
15517+ len, output, isIndef );
1541715518}
1541815519
1541915520#if defined(OPENSSL_EXTRA)
@@ -15439,18 +15540,18 @@ word32 SetOthername(void *name, byte *output)
1543915540 nameSz = (word32)nm->value->value.utf8string->length;
1544015541
1544115542 len = nm->type_id->objSz +
15442- SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL) +
15443- SetHeader(CTC_UTF8, nameSz, NULL) + nameSz;
15543+ SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL, 0 ) +
15544+ SetHeader(CTC_UTF8, nameSz, NULL, 0 ) + nameSz;
1544415545
1544515546 if (output != NULL) {
1544615547 /* otherName OID */
1544715548 XMEMCPY(output, nm->type_id->obj, nm->type_id->objSz);
1544815549 output += nm->type_id->objSz;
1544915550
1545015551 output += SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2,
15451- output);
15552+ output, 0 );
1545215553
15453- output += SetHeader(CTC_UTF8, nameSz, output);
15554+ output += SetHeader(CTC_UTF8, nameSz, output, 0 );
1545415555
1545515556 XMEMCPY(output, nameStr, nameSz);
1545615557 }
@@ -34454,7 +34555,7 @@ int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
3445434555 /* pubKey */
3445534556 if (pubKey) {
3445634557 idx += SetHeader(ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY |
34457- 1, pubKeyLen, output + idx);
34558+ 1, pubKeyLen, output + idx, 0 );
3445834559 XMEMCPY(output + idx, pubKey, pubKeyLen);
3445934560 idx += pubKeyLen;
3446034561 }
@@ -36355,7 +36456,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
3635536456 */
3635636457 extSz = EncodeOcspRequestExtensions(req, extArray + 2,
3635736458 OCSP_NONCE_EXT_SZ);
36358- extSz += SetExplicit(2, extSz, extArray);
36459+ extSz += SetExplicit(2, extSz, extArray, 0 );
3635936460 }
3636036461
3636136462 totalSz = algoSz + issuerSz + issuerKeySz + snSz;
0 commit comments