1b528cefcSMark Murray /* 2b528cefcSMark Murray * Copyright (c) 1999 Kungliga Tekniska H�gskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #ifdef HAVE_CONFIG_H 35b528cefcSMark Murray #include <config.h> 36b528cefcSMark Murray #endif 37b528cefcSMark Murray #include <stdio.h> 38b528cefcSMark Murray #include <string.h> 39b528cefcSMark Murray #include <err.h> 40b528cefcSMark Murray #include <roken.h> 41b528cefcSMark Murray 42b528cefcSMark Murray #include <libasn1.h> 43b528cefcSMark Murray 44b528cefcSMark Murray RCSID("$Id: check-der.c,v 1.7 1999/12/02 17:05:01 joda Exp $"); 45b528cefcSMark Murray 46b528cefcSMark Murray static void 47b528cefcSMark Murray print_bytes (unsigned const char *buf, size_t len) 48b528cefcSMark Murray { 49b528cefcSMark Murray int i; 50b528cefcSMark Murray 51b528cefcSMark Murray for (i = 0; i < len; ++i) 52b528cefcSMark Murray printf ("%02x ", buf[i]); 53b528cefcSMark Murray } 54b528cefcSMark Murray 55b528cefcSMark Murray struct test_case { 56b528cefcSMark Murray void *val; 57b528cefcSMark Murray int byte_len; 58b528cefcSMark Murray const unsigned char *bytes; 59b528cefcSMark Murray char *name; 60b528cefcSMark Murray }; 61b528cefcSMark Murray 62b528cefcSMark Murray static int 63b528cefcSMark Murray generic_test (const struct test_case *tests, 64b528cefcSMark Murray unsigned ntests, 65b528cefcSMark Murray size_t data_size, 66b528cefcSMark Murray int (*encode)(unsigned char *, size_t, void *, size_t *), 67b528cefcSMark Murray int (*length)(void *), 68b528cefcSMark Murray int (*decode)(unsigned char *, size_t, void *, size_t *), 69b528cefcSMark Murray int (*cmp)(void *a, void *b)) 70b528cefcSMark Murray { 71b528cefcSMark Murray unsigned char buf[4711]; 72b528cefcSMark Murray int i; 73b528cefcSMark Murray int failures = 0; 74b528cefcSMark Murray void *val = malloc (data_size); 75b528cefcSMark Murray 76b528cefcSMark Murray if (data_size != 0 && val == NULL) 77b528cefcSMark Murray err (1, "malloc"); 78b528cefcSMark Murray 79b528cefcSMark Murray for (i = 0; i < ntests; ++i) { 80b528cefcSMark Murray int ret; 81b528cefcSMark Murray size_t sz, consumed_sz, length_sz; 82b528cefcSMark Murray unsigned char *beg; 83b528cefcSMark Murray 84b528cefcSMark Murray ret = (*encode) (buf + sizeof(buf) - 1, sizeof(buf), 85b528cefcSMark Murray tests[i].val, &sz); 86b528cefcSMark Murray beg = buf + sizeof(buf) - sz; 87b528cefcSMark Murray if (ret != 0) { 88b528cefcSMark Murray printf ("encoding of %s failed\n", tests[i].name); 89b528cefcSMark Murray ++failures; 90b528cefcSMark Murray } 91b528cefcSMark Murray if (sz != tests[i].byte_len) { 92b528cefcSMark Murray printf ("encoding of %s has wrong len (%lu != %lu)\n", 93b528cefcSMark Murray tests[i].name, 94b528cefcSMark Murray (unsigned long)sz, (unsigned long)tests[i].byte_len); 95b528cefcSMark Murray ++failures; 96b528cefcSMark Murray } 97b528cefcSMark Murray 98b528cefcSMark Murray length_sz = (*length) (tests[i].val); 99b528cefcSMark Murray if (sz != length_sz) { 100b528cefcSMark Murray printf ("length for %s is bad (%lu != %lu)\n", 101b528cefcSMark Murray tests[i].name, (unsigned long)length_sz, (unsigned long)sz); 102b528cefcSMark Murray ++failures; 103b528cefcSMark Murray } 104b528cefcSMark Murray 105b528cefcSMark Murray if (memcmp (beg, tests[i].bytes, tests[i].byte_len) != 0) { 106b528cefcSMark Murray printf ("encoding of %s has bad bytes:\n" 107b528cefcSMark Murray "correct: ", tests[i].name); 108b528cefcSMark Murray print_bytes (tests[i].bytes, tests[i].byte_len); 109b528cefcSMark Murray printf ("\nactual: "); 110b528cefcSMark Murray print_bytes (beg, sz); 111b528cefcSMark Murray printf ("\n"); 112b528cefcSMark Murray ++failures; 113b528cefcSMark Murray } 114b528cefcSMark Murray ret = (*decode) (beg, sz, val, &consumed_sz); 115b528cefcSMark Murray if (ret != 0) { 116b528cefcSMark Murray printf ("decoding of %s failed\n", tests[i].name); 117b528cefcSMark Murray ++failures; 118b528cefcSMark Murray } 119b528cefcSMark Murray if (sz != consumed_sz) { 120b528cefcSMark Murray printf ("different length decoding %s (%ld != %ld)\n", 121b528cefcSMark Murray tests[i].name, 122b528cefcSMark Murray (unsigned long)sz, (unsigned long)consumed_sz); 123b528cefcSMark Murray ++failures; 124b528cefcSMark Murray } 125b528cefcSMark Murray if ((*cmp)(val, tests[i].val) != 0) { 126b528cefcSMark Murray printf ("%s: comparison failed\n", tests[i].name); 127b528cefcSMark Murray ++failures; 128b528cefcSMark Murray } 129b528cefcSMark Murray } 130b528cefcSMark Murray free (val); 131b528cefcSMark Murray return failures; 132b528cefcSMark Murray } 133b528cefcSMark Murray 134b528cefcSMark Murray static int 135b528cefcSMark Murray cmp_integer (void *a, void *b) 136b528cefcSMark Murray { 137b528cefcSMark Murray int *ia = (int *)a; 138b528cefcSMark Murray int *ib = (int *)b; 139b528cefcSMark Murray 140b528cefcSMark Murray return *ib - *ia; 141b528cefcSMark Murray } 142b528cefcSMark Murray 143b528cefcSMark Murray static int 144b528cefcSMark Murray test_integer (void) 145b528cefcSMark Murray { 146b528cefcSMark Murray struct test_case tests[] = { 147b528cefcSMark Murray {NULL, 3, "\x02\x01\x00"}, 148b528cefcSMark Murray {NULL, 3, "\x02\x01\x7f"}, 149b528cefcSMark Murray {NULL, 4, "\x02\x02\x00\x80"}, 150b528cefcSMark Murray {NULL, 4, "\x02\x02\x01\x00"}, 151b528cefcSMark Murray {NULL, 3, "\x02\x01\x80"}, 152b528cefcSMark Murray {NULL, 4, "\x02\x02\xff\x7f"}, 153b528cefcSMark Murray {NULL, 3, "\x02\x01\xff"}, 154b528cefcSMark Murray {NULL, 4, "\x02\x02\xff\x01"}, 155b528cefcSMark Murray {NULL, 4, "\x02\x02\x00\xff"}, 156b528cefcSMark Murray {NULL, 6, "\x02\x04\x80\x00\x00\x00"}, 157b528cefcSMark Murray {NULL, 6, "\x02\x04\x7f\xff\xff\xff"} 158b528cefcSMark Murray }; 159b528cefcSMark Murray 160b528cefcSMark Murray int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255, 161b528cefcSMark Murray 0x80000000, 0x7fffffff}; 162b528cefcSMark Murray int i; 163b528cefcSMark Murray int ntests = sizeof(tests) / sizeof(*tests); 164b528cefcSMark Murray 165b528cefcSMark Murray for (i = 0; i < ntests; ++i) { 166b528cefcSMark Murray tests[i].val = &values[i]; 167b528cefcSMark Murray asprintf (&tests[i].name, "integer %d", values[i]); 168b528cefcSMark Murray } 169b528cefcSMark Murray 170b528cefcSMark Murray return generic_test (tests, ntests, sizeof(int), 171b528cefcSMark Murray (int (*)(unsigned char *, size_t, 172b528cefcSMark Murray void *, size_t *))encode_integer, 173b528cefcSMark Murray (int (*)(void *))length_integer, 174b528cefcSMark Murray (int (*)(unsigned char *, size_t, 175b528cefcSMark Murray void *, size_t *))decode_integer, 176b528cefcSMark Murray cmp_integer); 177b528cefcSMark Murray } 178b528cefcSMark Murray 179b528cefcSMark Murray static int 180b528cefcSMark Murray cmp_octet_string (void *a, void *b) 181b528cefcSMark Murray { 182b528cefcSMark Murray octet_string *oa = (octet_string *)a; 183b528cefcSMark Murray octet_string *ob = (octet_string *)b; 184b528cefcSMark Murray 185b528cefcSMark Murray if (oa->length != ob->length) 186b528cefcSMark Murray return ob->length - oa->length; 187b528cefcSMark Murray 188b528cefcSMark Murray return (memcmp (oa->data, ob->data, oa->length)); 189b528cefcSMark Murray } 190b528cefcSMark Murray 191b528cefcSMark Murray static int 192b528cefcSMark Murray test_octet_string (void) 193b528cefcSMark Murray { 194b528cefcSMark Murray octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"}; 195b528cefcSMark Murray 196b528cefcSMark Murray struct test_case tests[] = { 197b528cefcSMark Murray {NULL, 10, "\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef"} 198b528cefcSMark Murray }; 199b528cefcSMark Murray int ntests = sizeof(tests) / sizeof(*tests); 200b528cefcSMark Murray 201b528cefcSMark Murray tests[0].val = &s1; 202b528cefcSMark Murray asprintf (&tests[0].name, "a octet string"); 203b528cefcSMark Murray 204b528cefcSMark Murray return generic_test (tests, ntests, sizeof(octet_string), 205b528cefcSMark Murray (int (*)(unsigned char *, size_t, 206b528cefcSMark Murray void *, size_t *))encode_octet_string, 207b528cefcSMark Murray (int (*)(void *))length_octet_string, 208b528cefcSMark Murray (int (*)(unsigned char *, size_t, 209b528cefcSMark Murray void *, size_t *))decode_octet_string, 210b528cefcSMark Murray cmp_octet_string); 211b528cefcSMark Murray } 212b528cefcSMark Murray 213b528cefcSMark Murray static int 214b528cefcSMark Murray cmp_general_string (void *a, void *b) 215b528cefcSMark Murray { 216b528cefcSMark Murray unsigned char **sa = (unsigned char **)a; 217b528cefcSMark Murray unsigned char **sb = (unsigned char **)b; 218b528cefcSMark Murray 219b528cefcSMark Murray return strcmp (*sa, *sb); 220b528cefcSMark Murray } 221b528cefcSMark Murray 222b528cefcSMark Murray static int 223b528cefcSMark Murray test_general_string (void) 224b528cefcSMark Murray { 225b528cefcSMark Murray unsigned char *s1 = "Test User 1"; 226b528cefcSMark Murray 227b528cefcSMark Murray struct test_case tests[] = { 228b528cefcSMark Murray {NULL, 13, "\x1b\x0b\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"} 229b528cefcSMark Murray }; 230b528cefcSMark Murray int ntests = sizeof(tests) / sizeof(*tests); 231b528cefcSMark Murray 232b528cefcSMark Murray tests[0].val = &s1; 233b528cefcSMark Murray asprintf (&tests[0].name, "the string \"%s\"", s1); 234b528cefcSMark Murray 235b528cefcSMark Murray return generic_test (tests, ntests, sizeof(unsigned char *), 236b528cefcSMark Murray (int (*)(unsigned char *, size_t, 237b528cefcSMark Murray void *, size_t *))encode_general_string, 238b528cefcSMark Murray (int (*)(void *))length_general_string, 239b528cefcSMark Murray (int (*)(unsigned char *, size_t, 240b528cefcSMark Murray void *, size_t *))decode_general_string, 241b528cefcSMark Murray cmp_general_string); 242b528cefcSMark Murray } 243b528cefcSMark Murray 244b528cefcSMark Murray static int 245b528cefcSMark Murray cmp_generalized_time (void *a, void *b) 246b528cefcSMark Murray { 247b528cefcSMark Murray time_t *ta = (time_t *)a; 248b528cefcSMark Murray time_t *tb = (time_t *)b; 249b528cefcSMark Murray 250b528cefcSMark Murray return *tb - *ta; 251b528cefcSMark Murray } 252b528cefcSMark Murray 253b528cefcSMark Murray static int 254b528cefcSMark Murray test_generalized_time (void) 255b528cefcSMark Murray { 256b528cefcSMark Murray struct test_case tests[] = { 257b528cefcSMark Murray {NULL, 17, "\x18\x0f""19700101000000Z"}, 258b528cefcSMark Murray {NULL, 17, "\x18\x0f""19851106210627Z"} 259b528cefcSMark Murray }; 260b528cefcSMark Murray time_t values[] = {0, 500159187}; 261b528cefcSMark Murray int i; 262b528cefcSMark Murray int ntests = sizeof(tests) / sizeof(*tests); 263b528cefcSMark Murray 264b528cefcSMark Murray for (i = 0; i < ntests; ++i) { 265b528cefcSMark Murray tests[i].val = &values[i]; 266b528cefcSMark Murray asprintf (&tests[i].name, "time %d", (int)values[i]); 267b528cefcSMark Murray } 268b528cefcSMark Murray 269b528cefcSMark Murray return generic_test (tests, ntests, sizeof(time_t), 270b528cefcSMark Murray (int (*)(unsigned char *, size_t, 271b528cefcSMark Murray void *, size_t *))encode_generalized_time, 272b528cefcSMark Murray (int (*)(void *))length_generalized_time, 273b528cefcSMark Murray (int (*)(unsigned char *, size_t, 274b528cefcSMark Murray void *, size_t *))decode_generalized_time, 275b528cefcSMark Murray cmp_generalized_time); 276b528cefcSMark Murray } 277b528cefcSMark Murray 278b528cefcSMark Murray int 279b528cefcSMark Murray main(int argc, char **argv) 280b528cefcSMark Murray { 281b528cefcSMark Murray int ret = 0; 282b528cefcSMark Murray 283b528cefcSMark Murray ret += test_integer (); 284b528cefcSMark Murray ret += test_octet_string (); 285b528cefcSMark Murray ret += test_general_string (); 286b528cefcSMark Murray ret += test_generalized_time (); 287b528cefcSMark Murray 288b528cefcSMark Murray return ret; 289b528cefcSMark Murray } 290