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