Skip to content

Commit f119086

Browse files
authored
Merge pull request #8918 from kojiws/fix_asn_integer_export
Fix SetShortInt() not to export wrong DER
2 parents 80a234a + d76386f commit f119086

8 files changed

Lines changed: 239 additions & 8 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,6 +2636,7 @@ if(WOLFSSL_EXAMPLES)
26362636
tests/api/test_tls_ext.c
26372637
tests/api/test_tls.c
26382638
tests/api/test_x509.c
2639+
tests/api/test_asn.c
26392640
tests/srp.c
26402641
tests/suites.c
26412642
tests/w64wrapper.c

tests/api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@
332332
#include <tests/api/test_tls_ext.h>
333333
#include <tests/api/test_tls.h>
334334
#include <tests/api/test_x509.h>
335+
#include <tests/api/test_asn.h>
335336

336337
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
337338
!defined(NO_RSA) && !defined(SINGLE_THREADED) && \
@@ -67446,6 +67447,9 @@ TEST_CASE testCases[] = {
6744667447
/* x509 */
6744767448
TEST_X509_DECLS,
6744867449

67450+
/* ASN */
67451+
TEST_ASN_DECLS,
67452+
6744967453
/* PEM and DER APIs. */
6745067454
TEST_DECL(test_wc_PemToDer),
6745167455
TEST_DECL(test_wc_AllocDer),

tests/api/include.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ tests_unit_test_SOURCES += tests/api/test_tls_ext.c
5656
tests_unit_test_SOURCES += tests/api/test_tls.c
5757
# Certs
5858
tests_unit_test_SOURCES += tests/api/test_x509.c
59+
# ASN
60+
tests_unit_test_SOURCES += tests/api/test_asn.c
5961
endif
6062

6163
EXTRA_DIST += tests/api/api.h
@@ -108,4 +110,5 @@ EXTRA_DIST += tests/api/test_evp.h
108110
EXTRA_DIST += tests/api/test_tls_ext.h
109111
EXTRA_DIST += tests/api/test_tls.h
110112
EXTRA_DIST += tests/api/test_x509.h
113+
EXTRA_DIST += tests/api/test_asn.h
111114

tests/api/test_asn.c

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/* test_asn.c
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
#include <tests/unit.h>
23+
24+
#include <tests/api/test_asn.h>
25+
26+
static int test_SetShortInt_once(word32 val, byte* valDer, word32 valDerSz)
27+
{
28+
EXPECT_DECLS;
29+
30+
#ifndef NO_PWDBASED
31+
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS8) || \
32+
defined(HAVE_PKCS12)
33+
34+
byte outDer[MAX_SHORT_SZ];
35+
word32 outDerSz = 0;
36+
word32 inOutIdx = 0;
37+
word32 maxIdx = MAX_SHORT_SZ;
38+
39+
ExpectIntLE(2 + valDerSz, MAX_SHORT_SZ);
40+
ExpectIntEQ(outDerSz = SetShortInt(outDer, &inOutIdx, val, maxIdx),
41+
2 + valDerSz);
42+
ExpectIntEQ(outDer[0], ASN_INTEGER);
43+
ExpectIntEQ(outDer[1], valDerSz);
44+
ExpectIntEQ(XMEMCMP(outDer + 2, valDer, valDerSz), 0);
45+
46+
#endif /* !WOLFSSL_ASN_TEMPLATE || HAVE_PKCS8 || HAVE_PKCS12 */
47+
#endif /* !NO_PWDBASED */
48+
49+
(void)val;
50+
(void)valDer;
51+
(void)valDerSz;
52+
53+
return EXPECT_RESULT();
54+
}
55+
56+
int test_SetShortInt(void)
57+
{
58+
EXPECT_DECLS;
59+
60+
byte valDer[MAX_SHORT_SZ] = {0};
61+
62+
/* Corner tests for input size */
63+
{
64+
/* Input 1 byte min */
65+
valDer[0] = 0x00;
66+
EXPECT_TEST(test_SetShortInt_once(0x00, valDer, 1));
67+
68+
/* Input 1 byte max */
69+
valDer[0] = 0x00;
70+
valDer[1] = 0xff;
71+
EXPECT_TEST(test_SetShortInt_once(0xff, valDer, 2));
72+
73+
/* Input 2 bytes min */
74+
valDer[0] = 0x01;
75+
valDer[1] = 0x00;
76+
EXPECT_TEST(test_SetShortInt_once(0x0100, valDer, 2));
77+
78+
/* Input 2 bytes max */
79+
valDer[0] = 0x00;
80+
valDer[1] = 0xff;
81+
valDer[2] = 0xff;
82+
EXPECT_TEST(test_SetShortInt_once(0xffff, valDer, 3));
83+
84+
/* Input 3 bytes min */
85+
valDer[0] = 0x01;
86+
valDer[1] = 0x00;
87+
valDer[2] = 0x00;
88+
EXPECT_TEST(test_SetShortInt_once(0x010000, valDer, 3));
89+
90+
/* Input 3 bytes max */
91+
valDer[0] = 0x00;
92+
valDer[1] = 0xff;
93+
valDer[2] = 0xff;
94+
valDer[3] = 0xff;
95+
EXPECT_TEST(test_SetShortInt_once(0xffffff, valDer, 4));
96+
97+
/* Input 4 bytes min */
98+
valDer[0] = 0x01;
99+
valDer[1] = 0x00;
100+
valDer[2] = 0x00;
101+
valDer[3] = 0x00;
102+
EXPECT_TEST(test_SetShortInt_once(0x01000000, valDer, 4));
103+
104+
/* Input 4 bytes max */
105+
valDer[0] = 0x00;
106+
valDer[1] = 0xff;
107+
valDer[2] = 0xff;
108+
valDer[3] = 0xff;
109+
valDer[4] = 0xff;
110+
EXPECT_TEST(test_SetShortInt_once(0xffffffff, valDer, 5));
111+
}
112+
113+
/* Corner tests for output size */
114+
{
115+
/* Skip "Output 1 byte min" because of same as "Input 1 byte min" */
116+
117+
/* Output 1 byte max */
118+
valDer[0] = 0x7f;
119+
EXPECT_TEST(test_SetShortInt_once(0x7f, valDer, 1));
120+
121+
/* Output 2 bytes min */
122+
valDer[0] = 0x00;
123+
valDer[1] = 0x80;
124+
EXPECT_TEST(test_SetShortInt_once(0x80, valDer, 2));
125+
126+
/* Output 2 bytes max */
127+
valDer[0] = 0x7f;
128+
valDer[1] = 0xff;
129+
EXPECT_TEST(test_SetShortInt_once(0x7fff, valDer, 2));
130+
131+
/* Output 3 bytes min */
132+
valDer[0] = 0x00;
133+
valDer[1] = 0x80;
134+
valDer[2] = 0x00;
135+
EXPECT_TEST(test_SetShortInt_once(0x8000, valDer, 3));
136+
137+
/* Output 3 bytes max */
138+
valDer[0] = 0x7f;
139+
valDer[1] = 0xff;
140+
valDer[2] = 0xff;
141+
EXPECT_TEST(test_SetShortInt_once(0x7fffff, valDer, 3));
142+
143+
/* Output 4 bytes min */
144+
valDer[0] = 0x00;
145+
valDer[1] = 0x80;
146+
valDer[2] = 0x00;
147+
valDer[3] = 0x00;
148+
EXPECT_TEST(test_SetShortInt_once(0x800000, valDer, 4));
149+
150+
/* Output 4 bytes max */
151+
valDer[0] = 0x7f;
152+
valDer[1] = 0xff;
153+
valDer[2] = 0xff;
154+
valDer[3] = 0xff;
155+
EXPECT_TEST(test_SetShortInt_once(0x7fffffff, valDer, 4));
156+
157+
/* Output 5 bytes min */
158+
valDer[0] = 0x00;
159+
valDer[1] = 0x80;
160+
valDer[2] = 0x00;
161+
valDer[3] = 0x00;
162+
valDer[4] = 0x00;
163+
EXPECT_TEST(test_SetShortInt_once(0x80000000, valDer, 5));
164+
165+
/* Skip "Output 5 bytes max" because of same as "Input 4 bytes max" */
166+
}
167+
168+
/* Extra tests */
169+
{
170+
valDer[0] = 0x01;
171+
EXPECT_TEST(test_SetShortInt_once(0x01, valDer, 1));
172+
}
173+
174+
return EXPECT_RESULT();
175+
}

