diff options
| author | jsing <> | 2022-03-02 11:28:00 +0000 |
|---|---|---|
| committer | jsing <> | 2022-03-02 11:28:00 +0000 |
| commit | 82fb0381802967c4e0623e7f4bde8e684c08dbc6 (patch) | |
| tree | ef22bb60da9100fb77f57965fd90ea63a5b3733b /src/lib/libcrypto/asn1 | |
| parent | 3afe4b6f29d7548f490e80402e8bf0ef7229dac1 (diff) | |
| download | openbsd-82fb0381802967c4e0623e7f4bde8e684c08dbc6.tar.gz openbsd-82fb0381802967c4e0623e7f4bde8e684c08dbc6.tar.bz2 openbsd-82fb0381802967c4e0623e7f4bde8e684c08dbc6.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')
| -rw-r--r-- | src/lib/libcrypto/asn1/a_object.c | 201 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/asn1_locl.h | 5 |
2 files changed, 181 insertions, 25 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 * |
diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h index 7d34d7c17a..bb6a9fc91a 100644 --- a/src/lib/libcrypto/asn1/asn1_locl.h +++ b/src/lib/libcrypto/asn1/asn1_locl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: asn1_locl.h,v 1.20 2022/01/14 08:53:53 tb Exp $ */ | 1 | /* $OpenBSD: asn1_locl.h,v 1.21 2022/03/02 11:28:00 jsing Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -201,4 +201,7 @@ int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class, | |||
| 201 | 201 | ||
| 202 | int asn1_tag2charwidth(int tag); | 202 | int asn1_tag2charwidth(int tag); |
| 203 | 203 | ||
| 204 | int i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len, | ||
| 205 | int no_name); | ||
| 206 | |||
| 204 | __END_HIDDEN_DECLS | 207 | __END_HIDDEN_DECLS |
