1/*	$NetBSD: test_engine_dso.c,v 1.1.1.1 2011/04/13 18:14:51 elric Exp $	*/
2
3/*
4 * Copyright (c) 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <config.h>
37
38#include <stdio.h>
39
40#include <krb5/roken.h>
41#include <krb5/getarg.h>
42
43#include <engine.h>
44#include <evp.h>
45
46struct {
47    const char *cpriv;
48    const char *cpub;
49    const char *spriv;
50    const char *spub;
51} dhtests[] = {
52    {
53	"5C0946275D07223AEAF04301D964498F3285946057B4C50D13B4FE12C88DFD8D499DD3CC00C1BC17C0D343F2FE053C9F53389110551715B1EDF261A0314485C4835D01F7B8894027D534A2D81D63619D2F58C9864AC9816086B3FF75C01B3FAFF355425AB7369A6ABDC8B633F0A0DC4D29B50F364E7594B297183D14E5CDC05D",
54	"2D66DC5998B7AEE3332DC1061C6E6F6CF0FCCD74534187E2CDC9ACBCADF0FC9D5900451F44832A762F01E9CEEF1CBD7D69D020AC524D09FAD087DFADEAC36C845157B83937B51C8DB7F500C3C54FB2A05E074E40BA982186E7FEB2534EDDB387D5480AAA355B398CCAD0886F3952C3718490B7884FA67BD8B6943CDDA20134C6",
55	"42644BA7CF74689E18BA72BF80FCA674D1A2ADF81795EB3828E67C30E42ABD07A8E90E27F046189FAC122D915276870B72427388EAAB5D06994FC38885BBACCEA1CFC45951B730D73C1A8F83208CD1351746601648C11D70BC95B817C86E4A5C40D633654615041C7934BB3CAF4E02754D542033DB024E94C7E561A29ED0C6EC",
56	"C233633AB116E2DB20B4E08DA42DE8766293E6D9042F7A2C2A2F34F18FE66010B074CCF3C9B03EF27B14F0746B738AF22776224161D767D96AEC230A1DFA6DECFFCE9FED23B96F50CCB0093E59817AD0CEAEB7993AB5764679948BFB1293C9560B07AA3DFA229E341EB17C9FAE0B1D483082461D2DDBCEEE6FE7C0A34D96F66D"
57    },
58    {
59	"76295C1280B890970F0F7EB01BBD9C5DF9BB8F590EB384A39EBF85CD141451407F955FD1D39012AA1F8BA53FD6A5A37CB2835CEDB27D1EBF1FE8AC9F2FFD628BD9BF7B8DD77CB80C8DC0A75F4567C7700442B26972833EB9738A8728A1FC274C59CED5E3ADA224B46711112AAA1CB831D2D6125E183ADA4F805A05024C9C6DDB",
60	"1E0AB5EBAAC7985FE67A574447FAE58AE4CB95416278D4C239A789D4532FA8E6F82BA10BE411D8A0A06B9E1DECE704466B3523496A8A4165B97FBCFB9CE9C4FF2DEEE786BA046E8C270FA8A9055D2F6E42EDDB32C73CF7875551A56EB69C0F14A3745745845B81C347401B27D074C60C5177BA9C14BBB1C8C219B78E15126EF8",
61	"68D84A8F92082F113542CFD990DEEFAD9C7EFA545268F8B3EBDF4CCBAF2865CF03EF60044EB4AF4154E6804CC2BDD673B801507446CEFC692DA577B6DC6E0272B7B081A1BEFDC2A4FAC83DB8845E3DA0D1B64DB33AA2164FEDB08A01E815336BD58F4E6DE6A265468E61C8C988B8AEC0D52DB714448DDC007E7C3382C07357DB",
62	"393815D507A2EF80DE2D0F2A55AAB1C25B870ACA3FC97438B4336CBF979BF9A4F8DA1B61C667129F9123045E07E24976040EC5E2368DD4EF70690102D74E900B260D3826256FD473733A7569BF514652AB78C48C334FDCA26C44ABF322643AF15BFF693A37BB2C19CA9FE5F1537FCFE2B24CF74D4E57060D35ABF115B4B6CD21"
63    },
64    {
65	"7307D6C3CB874327A95F7A6A91C336CEAA086736525DF3F8EC49497CF444C68D264EB70CD6904FE56E240EEF34E6C5177911C478A7F250A0F54183BCBE64B42BAB5D019E73E2F17C095C211E4815E6BA5FDD72786AF987ABBC9109ECEEF439AF9E2141D5222CE7DC0152D8E9A6CCCE301D21A7D1D6ACB9B91B5E28379C91890D",
66	"83FBD7BFFDF415BBB7E21D399CB2F36A61AFDBAFC542E428E444C66AA03617C0C55C639FE2428905B57035892AE1BD2C4060E807D9E003B0C204FFC8FDD69CC8ADE7A8E18DCBFFF64E3EF9DA2C117390374241466E48A020A1B2F575AE42C233F8BD357B8331CC203E0345DFC19C73E6F1F70B6C2786E681D73BF48B15FE9992",
67	"61BCF748BB05A48861578B8CB1855200B2E62A40E126BD7323E5B714645A54A2C8761EE39EE39BA6D2FE19B688168EDEA6DC5056400B5315ED299E7926176B887012E58634D78F05D7BCF0E1B81B1B41F5F8EF0B0711D3A64F9A317DD183AE039A4D3BE02A515892362F8C7BB6EB6434BB25418A438ED33D50C475122CBBE862",
68	"7DB8D69D1605D9812B7F2F3E92BCEEB3426FEEE3265A174D71B2B6E16B332B43DF0B3C2FA152E48DE2FAC110D8CECE122C3398558E7987B27CACE12722C0032AC7E7766A9BCC881BA35B9DB9E751BD4E51F7683DE092F6C1D4DD937CDCE9C16E6F7D77CC6AAD806E4082E8E22E28592C4D78256354393FE831E811E03ED0A81A"
69    },
70    {
71	"60C18B62F786DE6A4A8B13EB6DA2380B4C6731F861C715D9496DCF4A9F01CD33DDB52F1AB4D1F820FAF7AD4EFEB66586F7F08135714B13D77FE652B9EEAB2C543596A9ED307C1629CF535DD14AB22F081AE4ADF7A3E0BC7B33E0EC7A7306F9A737F55807974B5E1B7B6394BD0373917128B43A17757B34BAE1B600763E957F75",
72	"0DEDA337C38EA005D5B8567EAB681CE91892C2C62C9D42BF748FBFE681E11F25D98280E42E1539A10EEE9177EF2F40216987936AF19D9B5EBE22EEAC27242D77CE3A5061F2E5CFACF15CD0F80E736AE8642252FE91E129DE3C78CFB85A0B1BB87B059CBB24483444F8A07244F4E89370BA78D58BD409DFBB3D41921B8879B9C7",
73	"462C0707CF3366C2242A808CFDB79B77E8B3AF9D796583EB9CCD7BF4E8792AB0A818E49FFE53CA241F56988F825B366BF1E78481F8086A123259B9D83AC643E85845BF6B2C5412FFDDFAA8C9ED203CA4B3C1BFD777286099976472FA15B3CCC8418CF162F03C0C3E85D7EFC5CF5ACB9B2C039CCF3A1A9C6BB6B9C09C18D86CBD",
74	"56DB382EDB8C2D95934D20261CE1A37090B0802D451E647DB1DA3B73CDB5A878EAD598A8817302449370F9D45E34F5C45F73D02BF4EB2B3712A8665F446F5D2B774039E5444AB74807859FA58DF9EBA4B12BA4545ACED827E4ED64CC71F937D64A1033BC43403F2490C1B715A74822B8D50A72A102213F0CF7A1B98B771B34C4"
75    },
76    {
77	"61B7321207F4A73646E43E99221F902D2F38095E84CE7346A1510FE71BA7B9B34DCB6609E4DDDA8C82426E82D1C23F1E761130ECE4638D77554A7618E1608625049328FCC1F8845CA9A88E847106B01BD31EF6500E3C7EE81A048924BEAA3EDF367E5F4575341206C7A76427571898294B07BD918D4C2642854CC89D439042E5",
78	"29AA38E63E4DD7C651E25DEC7A5A53E48114F52813793D36A9DBDD4F7C06FC38406E330764E0B2AFD811C39D857EA5F904105360E06856DC0780C7D61C53165833F0AEA15CB54732DE113F44C8FCFB86F4A876DD42D7A55356D91C0173F2B012680FB54C13EF54B65DF4AEDE2E13419B1316435187CEF07D44DB3DF57C4703FD",
79	"5ED5AFB04CBFEE43EF3D9B60A57080831563648A2380D98F1EA4A96CF153903A40A2E564DED87E7254DF3270568AB952BF6F400681DD6AD919C9B06AC0F45F0646BCF37B217191AA0B7B7BED226B61F48B46DEA2E5A09E41F316583823A38A60FFD79085F43F60D98871ECA1A0F667701425094E88885A81DE9DA6C293E95060",
80	"4DE4F24EAA3E2790FBCB1B13C2ED0EFD846EC33154DBEBBEFD895E1399B3617D55EC2CE8D71CF380B55D93636FEF741328D6B1E224D46F8A8B60A41D08DD86E88DE806AA781791364E6D88BF68571BF5D8C35CB04BA302227B7E4CB6A67AB7510ACBCDBF2F8A95EB5DEE693CCA5CC425A0F1CA2D18C369A767906A2477E32704"
81    }
82};
83
84static void
85dh_test(DH *server, DH *client)
86{
87    void *skey, *ckey;
88    int ssize, csize;
89
90    skey = emalloc(DH_size(server));
91    ckey = emalloc(DH_size(client));
92
93    ssize = DH_compute_key(skey, client->pub_key, server);
94    if (ssize == -1)
95	errx(1, "DH_compute_key failed for server");
96    csize = DH_compute_key(ckey, server->pub_key, client);
97    if (csize == -1)
98	errx(1, "DH_compute_key failed for client");
99
100    if (ssize != csize)
101	errx(1, "DH_compute_key size mismatch");
102
103    if (memcmp(skey, ckey, csize) != 0)
104	errx(1, "DH_compute_key key mismatch");
105
106    free(skey);
107    free(ckey);
108}
109
110
111static int version_flag;
112static int help_flag;
113static char *id_flag;
114static char *rsa_flag;
115static int dh_flag = 1;
116static int test_random_flag;
117
118static struct getargs args[] = {
119    { "id",		0,	arg_string,	&id_flag,
120      "selects the engine id", 	"engine-id" },
121    { "rsa",		0,	arg_string,	&rsa_flag,
122      "tests RSA modes", 	"private-rsa-der-file" },
123    { "dh",		0,	arg_negative_flag,	&dh_flag,
124      "test dh", NULL },
125    { "test-random",	0,	arg_flag,	&test_random_flag,
126      "test if there is a random device", NULL },
127    { "version",	0,	arg_flag,	&version_flag,
128      "print version", NULL },
129    { "help",		0,	arg_flag,	&help_flag,
130      NULL, 	NULL }
131};
132
133static void
134usage (int ret)
135{
136    arg_printusage (args,
137		    sizeof(args)/sizeof(*args),
138		    NULL,
139		    "filename.so");
140    exit (ret);
141}
142
143int
144main(int argc, char **argv)
145{
146    ENGINE *engine = NULL;
147    int idx = 0;
148    int have_rsa, have_dh;
149
150    setprogname(argv[0]);
151
152    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &idx))
153	usage(1);
154
155    if (help_flag)
156	usage(0);
157
158    if(version_flag){
159	print_version(NULL);
160	exit(0);
161    }
162
163    argc -= idx;
164    argv += idx;
165
166    OpenSSL_add_all_algorithms();
167
168    if (argc == 0) {
169	OpenSSL_add_all_algorithms();
170	ENGINE_load_builtin_engines();
171	engine = ENGINE_by_id("builtin");
172    } else {
173	engine = ENGINE_by_dso(argv[0], id_flag);
174    }
175    if (engine == NULL)
176	errx(1, "ENGINE_by_dso failed");
177
178    printf("name: %s\n", ENGINE_get_name(engine));
179    printf("id: %s\n", ENGINE_get_id(engine));
180    have_rsa = ENGINE_get_RSA(engine) != NULL;
181    have_dh = ENGINE_get_DH(engine) != NULL;
182    printf("RSA: %s", have_rsa ? "yes," : "no");
183    if (have_rsa)
184	printf(" %s", ENGINE_get_RSA(engine)->name);
185    printf("\n");
186    printf("DH: %s", have_dh ? "yes," : "no");
187    if (have_dh)
188	printf(" %s", ENGINE_get_DH(engine)->name);
189    printf("\n");
190
191    if (RAND_status() != 1)
192	errx(77, "no functional random device, can't execute tests");
193    if (test_random_flag)
194	exit(0);
195
196    if (rsa_flag && have_rsa) {
197	unsigned char buf[1024 * 4];
198	const unsigned char *p;
199	size_t size;
200	int keylen;
201	RSA *rsa;
202	FILE *f;
203
204	f = fopen(rsa_flag, "rb");
205	if (f == NULL)
206	    err(1, "could not open file %s", rsa_flag);
207
208	size = fread(buf, 1, sizeof(buf), f);
209	if (size == 0)
210	    err(1, "failed to read file %s", rsa_flag);
211	if (size == sizeof(buf))
212	    err(1, "key too long in file %s!", rsa_flag);
213	fclose(f);
214
215	p = buf;
216	rsa = d2i_RSAPrivateKey(NULL, &p, size);
217	if (rsa == NULL)
218	    err(1, "failed to parse key in file %s", rsa_flag);
219
220	RSA_set_method(rsa, ENGINE_get_RSA(engine));
221
222	/*
223	 * try rsa signing
224	 */
225
226	memcpy(buf, "hejsan", 7);
227	keylen = RSA_private_encrypt(7, buf, buf, rsa, RSA_PKCS1_PADDING);
228	if (keylen <= 0)
229	    errx(1, "failed to private encrypt");
230
231	keylen = RSA_public_decrypt(keylen, buf, buf, rsa, RSA_PKCS1_PADDING);
232	if (keylen <= 0)
233	    errx(1, "failed to public decrypt");
234
235	if (keylen != 7)
236	    errx(1, "output buffer not same length: %d", (int)keylen);
237
238	if (memcmp(buf, "hejsan", 7) != 0)
239	    errx(1, "string not the same after decryption");
240
241	/*
242	 * try rsa encryption
243	 */
244
245	memcpy(buf, "hejsan", 7);
246	keylen = RSA_public_encrypt(7, buf, buf, rsa, RSA_PKCS1_PADDING);
247	if (keylen <= 0)
248	    errx(1, "failed to public encrypt");
249
250	keylen = RSA_private_decrypt(keylen, buf, buf, rsa, RSA_PKCS1_PADDING);
251	if (keylen <= 0)
252	    errx(1, "failed to private decrypt");
253
254	if (keylen != 7)
255	    errx(1, "output buffer not same length: %d", (int)keylen);
256
257	if (memcmp(buf, "hejsan", 7) != 0)
258	    errx(1, "string not the same after decryption");
259
260	RSA_free(rsa);
261
262	printf("rsa test passed\n");
263
264    }
265
266    if (dh_flag) {
267	DH *server, *client;
268	int i;
269
270	/* RFC2412-MODP-group2 */
271	const char *p =
272	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
273	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
274	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
275	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
276	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
277	    "FFFFFFFF" "FFFFFFFF";
278	const char *g = "02";
279
280	/*
281	 * Try generated keys
282	 */
283
284	for (i = 0; i < 10; i++) {
285	    server = DH_new_method(engine);
286	    client = DH_new_method(engine);
287
288	    BN_hex2bn(&server->p, p);
289	    BN_hex2bn(&client->p, p);
290	    BN_hex2bn(&server->g, g);
291	    BN_hex2bn(&client->g, g);
292
293	    if (!DH_generate_key(server))
294		errx(1, "DH_generate_key failed for server");
295	    if (!DH_generate_key(client))
296		errx(1, "DH_generate_key failed for client");
297
298	    dh_test(server, client);
299
300	    DH_free(server);
301	    DH_free(client);
302	}
303	/*
304	 * Try known result
305	 */
306
307	for (i = 0; i < sizeof(dhtests)/sizeof(dhtests[0]); i++) {
308
309	    server = DH_new_method(engine);
310	    client = DH_new_method(engine);
311
312	    BN_hex2bn(&server->p, p);
313	    BN_hex2bn(&client->p, p);
314	    BN_hex2bn(&server->g, g);
315	    BN_hex2bn(&client->g, g);
316
317	    BN_hex2bn(&client->priv_key, dhtests[i].cpriv);
318	    BN_hex2bn(&client->pub_key, dhtests[i].cpub);
319	    BN_hex2bn(&server->priv_key, dhtests[i].spriv);
320	    BN_hex2bn(&server->pub_key, dhtests[i].spub);
321
322	    dh_test(server, client);
323
324	    DH_free(server);
325	    DH_free(client);
326	}
327
328	printf("DH test passed\n");
329    }
330
331    ENGINE_finish(engine);
332
333    return 0;
334}
335