diff options
author | jsing <> | 2022-03-02 11:28:00 +0000 |
---|---|---|
committer | jsing <> | 2022-03-02 11:28:00 +0000 |
commit | 3c3fcd217ad6d444723416dd9eca5e1dc42f4bed (patch) | |
tree | ef22bb60da9100fb77f57965fd90ea63a5b3733b /src/lib/libcrypto/asn1/a_object.c | |
parent | 4d809bb98b2046d02a7447203478b3d9d0846702 (diff) | |
download | openbsd-3c3fcd217ad6d444723416dd9eca5e1dc42f4bed.tar.gz openbsd-3c3fcd217ad6d444723416dd9eca5e1dc42f4bed.tar.bz2 openbsd-3c3fcd217ad6d444723416dd9eca5e1dc42f4bed.zip |
Rewrite ASN1_OBJECT content to ascii/text conversion.
Rewrite the ASN1_OBJECT content to ascii/text conversion code using CBB and
CBS. Currently there is a strange split with i2t_ASN1_OBJECT() calling
OBJ_obj2txt() which implements the conversion, while OBJ_txt2obj() calls
back into the misnamed a2d_ASN1_OBJECT() function. Move the conversion
code into asn1/a_object.c and have OBJ_txt2obj() call that instead.
ok inoguchi@ tb@
Diffstat (limited to 'src/lib/libcrypto/asn1/a_object.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_object.c | 201 |
1 files changed, 177 insertions, 24 deletions
diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c index 1407f7df1c..f26026e6aa 100644 --- a/src/lib/libcrypto/asn1/a_object.c +++ b/src/lib/libcrypto/asn1/a_object.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_object.c,v 1.37 2022/01/07 11:13:54 tb Exp $ */ | 1 | /* $OpenBSD: a_object.c,v 1.38 2022/03/02 11:28:00 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 | * |
@@ -270,37 +270,190 @@ a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) | |||
270 | return (0); | 270 | return (0); |
271 | } | 271 | } |
272 | 272 | ||
273 | static int | ||
274 | oid_parse_arc(CBS *cbs, uint64_t *out_arc) | ||
275 | { | ||
276 | uint64_t arc = 0; | ||
277 | uint8_t val; | ||
278 | |||
279 | do { | ||
280 | if (!CBS_get_u8(cbs, &val)) | ||
281 | return 0; | ||
282 | if (arc == 0 && val == 0x80) | ||
283 | return 0; | ||
284 | if (arc > (UINT64_MAX >> 7)) | ||
285 | return 0; | ||
286 | arc = (arc << 7) | (val & 0x7f); | ||
287 | } while (val & 0x80); | ||
288 | |||
289 | *out_arc = arc; | ||
290 | |||
291 | return 1; | ||
292 | } | ||
293 | |||
294 | static int | ||
295 | oid_add_arc_txt(CBB *cbb, uint64_t arc, int first) | ||
296 | { | ||
297 | const char *fmt = ".%llu"; | ||
298 | char s[22]; /* Digits in decimal representation of 2^64-1, plus '.' and NUL. */ | ||
299 | int n; | ||
300 | |||
301 | if (first) | ||
302 | fmt = "%llu"; | ||
303 | n = snprintf(s, sizeof(s), fmt, (unsigned long long)arc); | ||
304 | if (n < 0 || (size_t)n >= sizeof(s)) | ||
305 | return 0; | ||
306 | if (!CBB_add_bytes(cbb, s, n)) | ||
307 | return 0; | ||
308 | |||
309 | return 1; | ||
310 | } | ||
311 | |||
312 | static int | ||
313 | c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb) | ||
314 | { | ||
315 | uint64_t arc, si1, si2; | ||
316 | |||
317 | /* | ||
318 | * X.690 section 8.19 - the first two subidentifiers are encoded as | ||
319 | * (x * 40) + y, with x being limited to [0,1,2]. | ||
320 | */ | ||
321 | if (!oid_parse_arc(cbs, &arc)) | ||
322 | return 0; | ||
323 | if ((si1 = arc / 40) > 2) | ||
324 | si1 = 2; | ||
325 | si2 = arc - si1 * 40; | ||
326 | |||
327 | if (!oid_add_arc_txt(cbb, si1, 1)) | ||
328 | return 0; | ||
329 | if (!oid_add_arc_txt(cbb, si2, 0)) | ||
330 | return 0; | ||
331 | |||
332 | while (CBS_len(cbs) > 0) { | ||
333 | if (!oid_parse_arc(cbs, &arc)) | ||
334 | return 0; | ||
335 | if (!oid_add_arc_txt(cbb, arc, 0)) | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | /* NUL terminate. */ | ||
340 | if (!CBB_add_u8(cbb, 0)) | ||
341 | return 0; | ||
342 | |||
343 | return 1; | ||
344 | } | ||
345 | |||
346 | static int | ||
347 | i2t_ASN1_OBJECT_oid(const ASN1_OBJECT *aobj, CBB *cbb) | ||
348 | { | ||
349 | CBS cbs; | ||
350 | |||
351 | CBS_init(&cbs, aobj->data, aobj->length); | ||
352 | |||
353 | return c2a_ASN1_OBJECT(&cbs, cbb); | ||
354 | } | ||
355 | |||
356 | static int | ||
357 | i2t_ASN1_OBJECT_name(const ASN1_OBJECT *aobj, CBB *cbb, const char **out_name) | ||
358 | { | ||
359 | const char *name; | ||
360 | int nid; | ||
361 | |||
362 | if ((nid = OBJ_obj2nid(aobj)) == NID_undef) | ||
363 | return 0; | ||
364 | |||
365 | if ((name = OBJ_nid2ln(nid)) == NULL) | ||
366 | name = OBJ_nid2sn(nid); | ||
367 | if (name == NULL) | ||
368 | return 0; | ||
369 | |||
370 | *out_name = name; | ||
371 | |||
372 | if (!CBB_add_bytes(cbb, name, strlen(name))) | ||
373 | return 0; | ||
374 | |||
375 | /* NUL terminate. */ | ||
376 | if (!CBB_add_u8(cbb, 0)) | ||
377 | return 0; | ||
378 | |||
379 | return 1; | ||
380 | } | ||
381 | |||
382 | static int | ||
383 | i2t_ASN1_OBJECT_cbb(const ASN1_OBJECT *aobj, CBB *cbb, int no_name) | ||
384 | { | ||
385 | const char *name; | ||
386 | |||
387 | if (!no_name) { | ||
388 | if (i2t_ASN1_OBJECT_name(aobj, cbb, &name)) | ||
389 | return 1; | ||
390 | if (name != NULL) | ||
391 | return 0; | ||
392 | } | ||
393 | return i2t_ASN1_OBJECT_oid(aobj, cbb); | ||
394 | } | ||
395 | |||
396 | int | ||
397 | i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len, int no_name) | ||
398 | { | ||
399 | uint8_t *data = NULL; | ||
400 | size_t data_len; | ||
401 | CBB cbb; | ||
402 | int ret = 0; | ||
403 | |||
404 | if (buf_len < 0) | ||
405 | return 0; | ||
406 | if (buf_len > 0) | ||
407 | buf[0] = '\0'; | ||
408 | |||
409 | if (!CBB_init(&cbb, 0)) | ||
410 | goto err; | ||
411 | if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, no_name)) | ||
412 | goto err; | ||
413 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
414 | goto err; | ||
415 | |||
416 | ret = strlcpy(buf, data, buf_len); | ||
417 | err: | ||
418 | CBB_cleanup(&cbb); | ||
419 | free(data); | ||
420 | |||
421 | return ret; | ||
422 | } | ||
423 | |||
273 | int | 424 | int |
274 | i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) | 425 | i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *aobj) |
275 | { | 426 | { |
276 | return OBJ_obj2txt(buf, buf_len, a, 0); | 427 | return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, 0); |
277 | } | 428 | } |
278 | 429 | ||
279 | int | 430 | int |
280 | i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) | 431 | i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *aobj) |
281 | { | 432 | { |
282 | char *tmp = NULL; | 433 | uint8_t *data = NULL; |
283 | size_t tlen = 256; | 434 | size_t data_len; |
284 | int i = -1; | 435 | CBB cbb; |
436 | int ret = -1; | ||
285 | 437 | ||
286 | if ((a == NULL) || (a->data == NULL)) | 438 | if (aobj == NULL || aobj->data == NULL) |
287 | return(BIO_write(bp, "NULL", 4)); | 439 | return BIO_write(bp, "NULL", 4); |
288 | if ((tmp = malloc(tlen)) == NULL) | 440 | |
289 | return -1; | 441 | if (!CBB_init(&cbb, 0)) |
290 | i = i2t_ASN1_OBJECT(tmp, tlen, a); | 442 | goto err; |
291 | if (i > (int)(tlen - 1)) { | 443 | if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, 0)) { |
292 | freezero(tmp, tlen); | 444 | ret = BIO_write(bp, "<INVALID>", 9); |
293 | if ((tmp = malloc(i + 1)) == NULL) | 445 | goto err; |
294 | return -1; | ||
295 | tlen = i + 1; | ||
296 | i = i2t_ASN1_OBJECT(tmp, tlen, a); | ||
297 | } | 446 | } |
298 | if (i <= 0) | 447 | if (!CBB_finish(&cbb, &data, &data_len)) |
299 | i = BIO_write(bp, "<INVALID>", 9); | 448 | goto err; |
300 | else | 449 | |
301 | i = BIO_write(bp, tmp, i); | 450 | ret = BIO_write(bp, data, data_len); |
302 | freezero(tmp, tlen); | 451 | |
303 | return (i); | 452 | err: |
453 | CBB_cleanup(&cbb); | ||
454 | free(data); | ||
455 | |||
456 | return ret; | ||
304 | } | 457 | } |
305 | 458 | ||
306 | ASN1_OBJECT * | 459 | ASN1_OBJECT * |