diff options
author | tb <> | 2023-12-25 22:02:59 +0000 |
---|---|---|
committer | tb <> | 2023-12-25 22:02:59 +0000 |
commit | 73b7427c3c99104d3110af3bddc5fa8049963cd7 (patch) | |
tree | 90d476cacff75c553be0c9a1bd40589eff75659d /src/lib | |
parent | 6fbc05f87ce487143e055a99f6450628fef7d792 (diff) | |
download | openbsd-73b7427c3c99104d3110af3bddc5fa8049963cd7.tar.gz openbsd-73b7427c3c99104d3110af3bddc5fa8049963cd7.tar.bz2 openbsd-73b7427c3c99104d3110af3bddc5fa8049963cd7.zip |
Avoid out-of-bounds accesses in ASN1_BIT_STRING_{get,set}()
If a negative n is passed, these functions would underrun the bitstring's
data array. So add checks for that and drop spades of unnecessary parens.
These functions are quite broken anyway. The setter attempts to zap the
unnecessary trailing zero octets, but fails to do so if the bit being
cleared isn't already set. Worse is the getter where you can't tell an
error (like attempting an out-of-bounds read) from the bit being unset.
ok joshua
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/asn1/a_bitstr.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c index 7ea3e12b91..851a3a3d51 100644 --- a/src/lib/libcrypto/asn1/a_bitstr.c +++ b/src/lib/libcrypto/asn1/a_bitstr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_bitstr.c,v 1.41 2023/07/28 10:33:13 tb Exp $ */ | 1 | /* $OpenBSD: a_bitstr.c,v 1.42 2023/12/25 22:02:59 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -120,20 +120,24 @@ ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) | |||
120 | int w, v, iv; | 120 | int w, v, iv; |
121 | unsigned char *c; | 121 | unsigned char *c; |
122 | 122 | ||
123 | w = n/8; | 123 | if (a == NULL) |
124 | return 0; | ||
125 | if (n < 0) | ||
126 | return 0; | ||
127 | |||
128 | w = n / 8; | ||
124 | v = 1 << (7 - (n & 0x07)); | 129 | v = 1 << (7 - (n & 0x07)); |
125 | iv = ~v; | 130 | iv = ~v; |
126 | if (!value) | ||
127 | v = 0; | ||
128 | 131 | ||
129 | if (a == NULL) | 132 | if (value == 0) |
130 | return 0; | 133 | v = 0; |
131 | 134 | ||
132 | asn1_abs_clear_unused_bits(a); | 135 | asn1_abs_clear_unused_bits(a); |
133 | 136 | ||
134 | if ((a->length < (w + 1)) || (a->data == NULL)) { | 137 | if (a->length < w + 1 || a->data == NULL) { |
135 | if (!value) | 138 | /* Don't expand if there's no bit to set. */ |
136 | return(1); /* Don't need to set */ | 139 | if (value == 0) |
140 | return 1; | ||
137 | if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) { | 141 | if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) { |
138 | ASN1error(ERR_R_MALLOC_FAILURE); | 142 | ASN1error(ERR_R_MALLOC_FAILURE); |
139 | return 0; | 143 | return 0; |
@@ -141,11 +145,12 @@ ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) | |||
141 | a->data = c; | 145 | a->data = c; |
142 | a->length = w + 1; | 146 | a->length = w + 1; |
143 | } | 147 | } |
148 | |||
144 | a->data[w] = ((a->data[w]) & iv) | v; | 149 | a->data[w] = ((a->data[w]) & iv) | v; |
145 | while ((a->length > 0) && (a->data[a->length - 1] == 0)) | 150 | while (a->length > 0 && a->data[a->length - 1] == 0) |
146 | a->length--; | 151 | a->length--; |
147 | 152 | ||
148 | return (1); | 153 | return 1; |
149 | } | 154 | } |
150 | LCRYPTO_ALIAS(ASN1_BIT_STRING_set_bit); | 155 | LCRYPTO_ALIAS(ASN1_BIT_STRING_set_bit); |
151 | 156 | ||
@@ -154,11 +159,18 @@ ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) | |||
154 | { | 159 | { |
155 | int w, v; | 160 | int w, v; |
156 | 161 | ||
162 | if (a == NULL) | ||
163 | return 0; | ||
164 | if (n < 0) | ||
165 | return 0; | ||
166 | |||
157 | w = n / 8; | 167 | w = n / 8; |
158 | v = 1 << (7 - (n & 0x07)); | 168 | v = 1 << (7 - (n & 0x07)); |
159 | if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) | 169 | |
160 | return (0); | 170 | if (a->length < w + 1 || a->data == NULL) |
161 | return ((a->data[w] & v) != 0); | 171 | return 0; |
172 | |||
173 | return (a->data[w] & v) != 0; | ||
162 | } | 174 | } |
163 | LCRYPTO_ALIAS(ASN1_BIT_STRING_get_bit); | 175 | LCRYPTO_ALIAS(ASN1_BIT_STRING_get_bit); |
164 | 176 | ||