xref: /minix3/crypto/external/bsd/heimdal/dist/lib/hcrypto/test_engine_dso.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 /*	$NetBSD: test_engine_dso.c,v 1.1.1.2 2014/04/24 12:45:30 pettai 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 
46 struct {
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 
84 static void
dh_test(DH * server,DH * client)85 dh_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 
111 static int version_flag;
112 static int help_flag;
113 static char *id_flag;
114 static char *rsa_flag;
115 static int dh_flag = 1;
116 static int test_random_flag;
117 
118 static 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 
133 static void
usage(int ret)134 usage (int ret)
135 {
136     arg_printusage (args,
137 		    sizeof(args)/sizeof(*args),
138 		    NULL,
139 		    "filename.so");
140     exit (ret);
141 }
142 
143 int
main(int argc,char ** argv)144 main(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