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