1 /*- 2 * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #include <sys/stat.h> 8 9 #include <assert.h> 10 #include <fcntl.h> 11 #include <inttypes.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <unistd.h> 16 17 #include <libder.h> 18 19 #include "test_common.h" 20 21 /* 22 * Note that the choice of secp112r1 is completely arbitrary. I was mainly 23 * shooting for something pretty weak to avoid people trying to "catch me" 24 * checking in private key material, even though it's very incredibly clearly 25 * just for a test case. 26 */ 27 static const uint8_t oid_secp112r1[] = 28 { 0x2b, 0x81, 0x04, 0x00, 0x06 }; 29 30 static const uint8_t privdata[] = { 0xa5, 0xf5, 0x2a, 0x56, 0x61, 0xe3, 0x58, 31 0x76, 0x5c, 0x4f, 0xd6, 0x8d, 0x60, 0x54 }; 32 33 static const uint8_t pubdata[] = { 0x00, 0x04, 0xae, 0x69, 0x41, 0x0d, 0x9c, 34 0x9b, 0xf2, 0x34, 0xf6, 0x2d, 0x7c, 0x91, 0xe1, 0xc7, 0x7f, 0x23, 0xa0, 35 0x84, 0x34, 0x5c, 0x38, 0x26, 0xd8, 0xcf, 0xbe, 0xf7, 0xdc, 0x8a }; 36 37 static void 38 test_interface(struct libder_object *root) 39 { 40 const uint8_t *data; 41 size_t datasz; 42 struct libder_object *keystring, *oid; 43 44 /* Grab the oid first. */ 45 oid = libder_obj_child(root, 2); 46 assert(oid != NULL); /* Actually just the container... */ 47 assert(libder_obj_type_simple(oid) == 0xa0); 48 49 oid = libder_obj_child(oid, 0); 50 assert(oid != NULL); /* Now *that*'s an OID. */ 51 assert(libder_obj_type_simple(oid) == BT_OID); 52 data = libder_obj_data(oid, &datasz); 53 assert(datasz == sizeof(oid_secp112r1)); 54 assert(memcmp(oid_secp112r1, data, datasz) == 0); 55 56 keystring = libder_obj_child(root, 1); 57 assert(keystring != NULL); 58 assert(libder_obj_type_simple(keystring) == BT_OCTETSTRING); 59 60 data = libder_obj_data(keystring, &datasz); 61 assert(datasz == sizeof(privdata)); 62 assert(memcmp(privdata, data, datasz) == 0); 63 } 64 65 /* buf and bufszs are just our reference */ 66 static void 67 test_construction(struct libder_ctx *ctx, const uint8_t *buf, size_t bufsz) 68 { 69 uint8_t *out; 70 struct libder_object *obj, *oidp, *pubp, *root; 71 struct libder_object *keystring; 72 size_t outsz; 73 uint8_t data; 74 75 root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0); 76 assert(root != NULL); 77 78 data = 1; 79 obj = libder_obj_alloc_simple(ctx, BT_INTEGER, &data, 1); 80 assert(obj != NULL); 81 assert(libder_obj_append(root, obj)); 82 83 /* Private key material */ 84 obj = libder_obj_alloc_simple(ctx, BT_OCTETSTRING, privdata, sizeof(privdata)); 85 assert(obj != NULL); 86 assert(libder_obj_append(root, obj)); 87 88 /* Now throw in the OID and pubkey containers */ 89 oidp = libder_obj_alloc_simple(ctx, 90 (BC_CONTEXT << 6) | BER_TYPE_CONSTRUCTED_MASK | 0, NULL, 0); 91 assert(oidp != NULL); 92 assert(libder_obj_append(root, oidp)); 93 94 pubp = libder_obj_alloc_simple(ctx, 95 (BC_CONTEXT << 6) | BER_TYPE_CONSTRUCTED_MASK | 1, NULL, 0); 96 assert(pubp != NULL); 97 assert(libder_obj_append(root, pubp)); 98 99 /* Actually add the OID */ 100 obj = libder_obj_alloc_simple(ctx, BT_OID, oid_secp112r1, sizeof(oid_secp112r1)); 101 assert(obj != NULL); 102 assert(libder_obj_append(oidp, obj)); 103 104 /* Finally, add the pubkey */ 105 obj = libder_obj_alloc_simple(ctx, BT_BITSTRING, pubdata, sizeof(pubdata)); 106 assert(obj != NULL); 107 assert(libder_obj_append(pubp, obj)); 108 109 out = NULL; 110 outsz = 0; 111 out = libder_write(ctx, root, out, &outsz); 112 assert(out != NULL); 113 assert(outsz == bufsz); 114 115 assert(memcmp(out, buf, bufsz) == 0); 116 117 libder_obj_free(root); 118 free(out); 119 } 120 121 int 122 main(int argc, char *argv[]) 123 { 124 struct stat sb; 125 struct libder_ctx *ctx; 126 struct libder_object *root; 127 uint8_t *buf, *out; 128 size_t bufsz, outsz, rootsz; 129 ssize_t readsz; 130 int dfd, error, fd; 131 132 dfd = open_progdir(argv[0]); 133 134 fd = openat(dfd, "repo.priv", O_RDONLY); 135 assert(fd >= 0); 136 137 close(dfd); 138 dfd = -1; 139 140 error = fstat(fd, &sb); 141 assert(error == 0); 142 143 bufsz = sb.st_size; 144 buf = malloc(bufsz); 145 assert(buf != NULL); 146 147 readsz = read(fd, buf, bufsz); 148 close(fd); 149 150 assert(readsz == bufsz); 151 152 ctx = libder_open(); 153 rootsz = bufsz; 154 libder_set_verbose(ctx, 2); 155 root = libder_read(ctx, buf, &rootsz); 156 157 assert(root != NULL); 158 assert(rootsz == bufsz); 159 160 test_interface(root); 161 test_construction(ctx, buf, bufsz); 162 163 outsz = 0; 164 out = NULL; 165 out = libder_write(ctx, root, out, &outsz); 166 assert(out != NULL); 167 assert(outsz == bufsz); 168 169 assert(memcmp(buf, out, outsz) == 0); 170 171 free(out); 172 free(buf); 173 libder_obj_free(root); 174 libder_close(ctx); 175 } 176