tests/api/test_asn.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* test_asn.h
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
#ifndef WOLFCRYPT_TEST_ASN_H
23+
#define WOLFCRYPT_TEST_ASN_H
24+
25+
#include <tests/api/api_decl.h>
26+
27+
int test_SetShortInt(void);
28+
29+
#define TEST_ASN_DECLS \
30+
TEST_DECL_GROUP("asn", test_SetShortInt) \
31+
32+
#endif /* WOLFCRYPT_TEST_ASN_H */

wolfcrypt/src/asn.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3252,22 +3252,31 @@ int SetShortInt(byte* output, word32* inOutIdx, word32 number, word32 maxIdx)
32523252
word32 idx = *inOutIdx;
32533253
word32 len;
32543254
int i;
3255+
word32 extraByte = 0;
32553256

32563257
if (number == 0)
32573258
len = 1;
32583259
else
32593260
len = BytePrecision(number);
32603261

3262+
if (number >> (WOLFSSL_BIT_SIZE * len - 1)) {
3263+
/* Need one byte of zero value not to be negative number */
3264+
extraByte = 1;
3265+
}
3266+
32613267
/* check for room for type and length bytes. */
3262-
if ((idx + 2 + len) > maxIdx)
3268+
if ((idx + 2 + extraByte + len) > maxIdx)
32633269
return BUFFER_E;
32643270

