Skip to content

Commit 01ee1b3

Browse files
Parse DER-enconded length into a size_t instead of an int
This avoids a possibly implementation-defined signed (int) to unsigned (size_t) conversion portably.
1 parent 3cb057f commit 01ee1b3

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

src/ecdsa_impl.h

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,68 +46,73 @@ static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CON
4646
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
4747
);
4848

49-
static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) {
50-
int lenleft, b1;
51-
size_t ret = 0;
49+
static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const unsigned char *sigend) {
50+
size_t lenleft;
51+
unsigned char b1;
52+
VERIFY_CHECK(len != NULL);
53+
*len = 0;
5254
if (*sigp >= sigend) {
53-
return -1;
55+
return 0;
5456
}
5557
b1 = *((*sigp)++);
5658
if (b1 == 0xFF) {
5759
/* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */
58-
return -1;
60+
return 0;
5961
}
6062
if ((b1 & 0x80) == 0) {
6163
/* X.690-0207 8.1.3.4 short form length octets */
62-
return b1;
64+
*len = b1;
65+
return 1;
6366
}
6467
if (b1 == 0x80) {
6568
/* Indefinite length is not allowed in DER. */
66-
return -1;
69+
return 0;
6770
}
6871
/* X.690-207 8.1.3.5 long form length octets */
6972
lenleft = b1 & 0x7F; /* lenleft is at least 1 */
70-
if (lenleft > sigend - *sigp) {
71-
return -1;
73+
if (lenleft > (size_t)(sigend - *sigp)) {
74+
return 0;
7275
}
7376
if (**sigp == 0) {
7477
/* Not the shortest possible length encoding. */
75-
return -1;
78+
return 0;
7679
}
77-
if ((size_t)lenleft > sizeof(size_t)) {
80+
if (lenleft > sizeof(size_t)) {
7881
/* The resulting length would exceed the range of a size_t, so
7982
* certainly longer than the passed array size.
8083
*/
81-
return -1;
84+
return 0;
8285
}
8386
while (lenleft > 0) {
84-
ret = (ret << 8) | **sigp;
87+
*len = (*len << 8) | **sigp;
8588
(*sigp)++;
8689
lenleft--;
8790
}
88-
if (ret > (size_t)(sigend - *sigp)) {
91+
if (*len > (size_t)(sigend - *sigp)) {
8992
/* Result exceeds the length of the passed array. */
90-
return -1;
93+
return 0;
9194
}
92-
if (ret < 128) {
95+
if (*len < 128) {
9396
/* Not the shortest possible length encoding. */
94-
return -1;
97+
return 0;
9598
}
96-
return ret;
99+
return 1;
97100
}
98101

99102
static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) {
100103
int overflow = 0;
101104
unsigned char ra[32] = {0};
102-
int rlen;
105+
size_t rlen;
103106

104107
if (*sig == sigend || **sig != 0x02) {
105108
/* Not a primitive integer (X.690-0207 8.3.1). */
106109
return 0;
107110
}
108111
(*sig)++;
109-
rlen = secp256k1_der_read_len(sig, sigend);
110-
if (rlen <= 0 || (*sig) + rlen > sigend) {
112+
if (secp256k1_der_read_len(&rlen, sig, sigend) == 0) {
113+
return 0;
114+
}
115+
if (rlen == 0 || *sig + rlen > sigend) {
111116
/* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */
112117
return 0;
113118
}
@@ -144,13 +149,15 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char
144149

145150
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) {
146151
const unsigned char *sigend = sig + size;
147-
int rlen;
152+
size_t rlen;
148153
if (sig == sigend || *(sig++) != 0x30) {
149154
/* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */
150155
return 0;
151156
}
152-
rlen = secp256k1_der_read_len(&sig, sigend);
153-
if (rlen < 0 || sig + rlen > sigend) {
157+
if (secp256k1_der_read_len(&rlen, &sig, sigend) == 0) {
158+
return 0;
159+
}
160+
if (sig + rlen > sigend) {
154161
/* Tuple exceeds bounds */
155162
return 0;
156163
}

0 commit comments

Comments
 (0)