summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2022-04-23 18:56:54 +0000
committerjsing <>2022-04-23 18:56:54 +0000
commita21700d1cbc0c5673e9dc658afc73350b8dd01ff (patch)
tree0274146de25f5693d5647860a3ade9219fc383f2 /src
parent0b0c2376e6bf555ee5f42a4c10baae3c4758fedf (diff)
downloadopenbsd-a21700d1cbc0c5673e9dc658afc73350b8dd01ff.tar.gz
openbsd-a21700d1cbc0c5673e9dc658afc73350b8dd01ff.tar.bz2
openbsd-a21700d1cbc0c5673e9dc658afc73350b8dd01ff.zip
Rewrite c2i_ASN1_BIT_STRING() using CBS.
Also switch to freeing and allocating, rather than attempting to recycle. While here, factor out the flags ASN1_STRING_FLAG_BITS_LEFT bit bashing and use the name "unused bits" rather than "bits left", to be more inline with X.690 wording. ok inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/a_bitstr.c127
1 files changed, 83 insertions, 44 deletions
diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c
index 4ffafd5f86..52fe0eb9cd 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.33 2021/12/25 08:52:44 jsing Exp $ */ 1/* $OpenBSD: a_bitstr.c,v 1.34 2022/04/23 18:56:54 jsing 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 *
@@ -56,6 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59#include <limits.h>
59#include <stdio.h> 60#include <stdio.h>
60#include <string.h> 61#include <string.h>
61 62
@@ -65,6 +66,8 @@
65#include <openssl/err.h> 66#include <openssl/err.h>
66#include <openssl/x509v3.h> 67#include <openssl/x509v3.h>
67 68
69#include "bytestring.h"
70
68const ASN1_ITEM ASN1_BIT_STRING_it = { 71const ASN1_ITEM ASN1_BIT_STRING_it = {
69 .itype = ASN1_ITYPE_PRIMITIVE, 72 .itype = ASN1_ITYPE_PRIMITIVE,
70 .utype = V_ASN1_BIT_STRING, 73 .utype = V_ASN1_BIT_STRING,
@@ -83,6 +86,25 @@ ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
83 ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it); 86 ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
84} 87}
85 88
89static void
90asn1_abs_clear_unused_bits(ASN1_BIT_STRING *abs)
91{
92 abs->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
93}
94
95static int
96asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits)
97{
98 if (unused_bits > 7)
99 return 0;
100
101 asn1_abs_clear_unused_bits(abs);
102
103 abs->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
104
105 return 1;
106}
107
86int 108int
87ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) 109ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
88{ 110{
@@ -104,7 +126,7 @@ ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
104 if (a == NULL) 126 if (a == NULL)
105 return 0; 127 return 0;
106 128
107 a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ 129 asn1_abs_clear_unused_bits(a);
108 130
109 if ((a->length < (w + 1)) || (a->data == NULL)) { 131 if ((a->length < (w + 1)) || (a->data == NULL)) {
110 if (!value) 132 if (!value)
@@ -269,68 +291,85 @@ i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
269 return (ret); 291 return (ret);
270} 292}
271 293
272ASN1_BIT_STRING * 294static int
273c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len) 295c2i_ASN1_BIT_STRING_cbs(ASN1_BIT_STRING **out_abs, CBS *cbs)
274{ 296{
275 ASN1_BIT_STRING *ret = NULL; 297 ASN1_BIT_STRING *abs = NULL;
276 const unsigned char *p; 298 uint8_t *data = NULL;
277 unsigned char *s; 299 size_t data_len = 0;
278 int i; 300 uint8_t unused_bits;
301 int ret = 0;
279 302
280 if (len < 1) { 303 if (out_abs == NULL || *out_abs != NULL)
304 goto err;
305
306 if (!CBS_get_u8(cbs, &unused_bits)) {
281 ASN1error(ASN1_R_STRING_TOO_SHORT); 307 ASN1error(ASN1_R_STRING_TOO_SHORT);
282 goto err; 308 goto err;
283 } 309 }
284 310
285 if (a == NULL || *a == NULL) { 311 if (!CBS_stow(cbs, &data, &data_len))
286 if ((ret = ASN1_BIT_STRING_new()) == NULL) 312 goto err;
287 return (NULL); 313 if (data_len > INT_MAX)
288 } else 314 goto err;
289 ret = *a;
290 315
291 p = *pp; 316 if ((abs = ASN1_BIT_STRING_new()) == NULL)
292 i = *(p++);
293 if (i > 7) {
294 ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
295 goto err; 317 goto err;
296 } 318
319 abs->data = data;
320 abs->length = (int)data_len;
321 data = NULL;
297 322
298 /* 323 /*
299 * We do this to preserve the settings. If we modify the settings, 324 * We do this to preserve the settings. If we modify the settings,
300 * via the _set_bit function, we will recalculate on output. 325 * via the _set_bit function, we will recalculate on output.
301 */ 326 */
302 ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ 327 if (!asn1_abs_set_unused_bits(abs, unused_bits)) {
303 ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ 328 ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
329 goto err;
330 }
331 if (abs->length > 0)
332 abs->data[abs->length - 1] &= 0xff << unused_bits;
304 333
305 /* using one because of the bits left byte */ 334 *out_abs = abs;
306 if (len-- > 1) { 335 abs = NULL;
307 if ((s = malloc(len)) == NULL) {
308 ASN1error(ERR_R_MALLOC_FAILURE);
309 goto err;
310 }
311 memcpy(s, p, len);
312 s[len - 1] &= (0xff << i);
313 p += len;
314 } else
315 s = NULL;
316 336
317 free(ret->data); 337 ret = 1;
318 ret->data = s;
319 ret->length = (int)len;
320 ret->type = V_ASN1_BIT_STRING;
321 338
322 if (a != NULL) 339 err:
323 *a = ret; 340 ASN1_BIT_STRING_free(abs);
341 freezero(data, data_len);
324 342
325 *pp = p; 343 return ret;
344}
326 345
327 return (ret); 346ASN1_BIT_STRING *
347c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out_abs, const unsigned char **pp, long len)
348{
349 ASN1_BIT_STRING *abs = NULL;
350 CBS content;
328 351
329 err: 352 if (out_abs != NULL) {
330 if (a == NULL || *a != ret) 353 ASN1_BIT_STRING_free(*out_abs);
331 ASN1_BIT_STRING_free(ret); 354 *out_abs = NULL;
355 }
356
357 if (len < 0) {
358 ASN1error(ASN1_R_LENGTH_ERROR);
359 return NULL;
360 }
361
362 CBS_init(&content, *pp, len);
363
364 if (!c2i_ASN1_BIT_STRING_cbs(&abs, &content))
365 return NULL;
366
367 *pp = CBS_data(&content);
368
369 if (out_abs != NULL)
370 *out_abs = abs;
332 371
333 return (NULL); 372 return abs;
334} 373}
335 374
336int 375int