32653271
/* check that MAX_SHORT_SZ allows this size of ShortInt. */
3266-
if (2 + len > MAX_SHORT_SZ)
3272+
if (2 + extraByte + len > MAX_SHORT_SZ)
32673273
return ASN_PARSE_E;
32683274

32693275
output[idx++] = ASN_INTEGER;
3270-
output[idx++] = (byte)len;
3276+
output[idx++] = (byte)(len + extraByte);
3277+
if (extraByte) {
3278+
output[idx++] = 0x00;
3279+
}
32713280

32723281
for (i = (int)len - 1; i >= 0; --i)
32733282
output[idx++] = (byte)(number >> (i * WOLFSSL_BIT_SIZE));
@@ -9565,6 +9574,8 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
95659574
word32 encIdx = 0;
95669575
const byte* hmacOidBuf = NULL;
95679576
word32 hmacOidBufSz = 0;
9577+
byte tmpShort[MAX_SHORT_SZ];
9578+
word32 tmpIdx = 0;
95689579

95699580
(void)heap;
95709581

@@ -9587,9 +9598,14 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
95879598
if (ret == 0) {
95889599
padSz = (word32)((blockSz - ((int)keySz & (blockSz - 1))) &
95899600
(blockSz - 1));
9590-
/* inner = OCT salt INT itt */
9591-
innerLen = 2 + saltSz + 2 + ((itt < 256) ? 1 : ((itt < 65536) ? 2 : 3));
9592-
9601+
ret = SetShortInt(tmpShort, &tmpIdx, (word32)itt, MAX_SHORT_SZ);
9602+
if (ret > 0) {
9603+
/* inner = OCT salt INT itt */
9604+
innerLen = 2 + saltSz + (word32)ret;
9605+
ret = 0;
9606+
}
9607+
}
9608+
if (ret == 0) {
95939609
if (version != PKCS5v2) {
95949610
pbeOidBuf = OidFromId((word32)pbeId, oidPBEType, &pbeOidBufSz);
95959611
/* pbe = OBJ pbse1 SEQ [ inner ] */

wolfssl/wolfcrypt/asn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2202,7 +2202,7 @@ WOLFSSL_LOCAL byte GetCertNameId(int idx);
22022202
#endif
22032203
WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number,
22042204
word32 maxIdx);
2205-
WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number,
2205+
WOLFSSL_TEST_VIS int SetShortInt(byte* input, word32* inOutIdx, word32 number,
22062206
word32 maxIdx);
22072207

22082208
WOLFSSL_LOCAL const char* GetSigName(int oid);

wolfssl/wolfcrypt/types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2021,7 +2021,7 @@ enum Max_ASN {
20212021
MAX_SIG_SZ = 256,
20222022
MAX_ALGO_SZ = 20,
20232023
MAX_LENGTH_SZ = WOLFSSL_ASN_MAX_LENGTH_SZ, /* Max length size for DER encoding */
2024-
MAX_SHORT_SZ = (1 + MAX_LENGTH_SZ), /* asn int + byte len + 4 byte length */
2024+
MAX_SHORT_SZ = (1 + 1 + 5), /* asn int + byte len + 5 byte length */
20252025
MAX_SEQ_SZ = (1 + MAX_LENGTH_SZ), /* enum(seq | con) + length(5) */
20262026
MAX_SET_SZ = (1 + MAX_LENGTH_SZ), /* enum(set | con) + length(5) */
20272027
MAX_OCTET_STR_SZ = (1 + MAX_LENGTH_SZ), /* enum(set | con) + length(5) */

0 commit comments

Comments
 (0)