1*9badb9adSjsing /* $OpenBSD: asn1basic.c,v 1.7 2022/06/25 13:57:17 jsing Exp $ */ 2725e2e31Sjsing /* 3725e2e31Sjsing * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org> 4725e2e31Sjsing * 5725e2e31Sjsing * Permission to use, copy, modify, and distribute this software for any 6725e2e31Sjsing * purpose with or without fee is hereby granted, provided that the above 7725e2e31Sjsing * copyright notice and this permission notice appear in all copies. 8725e2e31Sjsing * 9725e2e31Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10725e2e31Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11725e2e31Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12725e2e31Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13725e2e31Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14725e2e31Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15725e2e31Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16725e2e31Sjsing */ 17725e2e31Sjsing 18725e2e31Sjsing #include <openssl/asn1.h> 19725e2e31Sjsing 20725e2e31Sjsing #include <err.h> 21725e2e31Sjsing #include <stdio.h> 22725e2e31Sjsing #include <string.h> 23725e2e31Sjsing 249773c5c8Stb #include "asn1_locl.h" 259773c5c8Stb 26725e2e31Sjsing static void 27725e2e31Sjsing hexdump(const unsigned char *buf, size_t len) 28725e2e31Sjsing { 29725e2e31Sjsing size_t i; 30725e2e31Sjsing 31725e2e31Sjsing for (i = 1; i <= len; i++) 32725e2e31Sjsing fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); 33725e2e31Sjsing 34725e2e31Sjsing fprintf(stderr, "\n"); 35725e2e31Sjsing } 36725e2e31Sjsing 37725e2e31Sjsing static int 38725e2e31Sjsing asn1_compare_bytes(const char *label, const unsigned char *d1, int len1, 39725e2e31Sjsing const unsigned char *d2, int len2) 40725e2e31Sjsing { 41725e2e31Sjsing if (len1 != len2) { 42725e2e31Sjsing fprintf(stderr, "FAIL: %s - byte lengths differ " 43725e2e31Sjsing "(%i != %i)\n", label, len1, len2); 4430fc8fe5Sjsing fprintf(stderr, "Got:\n"); 4530fc8fe5Sjsing hexdump(d1, len1); 4630fc8fe5Sjsing fprintf(stderr, "Want:\n"); 4730fc8fe5Sjsing hexdump(d2, len2); 48725e2e31Sjsing return 0; 49725e2e31Sjsing } 50725e2e31Sjsing if (memcmp(d1, d2, len1) != 0) { 51725e2e31Sjsing fprintf(stderr, "FAIL: %s - bytes differ\n", label); 52725e2e31Sjsing fprintf(stderr, "Got:\n"); 53725e2e31Sjsing hexdump(d1, len1); 54725e2e31Sjsing fprintf(stderr, "Want:\n"); 55725e2e31Sjsing hexdump(d2, len2); 56725e2e31Sjsing return 0; 57725e2e31Sjsing } 58725e2e31Sjsing return 1; 59725e2e31Sjsing } 60725e2e31Sjsing 6130fc8fe5Sjsing const uint8_t asn1_bit_string_primitive[] = { 6230fc8fe5Sjsing 0x03, 0x07, 6330fc8fe5Sjsing 0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0, 6430fc8fe5Sjsing }; 6530fc8fe5Sjsing 6630fc8fe5Sjsing static int 6730fc8fe5Sjsing asn1_bit_string_test(void) 6830fc8fe5Sjsing { 6930fc8fe5Sjsing uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0}; 7030fc8fe5Sjsing ASN1_BIT_STRING *abs; 7130fc8fe5Sjsing uint8_t *p = NULL, *pp; 7230fc8fe5Sjsing const uint8_t *q; 7330fc8fe5Sjsing int bit, i, len; 7430fc8fe5Sjsing int failed = 1; 7530fc8fe5Sjsing 7630fc8fe5Sjsing if ((abs = ASN1_BIT_STRING_new()) == NULL) { 7730fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n"); 7830fc8fe5Sjsing goto failed; 7930fc8fe5Sjsing } 8030fc8fe5Sjsing if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) { 8130fc8fe5Sjsing fprintf(stderr, "FAIL: failed to set bit string\n"); 8230fc8fe5Sjsing goto failed; 8330fc8fe5Sjsing } 8430fc8fe5Sjsing 8530fc8fe5Sjsing if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) { 8630fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n"); 8730fc8fe5Sjsing goto failed; 8830fc8fe5Sjsing } 8930fc8fe5Sjsing if ((p = malloc(len)) == NULL) 9030fc8fe5Sjsing errx(1, "malloc"); 9130fc8fe5Sjsing memset(p, 0xbd, len); 9230fc8fe5Sjsing pp = p; 9330fc8fe5Sjsing if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) { 9430fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); 9530fc8fe5Sjsing goto failed; 9630fc8fe5Sjsing } 9730fc8fe5Sjsing 9830fc8fe5Sjsing if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive, 9930fc8fe5Sjsing sizeof(asn1_bit_string_primitive))) 10030fc8fe5Sjsing goto failed; 10130fc8fe5Sjsing 10230fc8fe5Sjsing /* Test primitive decoding. */ 10330fc8fe5Sjsing q = p; 10430fc8fe5Sjsing if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) { 10530fc8fe5Sjsing fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n"); 10630fc8fe5Sjsing goto failed; 10730fc8fe5Sjsing } 10830fc8fe5Sjsing if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length, 10930fc8fe5Sjsing bs, sizeof(bs))) 11030fc8fe5Sjsing goto failed; 11130fc8fe5Sjsing 11230fc8fe5Sjsing /* Test ASN1_BIT_STRING_get_bit(). */ 11330fc8fe5Sjsing for (i = 0; i < ((int)sizeof(bs) * 8); i++) { 11430fc8fe5Sjsing bit = (bs[i / 8] >> (7 - i % 8)) & 1; 11530fc8fe5Sjsing 11630fc8fe5Sjsing if (ASN1_BIT_STRING_get_bit(abs, i) != bit) { 11730fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) " 11830fc8fe5Sjsing "= %d, want %d\n", i, 11930fc8fe5Sjsing ASN1_BIT_STRING_get_bit(abs, i), bit); 12030fc8fe5Sjsing goto failed; 12130fc8fe5Sjsing } 12230fc8fe5Sjsing } 12330fc8fe5Sjsing 12430fc8fe5Sjsing /* Test ASN1_BIT_STRING_set_bit(). */ 12530fc8fe5Sjsing for (i = 0; i < ((int)sizeof(bs) * 8); i++) { 12630fc8fe5Sjsing if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) { 12730fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n"); 12830fc8fe5Sjsing goto failed; 12930fc8fe5Sjsing } 13030fc8fe5Sjsing } 13130fc8fe5Sjsing for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) { 13230fc8fe5Sjsing bit = (bs[i / 8] >> (7 - i % 8)) & 1; 13330fc8fe5Sjsing if (bit == 1) 13430fc8fe5Sjsing continue; 13530fc8fe5Sjsing if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) { 13630fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n"); 13730fc8fe5Sjsing goto failed; 13830fc8fe5Sjsing } 13930fc8fe5Sjsing } 14030fc8fe5Sjsing 14130fc8fe5Sjsing if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) { 14230fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); 14330fc8fe5Sjsing goto failed; 14430fc8fe5Sjsing } 14530fc8fe5Sjsing 14630fc8fe5Sjsing memset(p, 0xbd, len); 14730fc8fe5Sjsing pp = p; 14830fc8fe5Sjsing if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) { 14930fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); 15030fc8fe5Sjsing goto failed; 15130fc8fe5Sjsing } 15230fc8fe5Sjsing 15330fc8fe5Sjsing if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive, 15430fc8fe5Sjsing sizeof(asn1_bit_string_primitive))) 15530fc8fe5Sjsing goto failed; 15630fc8fe5Sjsing 15730fc8fe5Sjsing failed = 0; 15830fc8fe5Sjsing 15930fc8fe5Sjsing failed: 16030fc8fe5Sjsing ASN1_BIT_STRING_free(abs); 16130fc8fe5Sjsing free(p); 16230fc8fe5Sjsing 16330fc8fe5Sjsing return failed; 16430fc8fe5Sjsing } 16530fc8fe5Sjsing 166725e2e31Sjsing const uint8_t asn1_boolean_false[] = { 167725e2e31Sjsing 0x01, 0x01, 0x00, 168725e2e31Sjsing }; 169725e2e31Sjsing const uint8_t asn1_boolean_true[] = { 170725e2e31Sjsing 0x01, 0x01, 0x01, 171725e2e31Sjsing }; 172725e2e31Sjsing 173725e2e31Sjsing static int 174725e2e31Sjsing asn1_boolean_test(void) 175725e2e31Sjsing { 176725e2e31Sjsing uint8_t *p = NULL, *pp; 177725e2e31Sjsing const uint8_t *q; 178725e2e31Sjsing int len; 179725e2e31Sjsing int failed = 1; 180725e2e31Sjsing 181725e2e31Sjsing if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) { 182725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n"); 183725e2e31Sjsing goto failed; 184725e2e31Sjsing } 18530fc8fe5Sjsing if ((p = malloc(len)) == NULL) 186725e2e31Sjsing errx(1, "calloc"); 18730fc8fe5Sjsing memset(p, 0xbd, len); 188725e2e31Sjsing pp = p; 189725e2e31Sjsing if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) { 190725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n"); 191725e2e31Sjsing goto failed; 192725e2e31Sjsing } 193725e2e31Sjsing 194725e2e31Sjsing if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false, 195725e2e31Sjsing sizeof(asn1_boolean_false))) 196725e2e31Sjsing goto failed; 197725e2e31Sjsing 198725e2e31Sjsing q = p; 199725e2e31Sjsing if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) { 200725e2e31Sjsing fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n"); 201725e2e31Sjsing goto failed; 202725e2e31Sjsing } 203725e2e31Sjsing 204725e2e31Sjsing free(p); 205725e2e31Sjsing p = NULL; 206725e2e31Sjsing 207725e2e31Sjsing if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) { 208725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n"); 209725e2e31Sjsing goto failed; 210725e2e31Sjsing } 211725e2e31Sjsing if ((p = calloc(1, len)) == NULL) 212725e2e31Sjsing errx(1, "calloc"); 213725e2e31Sjsing pp = p; 214725e2e31Sjsing if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) { 215725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n"); 216725e2e31Sjsing goto failed; 217725e2e31Sjsing } 218725e2e31Sjsing 219725e2e31Sjsing if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true, 220725e2e31Sjsing sizeof(asn1_boolean_true))) 221725e2e31Sjsing goto failed; 222725e2e31Sjsing 223725e2e31Sjsing q = p; 224725e2e31Sjsing if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) { 22572ad5686Stb fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n"); 226725e2e31Sjsing goto failed; 227725e2e31Sjsing } 228725e2e31Sjsing 229725e2e31Sjsing failed = 0; 230725e2e31Sjsing 231725e2e31Sjsing failed: 232725e2e31Sjsing free(p); 233725e2e31Sjsing 234725e2e31Sjsing return failed; 235725e2e31Sjsing } 236725e2e31Sjsing 23751b91989Sjsing struct asn1_integer_test { 23851b91989Sjsing long value; 23951b91989Sjsing uint8_t content[64]; 24051b91989Sjsing size_t content_len; 24151b91989Sjsing int content_neg; 24251b91989Sjsing uint8_t der[64]; 24351b91989Sjsing size_t der_len; 24451b91989Sjsing int want_error; 24551b91989Sjsing }; 24651b91989Sjsing 24751b91989Sjsing struct asn1_integer_test asn1_integer_tests[] = { 24851b91989Sjsing { 24951b91989Sjsing .value = 0, 25051b91989Sjsing .content = {0x00}, 25151b91989Sjsing .content_len = 1, 25251b91989Sjsing .der = {0x02, 0x01, 0x00}, 25351b91989Sjsing .der_len = 3, 25451b91989Sjsing }, 25551b91989Sjsing { 25651b91989Sjsing .value = 1, 25751b91989Sjsing .content = {0x01}, 25851b91989Sjsing .content_len = 1, 25951b91989Sjsing .der = {0x02, 0x01, 0x01}, 26051b91989Sjsing .der_len = 3, 26151b91989Sjsing }, 26251b91989Sjsing { 26351b91989Sjsing .value = -1, 26451b91989Sjsing .content = {0x01}, 26551b91989Sjsing .content_len = 1, 26651b91989Sjsing .content_neg = 1, 26751b91989Sjsing .der = {0x02, 0x01, 0xff}, 26851b91989Sjsing .der_len = 3, 26951b91989Sjsing }, 27051b91989Sjsing { 27151b91989Sjsing .value = 127, 27251b91989Sjsing .content = {0x7f}, 27351b91989Sjsing .content_len = 1, 27451b91989Sjsing .der = {0x02, 0x01, 0x7f}, 27551b91989Sjsing .der_len = 3, 27651b91989Sjsing }, 27751b91989Sjsing { 27851b91989Sjsing .value = -127, 27951b91989Sjsing .content = {0x7f}, 28051b91989Sjsing .content_len = 1, 28151b91989Sjsing .content_neg = 1, 28251b91989Sjsing .der = {0x02, 0x01, 0x81}, 28351b91989Sjsing .der_len = 3, 28451b91989Sjsing }, 28551b91989Sjsing { 28651b91989Sjsing .value = 128, 28751b91989Sjsing .content = {0x80}, 28851b91989Sjsing .content_len = 1, 28951b91989Sjsing .der = {0x02, 0x02, 0x00, 0x80}, 29051b91989Sjsing .der_len = 4, 29151b91989Sjsing }, 29251b91989Sjsing { 29351b91989Sjsing .value = -128, 29451b91989Sjsing .content = {0x80}, 29551b91989Sjsing .content_len = 1, 29651b91989Sjsing .content_neg = 1, 29751b91989Sjsing .der = {0x02, 0x01, 0x80}, 29851b91989Sjsing .der_len = 3, 29951b91989Sjsing }, 30051b91989Sjsing { 30151b91989Sjsing /* 2^64 */ 30251b91989Sjsing .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 30351b91989Sjsing .content_len = 9, 30451b91989Sjsing .der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 30551b91989Sjsing .der_len = 11, 30651b91989Sjsing }, 30751b91989Sjsing { 30851b91989Sjsing /* -2^64 */ 30951b91989Sjsing .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 31051b91989Sjsing .content_len = 9, 31151b91989Sjsing .content_neg = 1, 31251b91989Sjsing .der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 31351b91989Sjsing .der_len = 11, 31451b91989Sjsing }, 31551b91989Sjsing { 31651b91989Sjsing /* Invalid length. */ 31751b91989Sjsing .der = {0x02, 0x00}, 31851b91989Sjsing .der_len = 2, 31951b91989Sjsing .want_error = 1, 32051b91989Sjsing }, 32151b91989Sjsing { 32251b91989Sjsing /* Invalid padding. */ 32351b91989Sjsing .der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 32451b91989Sjsing .der_len = 11, 32551b91989Sjsing .want_error = 1, 32651b91989Sjsing }, 32751b91989Sjsing { 32851b91989Sjsing /* Invalid padding. */ 32951b91989Sjsing .der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 33051b91989Sjsing .der_len = 11, 33151b91989Sjsing .want_error = 1, 33251b91989Sjsing }, 33351b91989Sjsing }; 33451b91989Sjsing 33551b91989Sjsing #define N_ASN1_INTEGER_TESTS \ 33651b91989Sjsing (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests)) 33751b91989Sjsing 33851b91989Sjsing static int 33951b91989Sjsing asn1_integer_set_test(struct asn1_integer_test *ait) 34051b91989Sjsing { 34151b91989Sjsing ASN1_INTEGER *aint = NULL; 34251b91989Sjsing uint8_t *p = NULL, *pp; 34351b91989Sjsing int len; 34451b91989Sjsing int failed = 1; 34551b91989Sjsing 34651b91989Sjsing if ((aint = ASN1_INTEGER_new()) == NULL) { 34751b91989Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); 34851b91989Sjsing goto failed; 34951b91989Sjsing } 35051b91989Sjsing if (!ASN1_INTEGER_set(aint, ait->value)) { 35151b91989Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n", 35251b91989Sjsing ait->value); 35351b91989Sjsing goto failed; 35451b91989Sjsing } 35551b91989Sjsing if (ait->value != 0 && 35651b91989Sjsing !asn1_compare_bytes("INTEGER set", aint->data, aint->length, 35751b91989Sjsing ait->content, ait->content_len)) 35851b91989Sjsing goto failed; 35951b91989Sjsing if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) { 36051b91989Sjsing fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n"); 36151b91989Sjsing goto failed; 36251b91989Sjsing } 36351b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { 36451b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 36551b91989Sjsing goto failed; 36651b91989Sjsing } 36751b91989Sjsing if ((p = malloc(len)) == NULL) 36851b91989Sjsing errx(1, "malloc"); 36951b91989Sjsing memset(p, 0xbd, len); 37051b91989Sjsing pp = p; 37151b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { 37251b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 37351b91989Sjsing goto failed; 37451b91989Sjsing } 37551b91989Sjsing if (!asn1_compare_bytes("INTEGER set", p, len, ait->der, 37651b91989Sjsing ait->der_len)) 37751b91989Sjsing goto failed; 37851b91989Sjsing 37951b91989Sjsing failed = 0; 38051b91989Sjsing 38151b91989Sjsing failed: 38251b91989Sjsing ASN1_INTEGER_free(aint); 38351b91989Sjsing free(p); 38451b91989Sjsing 38551b91989Sjsing return failed; 38651b91989Sjsing } 38751b91989Sjsing 38851b91989Sjsing static int 38951b91989Sjsing asn1_integer_content_test(struct asn1_integer_test *ait) 39051b91989Sjsing { 39151b91989Sjsing ASN1_INTEGER *aint = NULL; 39251b91989Sjsing uint8_t *p = NULL, *pp; 39351b91989Sjsing int len; 39451b91989Sjsing int failed = 1; 39551b91989Sjsing 39651b91989Sjsing if ((aint = ASN1_INTEGER_new()) == NULL) { 39751b91989Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); 39851b91989Sjsing goto failed; 39951b91989Sjsing } 40051b91989Sjsing if ((aint->data = malloc(ait->content_len)) == NULL) 40151b91989Sjsing errx(1, "malloc"); 40251b91989Sjsing memcpy(aint->data, ait->content, ait->content_len); 40351b91989Sjsing aint->length = ait->content_len; 40451b91989Sjsing if (ait->content_neg) 40551b91989Sjsing aint->type = V_ASN1_NEG_INTEGER; 40651b91989Sjsing 40751b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { 40851b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 40951b91989Sjsing goto failed; 41051b91989Sjsing } 41151b91989Sjsing if ((p = malloc(len)) == NULL) 41251b91989Sjsing errx(1, "malloc"); 41351b91989Sjsing memset(p, 0xbd, len); 41451b91989Sjsing pp = p; 41551b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { 41651b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 41751b91989Sjsing goto failed; 41851b91989Sjsing } 41951b91989Sjsing if (!asn1_compare_bytes("INTEGER content", p, len, ait->der, 42051b91989Sjsing ait->der_len)) 42151b91989Sjsing goto failed; 42251b91989Sjsing 42351b91989Sjsing failed = 0; 42451b91989Sjsing 42551b91989Sjsing failed: 42651b91989Sjsing ASN1_INTEGER_free(aint); 42751b91989Sjsing free(p); 42851b91989Sjsing 42951b91989Sjsing return failed; 43051b91989Sjsing } 43151b91989Sjsing 43251b91989Sjsing static int 43351b91989Sjsing asn1_integer_decode_test(struct asn1_integer_test *ait) 43451b91989Sjsing { 43551b91989Sjsing ASN1_INTEGER *aint = NULL; 43651b91989Sjsing const uint8_t *q; 43751b91989Sjsing int failed = 1; 43851b91989Sjsing 43951b91989Sjsing q = ait->der; 44051b91989Sjsing if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) { 44151b91989Sjsing if (ait->want_error != 0) { 44251b91989Sjsing fprintf(stderr, "FAIL: INTEGER decoded when it should " 44351b91989Sjsing "have failed\n"); 44451b91989Sjsing goto failed; 44551b91989Sjsing } 44651b91989Sjsing if (!asn1_compare_bytes("INTEGER content", aint->data, 44751b91989Sjsing aint->length, ait->content, ait->content_len)) 44851b91989Sjsing goto failed; 44951b91989Sjsing } else if (ait->want_error == 0) { 45051b91989Sjsing fprintf(stderr, "FAIL: INTEGER failed to decode\n"); 45151b91989Sjsing goto failed; 45251b91989Sjsing } 45351b91989Sjsing 45451b91989Sjsing failed = 0; 45551b91989Sjsing 45651b91989Sjsing failed: 45751b91989Sjsing ASN1_INTEGER_free(aint); 45851b91989Sjsing 45951b91989Sjsing return failed; 46051b91989Sjsing } 46151b91989Sjsing 46251b91989Sjsing static int 463*9badb9adSjsing asn1_integer_cmp_test(void) 464*9badb9adSjsing { 465*9badb9adSjsing ASN1_INTEGER *a = NULL, *b = NULL; 466*9badb9adSjsing int failed = 1; 467*9badb9adSjsing 468*9badb9adSjsing if ((a = ASN1_INTEGER_new()) == NULL) 469*9badb9adSjsing goto failed; 470*9badb9adSjsing if ((b = ASN1_INTEGER_new()) == NULL) 471*9badb9adSjsing goto failed; 472*9badb9adSjsing 473*9badb9adSjsing if (ASN1_INTEGER_cmp(a, b) != 0) { 474*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER 0 == 0"); 475*9badb9adSjsing goto failed; 476*9badb9adSjsing } 477*9badb9adSjsing 478*9badb9adSjsing if (!ASN1_INTEGER_set(b, 1)) { 479*9badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER"); 480*9badb9adSjsing goto failed; 481*9badb9adSjsing } 482*9badb9adSjsing if (ASN1_INTEGER_cmp(a, b) >= 0) { 483*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER 0 < 1"); 484*9badb9adSjsing goto failed; 485*9badb9adSjsing } 486*9badb9adSjsing if (ASN1_INTEGER_cmp(b, a) <= 0) { 487*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER 1 > 0"); 488*9badb9adSjsing goto failed; 489*9badb9adSjsing } 490*9badb9adSjsing 491*9badb9adSjsing if (!ASN1_INTEGER_set(b, -1)) { 492*9badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER"); 493*9badb9adSjsing goto failed; 494*9badb9adSjsing } 495*9badb9adSjsing if (ASN1_INTEGER_cmp(a, b) <= 0) { 496*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER 0 > -1"); 497*9badb9adSjsing goto failed; 498*9badb9adSjsing } 499*9badb9adSjsing if (ASN1_INTEGER_cmp(b, a) >= 0) { 500*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER -1 < 0"); 501*9badb9adSjsing goto failed; 502*9badb9adSjsing } 503*9badb9adSjsing 504*9badb9adSjsing if (!ASN1_INTEGER_set(a, 1)) { 505*9badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER"); 506*9badb9adSjsing goto failed; 507*9badb9adSjsing } 508*9badb9adSjsing if (ASN1_INTEGER_cmp(a, b) <= 0) { 509*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER 1 > -1"); 510*9badb9adSjsing goto failed; 511*9badb9adSjsing } 512*9badb9adSjsing if (ASN1_INTEGER_cmp(b, a) >= 0) { 513*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER -1 < 1"); 514*9badb9adSjsing goto failed; 515*9badb9adSjsing } 516*9badb9adSjsing 517*9badb9adSjsing if (!ASN1_INTEGER_set(b, 1)) { 518*9badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER"); 519*9badb9adSjsing goto failed; 520*9badb9adSjsing } 521*9badb9adSjsing if (ASN1_INTEGER_cmp(a, b) != 0) { 522*9badb9adSjsing fprintf(stderr, "FAIL: INTEGER 1 == 1"); 523*9badb9adSjsing goto failed; 524*9badb9adSjsing } 525*9badb9adSjsing 526*9badb9adSjsing failed = 0; 527*9badb9adSjsing 528*9badb9adSjsing failed: 529*9badb9adSjsing ASN1_INTEGER_free(a); 530*9badb9adSjsing ASN1_INTEGER_free(b); 531*9badb9adSjsing 532*9badb9adSjsing return failed; 533*9badb9adSjsing } 534*9badb9adSjsing 535*9badb9adSjsing static int 53651b91989Sjsing asn1_integer_test(void) 53751b91989Sjsing { 53851b91989Sjsing struct asn1_integer_test *ait; 53951b91989Sjsing int failed = 0; 54051b91989Sjsing size_t i; 54151b91989Sjsing 54251b91989Sjsing for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) { 54351b91989Sjsing ait = &asn1_integer_tests[i]; 54451b91989Sjsing if (ait->content_len > 0 && ait->content_len <= 4) 54551b91989Sjsing failed |= asn1_integer_set_test(ait); 54651b91989Sjsing if (ait->content_len > 0) 54751b91989Sjsing failed |= asn1_integer_content_test(ait); 54851b91989Sjsing failed |= asn1_integer_decode_test(ait); 54951b91989Sjsing } 55051b91989Sjsing 551*9badb9adSjsing failed |= asn1_integer_cmp_test(); 552*9badb9adSjsing 55351b91989Sjsing return failed; 55451b91989Sjsing } 55551b91989Sjsing 556725e2e31Sjsing int 557725e2e31Sjsing main(int argc, char **argv) 558725e2e31Sjsing { 559725e2e31Sjsing int failed = 0; 560725e2e31Sjsing 56130fc8fe5Sjsing failed |= asn1_bit_string_test(); 562725e2e31Sjsing failed |= asn1_boolean_test(); 56351b91989Sjsing failed |= asn1_integer_test(); 564725e2e31Sjsing 565725e2e31Sjsing return (failed); 566725e2e31Sjsing } 567