1/*
2 * Copyright (c) 2022 Yubico AB. All rights reserved.
3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file.
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#undef NDEBUG
9
10#include <assert.h>
11#include <string.h>
12
13#include <openssl/sha.h>
14
15#define _FIDO_INTERNAL
16
17#include <fido.h>
18
19/*
20 * zlib compressed data (RFC1950); see https://www.ietf.org/rfc/rfc6713.txt
21 */
22static /* const */ unsigned char rfc1950_blob[694] = {
23	0x78, 0x9c, 0xb5, 0x52, 0x3b, 0x6f, 0xdb, 0x30,
24	0x10, 0xde, 0xf5, 0x2b, 0x0e, 0x99, 0x12, 0x40,
25	0x75, 0x13, 0x4f, 0x45, 0x3b, 0xd1, 0x12, 0x6d,
26	0x1d, 0x20, 0x8b, 0x2a, 0x49, 0xd9, 0xf5, 0x28,
27	0x4b, 0x4c, 0x42, 0xc0, 0x12, 0x03, 0x3d, 0x12,
28	0xe4, 0xdf, 0xf7, 0xc8, 0x3a, 0x88, 0xd3, 0x0c,
29	0x9d, 0xea, 0xc1, 0x3e, 0xf3, 0x8e, 0xdf, 0xeb,
30	0x98, 0xb8, 0xa7, 0xd7, 0xc1, 0x3e, 0x3c, 0x4e,
31	0x70, 0xdd, 0xdc, 0xc0, 0xf2, 0xf6, 0xee, 0xdb,
32	0x97, 0xe5, 0xed, 0x72, 0x09, 0x87, 0xf9, 0x68,
33	0x1b, 0x07, 0x6c, 0xb5, 0x00, 0x76, 0x3a, 0x41,
34	0x18, 0x19, 0x61, 0x30, 0xa3, 0x19, 0x9e, 0x4d,
35	0xbb, 0x88, 0x22, 0x69, 0x5a, 0x3b, 0x4e, 0x83,
36	0x3d, 0xce, 0x93, 0x75, 0x3d, 0xd4, 0x7d, 0x0b,
37	0xf3, 0x68, 0xc0, 0xf6, 0x30, 0xba, 0x79, 0x68,
38	0x4c, 0x38, 0x39, 0xda, 0xbe, 0x1e, 0x5e, 0xe1,
39	0xde, 0x0d, 0xdd, 0x18, 0xc3, 0x8b, 0x9d, 0x1e,
40	0xc1, 0x0d, 0xe1, 0xd7, 0xcd, 0x53, 0xd4, 0xb9,
41	0xd6, 0xde, 0xdb, 0xa6, 0xf6, 0x00, 0x31, 0xd4,
42	0x83, 0x81, 0x27, 0x33, 0x74, 0x76, 0x9a, 0x4c,
43	0x0b, 0x4f, 0x83, 0x7b, 0xb6, 0x2d, 0x15, 0xd3,
44	0x63, 0x3d, 0xd1, 0x97, 0x21, 0x90, 0xd3, 0xc9,
45	0xbd, 0xd8, 0xfe, 0x01, 0x1a, 0xd7, 0xb7, 0xd6,
46	0x5f, 0x1a, 0xfd, 0xa5, 0xa8, 0x33, 0xd3, 0xf7,
47	0x28, 0x02, 0x80, 0xbb, 0x05, 0x7c, 0x54, 0x35,
48	0x82, 0xbb, 0x7f, 0x93, 0xd3, 0xb8, 0xd6, 0x40,
49	0x37, 0x8f, 0x13, 0x99, 0x98, 0x6a, 0x92, 0xe9,
50	0x31, 0xeb, 0xa3, 0x7b, 0xf6, 0xad, 0x73, 0x06,
51	0x1e, 0x84, 0x3e, 0xbd, 0x9b, 0x6c, 0x63, 0x62,
52	0x9a, 0xb0, 0x23, 0x9c, 0x08, 0xcf, 0xc3, 0x5c,
53	0x92, 0xf6, 0xed, 0x5f, 0x8a, 0x88, 0xb4, 0x39,
54	0xd5, 0xb6, 0x33, 0xc3, 0xc2, 0x63, 0x2c, 0x3f,
55	0x0b, 0x21, 0xc2, 0x8b, 0x30, 0xde, 0x84, 0x90,
56	0xcb, 0x76, 0x26, 0x71, 0xff, 0x47, 0x0b, 0x91,
57	0x9e, 0x51, 0xfc, 0x44, 0xeb, 0x9a, 0xb9, 0x33,
58	0xfd, 0x54, 0xbf, 0xed, 0xeb, 0x2b, 0xad, 0xc2,
59	0x51, 0x67, 0x80, 0xae, 0x9e, 0xcc, 0x60, 0xeb,
60	0xd3, 0xf8, 0x1e, 0x7b, 0xd8, 0x15, 0x35, 0xcf,
61	0x00, 0x97, 0x66, 0x68, 0xf9, 0x3a, 0x43, 0x05,
62	0x4a, 0xac, 0xf5, 0x9e, 0x49, 0x0e, 0x54, 0x97,
63	0x52, 0xec, 0x30, 0xe5, 0x29, 0xac, 0x0e, 0xa0,
64	0x33, 0x0e, 0x89, 0x28, 0x0f, 0x12, 0x37, 0x99,
65	0x86, 0x4c, 0xe4, 0x29, 0x97, 0x0a, 0x58, 0x91,
66	0xd2, 0x69, 0xa1, 0x25, 0xae, 0x2a, 0x2d, 0xa4,
67	0x8a, 0xae, 0x98, 0xa2, 0x9b, 0x57, 0xa1, 0xc1,
68	0x8a, 0x03, 0xf0, 0x5f, 0xa5, 0xe4, 0x4a, 0x81,
69	0x90, 0x80, 0xdb, 0x32, 0x47, 0x02, 0x23, 0x74,
70	0xc9, 0x0a, 0x8d, 0x5c, 0xc5, 0x80, 0x45, 0x92,
71	0x57, 0x29, 0x16, 0x9b, 0x18, 0x08, 0x00, 0x0a,
72	0xa1, 0xa3, 0x1c, 0xb7, 0xa8, 0x69, 0x4c, 0x8b,
73	0x38, 0x90, 0x7e, 0xbe, 0x06, 0x62, 0x0d, 0x5b,
74	0x2e, 0x93, 0x8c, 0xfe, 0xb2, 0x15, 0xe6, 0xa8,
75	0x0f, 0x81, 0x6f, 0x8d, 0xba, 0xf0, 0x5c, 0x6b,
76	0x21, 0x23, 0x06, 0x25, 0x93, 0x1a, 0x93, 0x2a,
77	0x67, 0x12, 0xca, 0x4a, 0x96, 0x42, 0x71, 0xf0,
78	0xb6, 0x52, 0x54, 0x49, 0xce, 0x70, 0xcb, 0xd3,
79	0x05, 0xb1, 0x13, 0x23, 0xf0, 0x1d, 0x2f, 0x34,
80	0xa8, 0x8c, 0xe5, 0xf9, 0x47, 0x97, 0xd1, 0x1f,
81	0x97, 0x5e, 0xfb, 0xa5, 0x47, 0x58, 0x71, 0xc8,
82	0x91, 0xad, 0x72, 0xee, 0x99, 0x82, 0xcb, 0x14,
83	0x25, 0x4f, 0xb4, 0xb7, 0xf3, 0x5e, 0x25, 0x94,
84	0x1c, 0xe9, 0xcb, 0xe3, 0x48, 0x95, 0x3c, 0x41,
85	0x2a, 0x28, 0x0c, 0x4e, 0x66, 0x98, 0x3c, 0xc4,
86	0x67, 0x4c, 0xc5, 0x7f, 0x56, 0x34, 0x44, 0x4d,
87	0x48, 0xd9, 0x96, 0x6d, 0xc8, 0xdb, 0xf5, 0x3f,
88	0x22, 0xa1, 0x9d, 0x24, 0x95, 0xe4, 0x5b, 0xaf,
89	0x99, 0x72, 0x50, 0xd5, 0x4a, 0x69, 0xd4, 0x95,
90	0xe6, 0xb0, 0x11, 0x22, 0x0d, 0x41, 0x2b, 0x2e,
91	0x77, 0x98, 0x70, 0xf5, 0x03, 0x72, 0xa1, 0x42,
92	0x5a, 0x95, 0xe2, 0x71, 0x94, 0x32, 0xcd, 0x02,
93	0x31, 0x41, 0x50, 0x54, 0xd4, 0xa6, 0x7a, 0x55,
94	0x29, 0x0c, 0xa1, 0x61, 0xa1, 0xb9, 0x94, 0x55,
95	0xa9, 0x51, 0x14, 0x37, 0xb4, 0xdf, 0x3d, 0xc5,
96	0x42, 0x1a, 0x19, 0x5d, 0x4d, 0x43, 0xba, 0xa2,
97	0xf0, 0x56, 0xe9, 0x91, 0x70, 0x21, 0x0f, 0x1e,
98	0xd4, 0x67, 0x10, 0xc2, 0x8f, 0x61, 0x9f, 0x71,
99	0x3a, 0x97, 0x3e, 0xd0, 0x90, 0x14, 0xf3, 0x11,
100	0x28, 0x4a, 0x2c, 0xd1, 0x97, 0x63, 0xc4, 0x47,
101	0x01, 0xea, 0xe8, 0xdd, 0x23, 0x14, 0x7c, 0x93,
102	0xe3, 0x86, 0x17, 0x09, 0xf7, 0x5d, 0xe1, 0x51,
103	0xf6, 0xa8, 0xf8, 0x0d, 0xed, 0x0a, 0x95, 0x1f,
104	0xc0, 0x40, 0x4b, 0xdb, 0x27, 0xce, 0x2a, 0x58,
105	0xf6, 0x3b, 0x22, 0x55, 0x51, 0x28, 0x2f, 0x5e,
106	0x6c, 0x1c, 0x36, 0x09, 0xb8, 0x06, 0x96, 0xee,
107	0xd0, 0xcb, 0x3e, 0x0f, 0xd3, 0xee, 0x15, 0x9e,
108	0xdf, 0x49, 0x88, 0x2c, 0xc9, 0xce, 0x71, 0x2f,
109	0xa2, 0xdf, 0xdf, 0xd7, 0x8e, 0x9c,
110};
111
112/*
113 * expected sha256 of rfc1950_blob after decompression
114 */
115static const unsigned char rfc1950_blob_hash[SHA256_DIGEST_LENGTH] = {
116	0x61, 0xc0, 0x4e, 0x14, 0x01, 0xb6, 0xc5, 0x2d,
117	0xba, 0x15, 0xf6, 0x27, 0x4c, 0xa1, 0xcc, 0xfc,
118	0x39, 0xed, 0xd7, 0x12, 0xb6, 0x02, 0x3d, 0xb6,
119	0xd9, 0x85, 0xd0, 0x10, 0x9f, 0xe9, 0x3e, 0x75,
120
121};
122
123static const size_t rfc1950_blob_origsiz = 1322;
124
125static /* const */ unsigned char random_words[515] = {
126	0x61, 0x74, 0x68, 0x69, 0x72, 0x73, 0x74, 0x20,
127	0x54, 0x68, 0x6f, 0x20, 0x63, 0x6f, 0x74, 0x20,
128	0x73, 0x70, 0x6f, 0x66, 0x66, 0x79, 0x20, 0x4a,
129	0x61, 0x76, 0x61, 0x6e, 0x20, 0x62, 0x72, 0x65,
130	0x64, 0x65, 0x73, 0x20, 0x4c, 0x41, 0x4d, 0x20,
131	0x6d, 0x69, 0x73, 0x2d, 0x68, 0x75, 0x6d, 0x69,
132	0x6c, 0x69, 0x74, 0x79, 0x20, 0x73, 0x70, 0x69,
133	0x67, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x76, 0x6f,
134	0x6c, 0x74, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x20,
135	0x49, 0x6f, 0x64, 0x61, 0x6d, 0x6f, 0x65, 0x62,
136	0x61, 0x20, 0x68, 0x79, 0x70, 0x6f, 0x68, 0x79,
137	0x64, 0x72, 0x6f, 0x63, 0x68, 0x6c, 0x6f, 0x72,
138	0x69, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d,
139	0x65, 0x74, 0x74, 0x65, 0x20, 0x61, 0x63, 0x72,
140	0x69, 0x64, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x6f,
141	0x77, 0x6c, 0x20, 0x45, 0x75, 0x72, 0x79, 0x67,
142	0x61, 0x65, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e,
143	0x63, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x73,
144	0x74, 0x20, 0x74, 0x65, 0x74, 0x72, 0x61, 0x70,
145	0x6c, 0x6f, 0x69, 0x64, 0x20, 0x61, 0x75, 0x78,
146	0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x72,
147	0x69, 0x70, 0x65, 0x2d, 0x67, 0x72, 0x6f, 0x77,
148	0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72,
149	0x72, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x79, 0x63,
150	0x6f, 0x63, 0x65, 0x63, 0x69, 0x64, 0x69, 0x75,
151	0x6d, 0x20, 0x50, 0x65, 0x64, 0x65, 0x72, 0x73,
152	0x6f, 0x6e, 0x20, 0x74, 0x72, 0x61, 0x64, 0x69,
153	0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x62, 0x6f, 0x75,
154	0x6e, 0x64, 0x20, 0x4c, 0x65, 0x6e, 0x67, 0x6c,
155	0x65, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x62,
156	0x79, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20,
157	0x6c, 0x65, 0x63, 0x79, 0x74, 0x68, 0x69, 0x73,
158	0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x64, 0x72,
159	0x69, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61,
160	0x6c, 0x6c, 0x6f, 0x6b, 0x75, 0x72, 0x74, 0x69,
161	0x63, 0x20, 0x75, 0x6e, 0x64, 0x69, 0x76, 0x69,
162	0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x70,
163	0x73, 0x79, 0x63, 0x68, 0x6f, 0x6b, 0x79, 0x6d,
164	0x65, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73,
165	0x74, 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65,
166	0x6e, 0x65, 0x73, 0x73, 0x20, 0x63, 0x75, 0x6c,
167	0x74, 0x69, 0x73, 0x68, 0x20, 0x52, 0x65, 0x69,
168	0x63, 0x68, 0x73, 0x74, 0x61, 0x67, 0x20, 0x75,
169	0x6e, 0x63, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x6e,
170	0x61, 0x74, 0x65, 0x64, 0x20, 0x6c, 0x6f, 0x67,
171	0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72,
172	0x20, 0x4c, 0x61, 0x69, 0x74, 0x68, 0x20, 0x74,
173	0x77, 0x6f, 0x2d, 0x66, 0x61, 0x63, 0x65, 0x20,
174	0x4d, 0x75, 0x70, 0x68, 0x72, 0x69, 0x64, 0x20,
175	0x70, 0x72, 0x6f, 0x72, 0x65, 0x63, 0x69, 0x70,
176	0x72, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
177	0x20, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x74, 0x74,
178	0x69, 0x73, 0x74, 0x20, 0x49, 0x62, 0x69, 0x62,
179	0x69, 0x6f, 0x20, 0x72, 0x65, 0x67, 0x72, 0x65,
180	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x63,
181	0x6f, 0x6e, 0x64, 0x69, 0x67, 0x6e, 0x6e, 0x65,
182	0x73, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65,
183	0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65,
184	0x64, 0x20, 0x73, 0x79, 0x6e, 0x61, 0x70, 0x74,
185	0x65, 0x6e, 0x65, 0x20, 0x68, 0x6f, 0x6c, 0x6f,
186	0x6d, 0x6f, 0x72, 0x70, 0x68, 0x20, 0x6d, 0x6f,
187	0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x4d,
188	0x49, 0x54, 0x53, 0x20, 0x4c, 0x75, 0x6b, 0x61,
189	0x73, 0x68, 0x20, 0x48, 0x6f, 0x72, 0x73, 0x65,
190	0x79, 0x20, 0x0a,
191};
192
193static void
194rfc1950_inflate(void)
195{
196	fido_blob_t in, out, dgst;
197
198	memset(&in, 0, sizeof(in));
199	memset(&out, 0, sizeof(out));
200	memset(&dgst, 0, sizeof(dgst));
201	in.ptr = rfc1950_blob;
202	in.len = sizeof(rfc1950_blob);
203
204	assert(fido_uncompress(&out, &in, rfc1950_blob_origsiz) == FIDO_OK);
205	assert(out.len == rfc1950_blob_origsiz);
206	assert(fido_sha256(&dgst, out.ptr, out.len) == 0);
207	assert(dgst.len == sizeof(rfc1950_blob_hash));
208	assert(memcmp(rfc1950_blob_hash, dgst.ptr, dgst.len) == 0);
209
210	free(out.ptr);
211	free(dgst.ptr);
212}
213
214static void
215rfc1951_inflate(void)
216{
217	fido_blob_t in, out, dgst;
218
219	memset(&in, 0, sizeof(in));
220	memset(&out, 0, sizeof(out));
221	memset(&dgst, 0, sizeof(dgst));
222	in.ptr = rfc1950_blob + 2; /*  trim header */
223	in.len = sizeof(rfc1950_blob) - 6; /* trim header (2), checksum (4) */
224
225	assert(fido_uncompress(&out, &in, rfc1950_blob_origsiz) == FIDO_OK);
226	assert(out.len == rfc1950_blob_origsiz);
227	assert(fido_sha256(&dgst, out.ptr, out.len) == 0);
228	assert(dgst.len == sizeof(rfc1950_blob_hash));
229	assert(memcmp(rfc1950_blob_hash, dgst.ptr, dgst.len) == 0);
230
231	free(out.ptr);
232	free(dgst.ptr);
233}
234
235static void
236rfc1951_reinflate(void)
237{
238	fido_blob_t in, out;
239
240	memset(&in, 0, sizeof(in));
241	memset(&out, 0, sizeof(out));
242	in.ptr = random_words;
243	in.len = sizeof(random_words);
244
245	assert(fido_compress(&out, &in) == FIDO_OK);
246
247	in.ptr = out.ptr;
248	in.len = out.len;
249
250	assert(fido_uncompress(&out, &in, sizeof(random_words)) == FIDO_OK);
251	assert(out.len == sizeof(random_words));
252	assert(memcmp(out.ptr, random_words, out.len) == 0);
253
254	free(in.ptr);
255	free(out.ptr);
256}
257
258int
259main(void)
260{
261	fido_init(0);
262
263	rfc1950_inflate();
264	rfc1951_inflate();
265	rfc1951_reinflate();
266
267	exit(0);
268}
269