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