1 /* $OpenBSD: asn1evp.c,v 1.3 2018/11/08 21:37:21 jsing Exp $ */ 2 /* 3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <limits.h> 19 #include <stdio.h> 20 #include <string.h> 21 22 #include <openssl/asn1.h> 23 24 #define TEST_NUM 0x7fffffffL 25 26 unsigned char asn1_atios[] = { 27 0x30, 0x10, 0x02, 0x04, 0x7f, 0xff, 0xff, 0xff, 28 0x04, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 29 0x06, 0x07, 30 }; 31 32 unsigned char test_octetstring[] = { 33 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 34 }; 35 36 static void 37 hexdump(const unsigned char *buf, size_t len) 38 { 39 size_t i; 40 41 for (i = 1; i <= len; i++) 42 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); 43 44 fprintf(stderr, "\n"); 45 } 46 47 static int 48 compare_data(const char *label, const unsigned char *d1, size_t d1_len, 49 const unsigned char *d2, size_t d2_len) 50 { 51 if (d1_len != d2_len) { 52 fprintf(stderr, "FAIL: got %s with length %zu, want %zu\n", 53 label, d1_len, d2_len); 54 return -1; 55 } 56 if (memcmp(d1, d2, d1_len) != 0) { 57 fprintf(stderr, "FAIL: %s differs\n", label); 58 fprintf(stderr, "got:\n"); 59 hexdump(d1, d1_len); 60 fprintf(stderr, "want:\n"); 61 hexdump(d2, d2_len); 62 return -1; 63 } 64 return 0; 65 } 66 67 int 68 main(int argc, char **argv) 69 { 70 unsigned char data[16]; 71 long num = TEST_NUM; 72 ASN1_TYPE *at = NULL; 73 int failed = 1; 74 int len; 75 76 if ((at = ASN1_TYPE_new()) == NULL) { 77 fprintf(stderr, "FAIL: ASN1_TYPE_new returned NULL\n"); 78 goto done; 79 } 80 81 if (!ASN1_TYPE_set_int_octetstring(at, num, test_octetstring, 82 sizeof(test_octetstring))) { 83 fprintf(stderr, "FAIL: ASN1_TYPE_set_int_octetstring failed\n"); 84 goto done; 85 } 86 if (at->type != V_ASN1_SEQUENCE) { 87 fprintf(stderr, "FAIL: not a V_ASN1_SEQUENCE (%i != %i)\n", 88 at->type, V_ASN1_SEQUENCE); 89 goto done; 90 } 91 if (at->value.sequence->type != V_ASN1_OCTET_STRING) { 92 fprintf(stderr, "FAIL: not a V_ASN1_OCTET_STRING (%i != %i)\n", 93 at->type, V_ASN1_OCTET_STRING); 94 goto done; 95 } 96 if (compare_data("sequence", at->value.sequence->data, 97 at->value.sequence->length, asn1_atios, sizeof(asn1_atios)) == -1) 98 goto done; 99 100 memset(&data, 0, sizeof(data)); 101 num = 0; 102 103 if ((len = ASN1_TYPE_get_int_octetstring(at, &num, data, 104 sizeof(data))) < 0) { 105 fprintf(stderr, "FAIL: ASN1_TYPE_get_int_octetstring failed\n"); 106 goto done; 107 } 108 if (num != TEST_NUM) { 109 fprintf(stderr, "FAIL: got num %li, want %li\n", num, TEST_NUM); 110 goto done; 111 } 112 if (compare_data("octet string", data, len, 113 test_octetstring, sizeof(test_octetstring)) == -1) 114 goto done; 115 if (data[len] != 0) { 116 fprintf(stderr, "FAIL: octet string overflowed buffer\n"); 117 goto done; 118 } 119 120 memset(&data, 0, sizeof(data)); 121 num = 0; 122 123 /* With a limit buffer, the output should be truncated... */ 124 if ((len = ASN1_TYPE_get_int_octetstring(at, &num, data, 4)) < 0) { 125 fprintf(stderr, "FAIL: ASN1_TYPE_get_int_octetstring failed\n"); 126 goto done; 127 } 128 if (num != TEST_NUM) { 129 fprintf(stderr, "FAIL: got num %li, want %li\n", num, TEST_NUM); 130 goto done; 131 } 132 if (len != sizeof(test_octetstring)) { 133 fprintf(stderr, "FAIL: got length mismatch (%i != %zu)\n", 134 len, sizeof(test_octetstring)); 135 goto done; 136 } 137 if (compare_data("octet string", data, 4, test_octetstring, 4) == -1) 138 goto done; 139 if (data[4] != 0) { 140 fprintf(stderr, "FAIL: octet string overflowed buffer\n"); 141 goto done; 142 } 143 144 failed = 0; 145 146 done: 147 ASN1_TYPE_free(at); 148 149 return failed; 150 } 151