xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/hcrypto/test_engine_dso.c (revision d3273b5b76f5afaafe308cead5511dbb8df8c5e9)
1 /*	$NetBSD: test_engine_dso.c,v 1.2 2017/01/28 21:31:47 christos 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 #include <krb5/roken.h>
38 #include <krb5/getarg.h>
39 
40 #include <engine.h>
41 #include <evp.h>
42 
43 struct {
44     const char *cpriv;
45     const char *cpub;
46     const char *spriv;
47     const char *spub;
48 } dhtests[] = {
49     {
50 	"5C0946275D07223AEAF04301D964498F3285946057B4C50D13B4FE12C88DFD8D499DD3CC00C1BC17C0D343F2FE053C9F53389110551715B1EDF261A0314485C4835D01F7B8894027D534A2D81D63619D2F58C9864AC9816086B3FF75C01B3FAFF355425AB7369A6ABDC8B633F0A0DC4D29B50F364E7594B297183D14E5CDC05D",
51 	"2D66DC5998B7AEE3332DC1061C6E6F6CF0FCCD74534187E2CDC9ACBCADF0FC9D5900451F44832A762F01E9CEEF1CBD7D69D020AC524D09FAD087DFADEAC36C845157B83937B51C8DB7F500C3C54FB2A05E074E40BA982186E7FEB2534EDDB387D5480AAA355B398CCAD0886F3952C3718490B7884FA67BD8B6943CDDA20134C6",
52 	"42644BA7CF74689E18BA72BF80FCA674D1A2ADF81795EB3828E67C30E42ABD07A8E90E27F046189FAC122D915276870B72427388EAAB5D06994FC38885BBACCEA1CFC45951B730D73C1A8F83208CD1351746601648C11D70BC95B817C86E4A5C40D633654615041C7934BB3CAF4E02754D542033DB024E94C7E561A29ED0C6EC",
53 	"C233633AB116E2DB20B4E08DA42DE8766293E6D9042F7A2C2A2F34F18FE66010B074CCF3C9B03EF27B14F0746B738AF22776224161D767D96AEC230A1DFA6DECFFCE9FED23B96F50CCB0093E59817AD0CEAEB7993AB5764679948BFB1293C9560B07AA3DFA229E341EB17C9FAE0B1D483082461D2DDBCEEE6FE7C0A34D96F66D"
54     },
55     {
56 	"76295C1280B890970F0F7EB01BBD9C5DF9BB8F590EB384A39EBF85CD141451407F955FD1D39012AA1F8BA53FD6A5A37CB2835CEDB27D1EBF1FE8AC9F2FFD628BD9BF7B8DD77CB80C8DC0A75F4567C7700442B26972833EB9738A8728A1FC274C59CED5E3ADA224B46711112AAA1CB831D2D6125E183ADA4F805A05024C9C6DDB",
57 	"1E0AB5EBAAC7985FE67A574447FAE58AE4CB95416278D4C239A789D4532FA8E6F82BA10BE411D8A0A06B9E1DECE704466B3523496A8A4165B97FBCFB9CE9C4FF2DEEE786BA046E8C270FA8A9055D2F6E42EDDB32C73CF7875551A56EB69C0F14A3745745845B81C347401B27D074C60C5177BA9C14BBB1C8C219B78E15126EF8",
58 	"68D84A8F92082F113542CFD990DEEFAD9C7EFA545268F8B3EBDF4CCBAF2865CF03EF60044EB4AF4154E6804CC2BDD673B801507446CEFC692DA577B6DC6E0272B7B081A1BEFDC2A4FAC83DB8845E3DA0D1B64DB33AA2164FEDB08A01E815336BD58F4E6DE6A265468E61C8C988B8AEC0D52DB714448DDC007E7C3382C07357DB",
59 	"393815D507A2EF80DE2D0F2A55AAB1C25B870ACA3FC97438B4336CBF979BF9A4F8DA1B61C667129F9123045E07E24976040EC5E2368DD4EF70690102D74E900B260D3826256FD473733A7569BF514652AB78C48C334FDCA26C44ABF322643AF15BFF693A37BB2C19CA9FE5F1537FCFE2B24CF74D4E57060D35ABF115B4B6CD21"
60     },
61     {
62 	"7307D6C3CB874327A95F7A6A91C336CEAA086736525DF3F8EC49497CF444C68D264EB70CD6904FE56E240EEF34E6C5177911C478A7F250A0F54183BCBE64B42BAB5D019E73E2F17C095C211E4815E6BA5FDD72786AF987ABBC9109ECEEF439AF9E2141D5222CE7DC0152D8E9A6CCCE301D21A7D1D6ACB9B91B5E28379C91890D",
63 	"83FBD7BFFDF415BBB7E21D399CB2F36A61AFDBAFC542E428E444C66AA03617C0C55C639FE2428905B57035892AE1BD2C4060E807D9E003B0C204FFC8FDD69CC8ADE7A8E18DCBFFF64E3EF9DA2C117390374241466E48A020A1B2F575AE42C233F8BD357B8331CC203E0345DFC19C73E6F1F70B6C2786E681D73BF48B15FE9992",
64 	"61BCF748BB05A48861578B8CB1855200B2E62A40E126BD7323E5B714645A54A2C8761EE39EE39BA6D2FE19B688168EDEA6DC5056400B5315ED299E7926176B887012E58634D78F05D7BCF0E1B81B1B41F5F8EF0B0711D3A64F9A317DD183AE039A4D3BE02A515892362F8C7BB6EB6434BB25418A438ED33D50C475122CBBE862",
65 	"7DB8D69D1605D9812B7F2F3E92BCEEB3426FEEE3265A174D71B2B6E16B332B43DF0B3C2FA152E48DE2FAC110D8CECE122C3398558E7987B27CACE12722C0032AC7E7766A9BCC881BA35B9DB9E751BD4E51F7683DE092F6C1D4DD937CDCE9C16E6F7D77CC6AAD806E4082E8E22E28592C4D78256354393FE831E811E03ED0A81A"
66     },
67     {
68 	"60C18B62F786DE6A4A8B13EB6DA2380B4C6731F861C715D9496DCF4A9F01CD33DDB52F1AB4D1F820FAF7AD4EFEB66586F7F08135714B13D77FE652B9EEAB2C543596A9ED307C1629CF535DD14AB22F081AE4ADF7A3E0BC7B33E0EC7A7306F9A737F55807974B5E1B7B6394BD0373917128B43A17757B34BAE1B600763E957F75",
69 	"0DEDA337C38EA005D5B8567EAB681CE91892C2C62C9D42BF748FBFE681E11F25D98280E42E1539A10EEE9177EF2F40216987936AF19D9B5EBE22EEAC27242D77CE3A5061F2E5CFACF15CD0F80E736AE8642252FE91E129DE3C78CFB85A0B1BB87B059CBB24483444F8A07244F4E89370BA78D58BD409DFBB3D41921B8879B9C7",
70 	"462C0707CF3366C2242A808CFDB79B77E8B3AF9D796583EB9CCD7BF4E8792AB0A818E49FFE53CA241F56988F825B366BF1E78481F8086A123259B9D83AC643E85845BF6B2C5412FFDDFAA8C9ED203CA4B3C1BFD777286099976472FA15B3CCC8418CF162F03C0C3E85D7EFC5CF5ACB9B2C039CCF3A1A9C6BB6B9C09C18D86CBD",
71 	"56DB382EDB8C2D95934D20261CE1A37090B0802D451E647DB1DA3B73CDB5A878EAD598A8817302449370F9D45E34F5C45F73D02BF4EB2B3712A8665F446F5D2B774039E5444AB74807859FA58DF9EBA4B12BA4545ACED827E4ED64CC71F937D64A1033BC43403F2490C1B715A74822B8D50A72A102213F0CF7A1B98B771B34C4"
72     },
73     {
74 	"61B7321207F4A73646E43E99221F902D2F38095E84CE7346A1510FE71BA7B9B34DCB6609E4DDDA8C82426E82D1C23F1E761130ECE4638D77554A7618E1608625049328FCC1F8845CA9A88E847106B01BD31EF6500E3C7EE81A048924BEAA3EDF367E5F4575341206C7A76427571898294B07BD918D4C2642854CC89D439042E5",
75 	"29AA38E63E4DD7C651E25DEC7A5A53E48114F52813793D36A9DBDD4F7C06FC38406E330764E0B2AFD811C39D857EA5F904105360E06856DC0780C7D61C53165833F0AEA15CB54732DE113F44C8FCFB86F4A876DD42D7A55356D91C0173F2B012680FB54C13EF54B65DF4AEDE2E13419B1316435187CEF07D44DB3DF57C4703FD",
76 	"5ED5AFB04CBFEE43EF3D9B60A57080831563648A2380D98F1EA4A96CF153903A40A2E564DED87E7254DF3270568AB952BF6F400681DD6AD919C9B06AC0F45F0646BCF37B217191AA0B7B7BED226B61F48B46DEA2E5A09E41F316583823A38A60FFD79085F43F60D98871ECA1A0F667701425094E88885A81DE9DA6C293E95060",
77 	"4DE4F24EAA3E2790FBCB1B13C2ED0EFD846EC33154DBEBBEFD895E1399B3617D55EC2CE8D71CF380B55D93636FEF741328D6B1E224D46F8A8B60A41D08DD86E88DE806AA781791364E6D88BF68571BF5D8C35CB04BA302227B7E4CB6A67AB7510ACBCDBF2F8A95EB5DEE693CCA5CC425A0F1CA2D18C369A767906A2477E32704"
78     }
79 };
80 
81 static void
dh_test(DH * server,DH * client)82 dh_test(DH *server, DH *client)
83 {
84     void *skey, *ckey;
85     int ssize, csize;
86 
87     skey = emalloc(DH_size(server));
88     ckey = emalloc(DH_size(client));
89 
90     ssize = DH_compute_key(skey, client->pub_key, server);
91     if (ssize == -1)
92 	errx(1, "DH_compute_key failed for server");
93     csize = DH_compute_key(ckey, server->pub_key, client);
94     if (csize == -1)
95 	errx(1, "DH_compute_key failed for client");
96 
97     if (ssize != csize)
98 	errx(1, "DH_compute_key size mismatch");
99 
100     if (memcmp(skey, ckey, csize) != 0)
101 	errx(1, "DH_compute_key key mismatch");
102 
103     free(skey);
104     free(ckey);
105 }
106 
107 
108 static int version_flag;
109 static int help_flag;
110 static char *id_flag;
111 static char *rsa_flag;
112 static int dh_flag = 1;
113 static int test_random_flag;
114 
115 static struct getargs args[] = {
116     { "id",		0,	arg_string,	&id_flag,
117       "selects the engine id", 	"engine-id" },
118     { "rsa",		0,	arg_string,	&rsa_flag,
119       "tests RSA modes", 	"private-rsa-der-file" },
120     { "dh",		0,	arg_negative_flag,	&dh_flag,
121       "test dh", NULL },
122     { "test-random",	0,	arg_flag,	&test_random_flag,
123       "test if there is a random device", NULL },
124     { "version",	0,	arg_flag,	&version_flag,
125       "print version", NULL },
126     { "help",		0,	arg_flag,	&help_flag,
127       NULL, 	NULL }
128 };
129 
130 static void
usage(int ret)131 usage (int ret)
132 {
133     arg_printusage (args,
134 		    sizeof(args)/sizeof(*args),
135 		    NULL,
136 		    "filename.so");
137     exit (ret);
138 }
139 
140 int
main(int argc,char ** argv)141 main(int argc, char **argv)
142 {
143     ENGINE *engine = NULL;
144     int idx = 0;
145     int have_rsa, have_dh;
146 
147     setprogname(argv[0]);
148 
149     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &idx))
150 	usage(1);
151 
152     if (help_flag)
153 	usage(0);
154 
155     if(version_flag){
156 	print_version(NULL);
157 	exit(0);
158     }
159 
160     argc -= idx;
161     argv += idx;
162 
163     OpenSSL_add_all_algorithms();
164 
165     if (argc == 0) {
166 	OpenSSL_add_all_algorithms();
167 	ENGINE_load_builtin_engines();
168 	engine = ENGINE_by_id("builtin");
169     } else {
170 	engine = ENGINE_by_dso(argv[0], id_flag);
171     }
172     if (engine == NULL)
173 	errx(1, "ENGINE_by_dso failed");
174 
175     printf("name: %s\n", ENGINE_get_name(engine));
176     printf("id: %s\n", ENGINE_get_id(engine));
177     have_rsa = ENGINE_get_RSA(engine) != NULL;
178     have_dh = ENGINE_get_DH(engine) != NULL;
179     printf("RSA: %s", have_rsa ? "yes," : "no");
180     if (have_rsa)
181 	printf(" %s", ENGINE_get_RSA(engine)->name);
182     printf("\n");
183     printf("DH: %s", have_dh ? "yes," : "no");
184     if (have_dh)
185 	printf(" %s", ENGINE_get_DH(engine)->name);
186     printf("\n");
187 
188     if (RAND_status() != 1)
189 	errx(77, "no functional random device, can't execute tests");
190     if (test_random_flag)
191 	exit(0);
192 
193     if (rsa_flag && have_rsa) {
194 	unsigned char buf[1024 * 4];
195 	const unsigned char *p;
196 	size_t size;
197 	int keylen;
198 	RSA *rsa;
199 	FILE *f;
200 
201 	f = fopen(rsa_flag, "rb");
202 	if (f == NULL)
203 	    err(1, "could not open file %s", rsa_flag);
204 
205 	size = fread(buf, 1, sizeof(buf), f);
206 	if (size == 0)
207 	    err(1, "failed to read file %s", rsa_flag);
208 	if (size == sizeof(buf))
209 	    err(1, "key too long in file %s!", rsa_flag);
210 	fclose(f);
211 
212 	p = buf;
213 	rsa = d2i_RSAPrivateKey(NULL, &p, size);
214 	if (rsa == NULL)
215 	    err(1, "failed to parse key in file %s", rsa_flag);
216 
217 	RSA_set_method(rsa, ENGINE_get_RSA(engine));
218 
219 	/*
220 	 * try rsa signing
221 	 */
222 
223 	memcpy(buf, "hejsan", 7);
224 	keylen = RSA_private_encrypt(7, buf, buf, rsa, RSA_PKCS1_PADDING);
225 	if (keylen <= 0)
226 	    errx(1, "failed to private encrypt");
227 
228 	keylen = RSA_public_decrypt(keylen, buf, buf, rsa, RSA_PKCS1_PADDING);
229 	if (keylen <= 0)
230 	    errx(1, "failed to public decrypt");
231 
232 	if (keylen != 7)
233 	    errx(1, "output buffer not same length: %d", (int)keylen);
234 
235 	if (memcmp(buf, "hejsan", 7) != 0)
236 	    errx(1, "string not the same after decryption");
237 
238 	/*
239 	 * try rsa encryption
240 	 */
241 
242 	memcpy(buf, "hejsan", 7);
243 	keylen = RSA_public_encrypt(7, buf, buf, rsa, RSA_PKCS1_PADDING);
244 	if (keylen <= 0)
245 	    errx(1, "failed to public encrypt");
246 
247 	keylen = RSA_private_decrypt(keylen, buf, buf, rsa, RSA_PKCS1_PADDING);
248 	if (keylen <= 0)
249 	    errx(1, "failed to private decrypt");
250 
251 	if (keylen != 7)
252 	    errx(1, "output buffer not same length: %d", (int)keylen);
253 
254 	if (memcmp(buf, "hejsan", 7) != 0)
255 	    errx(1, "string not the same after decryption");
256 
257 	RSA_free(rsa);
258 
259 	printf("rsa test passed\n");
260 
261     }
262 
263     if (dh_flag) {
264 	DH *server, *client;
265 	int i;
266 
267 	/* RFC2412-MODP-group2 */
268 	const char *p =
269 	    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
270 	    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
271 	    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
272 	    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
273 	    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
274 	    "FFFFFFFF" "FFFFFFFF";
275 	const char *g = "02";
276 
277 	/*
278 	 * Try generated keys
279 	 */
280 
281 	for (i = 0; i < 10; i++) {
282 	    server = DH_new_method(engine);
283 	    client = DH_new_method(engine);
284 
285 	    BN_hex2bn(&server->p, p);
286 	    BN_hex2bn(&client->p, p);
287 	    BN_hex2bn(&server->g, g);
288 	    BN_hex2bn(&client->g, g);
289 
290 	    if (!DH_generate_key(server))
291 		errx(1, "DH_generate_key failed for server");
292 	    if (!DH_generate_key(client))
293 		errx(1, "DH_generate_key failed for client");
294 
295 	    dh_test(server, client);
296 
297 	    DH_free(server);
298 	    DH_free(client);
299 	}
300 	/*
301 	 * Try known result
302 	 */
303 
304 	for (i = 0; i < sizeof(dhtests)/sizeof(dhtests[0]); i++) {
305 
306 	    server = DH_new_method(engine);
307 	    client = DH_new_method(engine);
308 
309 	    BN_hex2bn(&server->p, p);
310 	    BN_hex2bn(&client->p, p);
311 	    BN_hex2bn(&server->g, g);
312 	    BN_hex2bn(&client->g, g);
313 
314 	    BN_hex2bn(&client->priv_key, dhtests[i].cpriv);
315 	    BN_hex2bn(&client->pub_key, dhtests[i].cpub);
316 	    BN_hex2bn(&server->priv_key, dhtests[i].spriv);
317 	    BN_hex2bn(&server->pub_key, dhtests[i].spub);
318 
319 	    dh_test(server, client);
320 
321 	    DH_free(server);
322 	    DH_free(client);
323 	}
324 
325 	printf("DH test passed\n");
326     }
327 
328     ENGINE_finish(engine);
329 
330     return 0;
331 }
332