xref: /freebsd/contrib/libder/tests/test_privkey.c (revision 35c0a8c449fd2b7f75029ebed5e10852240f0865)
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
test_interface(struct libder_object * root)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
test_construction(struct libder_ctx * ctx,const uint8_t * buf,size_t bufsz)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
main(int argc,char * argv[])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