123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983 |
- /*
- * Copyright (c) 2007, Cameron Rich
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the axTLS project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * The testing of the crypto and ssl stuff goes here. Keeps the individual code
- * modules from being uncluttered with test code.
- *
- * This is test code - I make no apologies for the quality!
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #ifndef WIN32
- #include <pthread.h>
- #endif
- #include "ssl.h"
- #define DEFAULT_CERT "../ssl/test/axTLS.x509_512.cer"
- #define DEFAULT_KEY "../ssl/test/axTLS.key_512"
- //#define DEFAULT_SVR_OPTION SSL_DISPLAY_BYTES|SSL_DISPLAY_STATES
- #define DEFAULT_SVR_OPTION 0
- #define DEFAULT_CLNT_OPTION 0
- //#define DEFAULT_CLNT_OPTION SSL_DISPLAY_BYTES|SSL_DISPLAY_STATES
- static int g_port = 19001;
- /**************************************************************************
- * AES tests
- *
- * Run through a couple of the RFC3602 tests to verify that AES is correct.
- **************************************************************************/
- #define TEST1_SIZE 16
- #define TEST2_SIZE 32
- static int AES_test(BI_CTX *bi_ctx)
- {
- AES_CTX aes_key;
- int res = 1;
- uint8_t key[TEST1_SIZE];
- uint8_t iv[TEST1_SIZE];
- {
- /*
- Case #1: Encrypting 16 bytes (1 block) using AES-CBC
- Key : 0x06a9214036b8a15b512e03d534120006
- IV : 0x3dafba429d9eb430b422da802c9fac41
- Plaintext : "Single block msg"
- Ciphertext: 0xe353779c1079aeb82708942dbe77181a
- */
- char *in_str = "Single block msg";
- uint8_t ct[TEST1_SIZE];
- uint8_t enc_data[TEST1_SIZE];
- uint8_t dec_data[TEST1_SIZE];
- bigint *key_bi = bi_str_import(
- bi_ctx, "06A9214036B8A15B512E03D534120006");
- bigint *iv_bi = bi_str_import(
- bi_ctx, "3DAFBA429D9EB430B422DA802C9FAC41");
- bigint *ct_bi = bi_str_import(
- bi_ctx, "E353779C1079AEB82708942DBE77181A");
- bi_export(bi_ctx, key_bi, key, TEST1_SIZE);
- bi_export(bi_ctx, iv_bi, iv, TEST1_SIZE);
- bi_export(bi_ctx, ct_bi, ct, TEST1_SIZE);
- AES_set_key(&aes_key, key, iv, AES_MODE_128);
- AES_cbc_encrypt(&aes_key, (const uint8_t *)in_str,
- enc_data, sizeof(enc_data));
- if (memcmp(enc_data, ct, sizeof(ct)))
- {
- printf("Error: AES ENCRYPT #1 failed\n");
- goto end;
- }
- AES_set_key(&aes_key, key, iv, AES_MODE_128);
- AES_convert_key(&aes_key);
- AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data));
- if (memcmp(dec_data, in_str, sizeof(dec_data)))
- {
- printf("Error: AES DECRYPT #1 failed\n");
- goto end;
- }
- }
- {
- /*
- Case #2: Encrypting 32 bytes (2 blocks) using AES-CBC
- Key : 0xc286696d887c9aa0611bbb3e2025a45a
- IV : 0x562e17996d093d28ddb3ba695a2e6f58
- Plaintext : 0x000102030405060708090a0b0c0d0e0f
- 101112131415161718191a1b1c1d1e1f
- Ciphertext: 0xd296cd94c2cccf8a3a863028b5e1dc0a
- 7586602d253cfff91b8266bea6d61ab1
- */
- uint8_t in_data[TEST2_SIZE];
- uint8_t ct[TEST2_SIZE];
- uint8_t enc_data[TEST2_SIZE];
- uint8_t dec_data[TEST2_SIZE];
- bigint *in_bi = bi_str_import(bi_ctx,
- "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
- bigint *key_bi = bi_str_import(
- bi_ctx, "C286696D887C9AA0611BBB3E2025A45A");
- bigint *iv_bi = bi_str_import(
- bi_ctx, "562E17996D093D28DDB3BA695A2E6F58");
- bigint *ct_bi = bi_str_import(bi_ctx,
- "D296CD94C2CCCF8A3A863028B5E1DC0A7586602D253CFFF91B8266BEA6D61AB1");
- bi_export(bi_ctx, in_bi, in_data, TEST2_SIZE);
- bi_export(bi_ctx, key_bi, key, TEST1_SIZE);
- bi_export(bi_ctx, iv_bi, iv, TEST1_SIZE);
- bi_export(bi_ctx, ct_bi, ct, TEST2_SIZE);
- AES_set_key(&aes_key, key, iv, AES_MODE_128);
- AES_cbc_encrypt(&aes_key, (const uint8_t *)in_data,
- enc_data, sizeof(enc_data));
- if (memcmp(enc_data, ct, sizeof(ct)))
- {
- printf("Error: ENCRYPT #2 failed\n");
- goto end;
- }
- AES_set_key(&aes_key, key, iv, AES_MODE_128);
- AES_convert_key(&aes_key);
- AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data));
- if (memcmp(dec_data, in_data, sizeof(dec_data)))
- {
- printf("Error: DECRYPT #2 failed\n");
- goto end;
- }
- }
- res = 0;
- printf("All AES tests passed\n");
- end:
- return res;
- }
- /**************************************************************************
- * RC4 tests
- *
- * ARC4 tests vectors from OpenSSL (crypto/rc4/rc4test.c)
- **************************************************************************/
- static const uint8_t keys[7][30]=
- {
- {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
- {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
- {8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {4,0xef,0x01,0x23,0x45},
- {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
- {4,0xef,0x01,0x23,0x45},
- };
- static const uint8_t data_len[7]={8,8,8,20,28,10};
- static uint8_t data[7][30]=
- {
- {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xff},
- {0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
- 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
- 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
- 0x12,0x34,0x56,0x78,0xff},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
- {0},
- };
- static const uint8_t output[7][30]=
- {
- {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
- {0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
- {0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
- {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,
- 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba,
- 0x36,0xb6,0x78,0x58,0x00},
- {0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89,
- 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c,
- 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87,
- 0x40,0x01,0x1e,0xcf,0x00},
- {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00},
- {0},
- };
- static int RC4_test(BI_CTX *bi_ctx)
- {
- int i, res = 1;
- RC4_CTX s;
- for (i = 0; i < 6; i++)
- {
- RC4_setup(&s, &keys[i][1], keys[i][0]);
- RC4_crypt(&s, data[i], data[i], data_len[i]);
- if (memcmp(data[i], output[i], data_len[i]))
- {
- printf("Error: RC4 CRYPT #%d failed\n", i);
- goto end;
- }
- }
- res = 0;
- printf("All RC4 tests passed\n");
- end:
- return res;
- }
- /**************************************************************************
- * SHA1 tests
- *
- * Run through a couple of the RFC3174 tests to verify that SHA1 is correct.
- **************************************************************************/
- static int SHA1_test(BI_CTX *bi_ctx)
- {
- SHA1_CTX ctx;
- uint8_t ct[SHA1_SIZE];
- uint8_t digest[SHA1_SIZE];
- int res = 1;
- {
- const char *in_str = "abc";
- bigint *ct_bi = bi_str_import(bi_ctx,
- "A9993E364706816ABA3E25717850C26C9CD0D89D");
- bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE);
- SHA1_Init(&ctx);
- SHA1_Update(&ctx, (const uint8_t *)in_str, strlen(in_str));
- SHA1_Final(digest, &ctx);
- if (memcmp(digest, ct, sizeof(ct)))
- {
- printf("Error: SHA1 #1 failed\n");
- goto end;
- }
- }
- {
- const char *in_str =
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
- bigint *ct_bi = bi_str_import(bi_ctx,
- "84983E441C3BD26EBAAE4AA1F95129E5E54670F1");
- bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE);
- SHA1_Init(&ctx);
- SHA1_Update(&ctx, (const uint8_t *)in_str, strlen(in_str));
- SHA1_Final(digest, &ctx);
- if (memcmp(digest, ct, sizeof(ct)))
- {
- printf("Error: SHA1 #2 failed\n");
- goto end;
- }
- }
- res = 0;
- printf("All SHA1 tests passed\n");
- end:
- return res;
- }
- /**************************************************************************
- * MD5 tests
- *
- * Run through a couple of the RFC1321 tests to verify that MD5 is correct.
- **************************************************************************/
- static int MD5_test(BI_CTX *bi_ctx)
- {
- MD5_CTX ctx;
- uint8_t ct[MD5_SIZE];
- uint8_t digest[MD5_SIZE];
- int res = 1;
- {
- const char *in_str = "abc";
- bigint *ct_bi = bi_str_import(bi_ctx,
- "900150983CD24FB0D6963F7D28E17F72");
- bi_export(bi_ctx, ct_bi, ct, MD5_SIZE);
- MD5_Init(&ctx);
- MD5_Update(&ctx, (const uint8_t *)in_str, strlen(in_str));
- MD5_Final(digest, &ctx);
- if (memcmp(digest, ct, sizeof(ct)))
- {
- printf("Error: MD5 #1 failed\n");
- goto end;
- }
- }
- {
- const char *in_str =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- bigint *ct_bi = bi_str_import(
- bi_ctx, "D174AB98D277D9F5A5611C2C9F419D9F");
- bi_export(bi_ctx, ct_bi, ct, MD5_SIZE);
- MD5_Init(&ctx);
- MD5_Update(&ctx, (const uint8_t *)in_str, strlen(in_str));
- MD5_Final(digest, &ctx);
- if (memcmp(digest, ct, sizeof(ct)))
- {
- printf("Error: MD5 #2 failed\n");
- goto end;
- }
- }
- res = 0;
- printf("All MD5 tests passed\n");
- end:
- return res;
- }
- /**************************************************************************
- * HMAC tests
- *
- * Run through a couple of the RFC2202 tests to verify that HMAC is correct.
- **************************************************************************/
- static int HMAC_test(BI_CTX *bi_ctx)
- {
- uint8_t key[SHA1_SIZE];
- uint8_t ct[SHA1_SIZE];
- uint8_t dgst[SHA1_SIZE];
- int res = 1;
- const char *key_str;
- const char *data_str = "Hi There";
- bigint *key_bi = bi_str_import(bi_ctx, "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
- bigint *ct_bi = bi_str_import(bi_ctx, "9294727A3638BB1C13F48EF8158BFC9D");
- bi_export(bi_ctx, key_bi, key, MD5_SIZE);
- bi_export(bi_ctx, ct_bi, ct, MD5_SIZE);
- hmac_md5((const uint8_t *)data_str, 8, key, MD5_SIZE, dgst);
- if (memcmp(dgst, ct, MD5_SIZE))
- {
- printf("HMAC MD5 #1 failed\n");
- goto end;
- }
- data_str = "what do ya want for nothing?";
- key_str = "Jefe";
- ct_bi = bi_str_import(bi_ctx, "750C783E6AB0B503EAA86E310A5DB738");
- bi_export(bi_ctx, ct_bi, ct, MD5_SIZE);
- hmac_md5((const uint8_t *)data_str, 28, (const uint8_t *)key_str, 4, dgst);
- if (memcmp(dgst, ct, MD5_SIZE))
- {
- printf("HMAC MD5 #2 failed\n");
- goto end;
- }
-
- data_str = "Hi There";
- key_bi = bi_str_import(bi_ctx, "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
- bi_export(bi_ctx, key_bi, key, SHA1_SIZE);
- ct_bi = bi_str_import(bi_ctx, "B617318655057264E28BC0B6FB378C8EF146BE00");
- bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE);
- hmac_sha1((const uint8_t *)data_str, 8,
- (const uint8_t *)key, SHA1_SIZE, dgst);
- if (memcmp(dgst, ct, SHA1_SIZE))
- {
- printf("HMAC SHA1 #1 failed\n");
- goto end;
- }
- data_str = "what do ya want for nothing?";
- key_str = "Jefe";
- ct_bi = bi_str_import(bi_ctx, "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79");
- bi_export(bi_ctx, ct_bi, ct, SHA1_SIZE);
- hmac_sha1((const uint8_t *)data_str, 28, (const uint8_t *)key_str, 5, dgst);
- if (memcmp(dgst, ct, SHA1_SIZE))
- {
- printf("HMAC SHA1 failed\n");
- exit(1);
- }
- res = 0;
- printf("All HMAC tests passed\n");
- end:
- return res;
- }
- /**************************************************************************
- * BIGINT tests
- *
- **************************************************************************/
- static int BIGINT_test(BI_CTX *ctx)
- {
- int res = 1;
- bigint *bi_data, *bi_exp, *bi_res;
- const char *expnt, *plaintext, *mod;
- uint8_t compare[MAX_KEY_BYTE_SIZE];
- /**
- * 512 bit key
- */
- plaintext = /* 64 byte number */
- "01aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee";
- mod = "C30773C8ABE09FCC279EE0E5343370DE"
- "8B2FFDB6059271E3005A7CEEF0D35E0A"
- "1F9915D95E63560836CC2EB2C289270D"
- "BCAE8CAF6F5E907FC2759EE220071E1B";
- expnt = "A1E556CD1738E10DF539E35101334E97"
- "BE8D391C57A5C89A7AD9A2EA2ACA1B3D"
- "F3140F5091CC535CBAA47CEC4159EE1F"
- "B6A3661AFF1AB758426EAB158452A9B9";
- bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
- bi_exp = int_to_bi(ctx, 0x10001);
- bi_set_mod(ctx, bi_str_import(ctx, mod), 0);
- bi_res = bi_mod_power(ctx, bi_data, bi_exp);
- bi_data = bi_res; /* resuse again - see if we get the original */
- bi_exp = bi_str_import(ctx, expnt);
- bi_res = bi_mod_power(ctx, bi_data, bi_exp);
- bi_free_mod(ctx, 0);
- bi_export(ctx, bi_res, compare, 64);
- if (memcmp(plaintext, compare, 64) != 0)
- goto end;
- printf("All BIGINT tests passed\n");
- res = 0;
- end:
- return res;
- }
- /**************************************************************************
- * RSA tests
- *
- * Use the results from openssl to verify PKCS1 etc
- **************************************************************************/
- static int RSA_test(void)
- {
- int res = 1;
- const char *plaintext = /* 128 byte hex number */
- "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee2"
- "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeee2\012";
- uint8_t enc_data[128], dec_data[128];
- RSA_CTX *rsa_ctx = NULL;
- BI_CTX *bi_ctx;
- bigint *plaintext_bi;
- bigint *enc_data_bi, *dec_data_bi;
- uint8_t enc_data2[128], dec_data2[128];
- int size;
- int len;
- uint8_t *buf;
- /* extract the private key elements */
- len = get_file("../ssl/test/axTLS.key_1024", &buf);
- if (asn1_get_private_key(buf, len, &rsa_ctx) < 0)
- {
- goto end;
- }
- free(buf);
- bi_ctx = rsa_ctx->bi_ctx;
- plaintext_bi = bi_import(bi_ctx,
- (const uint8_t *)plaintext, strlen(plaintext));
- /* basic rsa encrypt */
- enc_data_bi = RSA_public(rsa_ctx, plaintext_bi);
- bi_export(bi_ctx, bi_copy(enc_data_bi), enc_data, sizeof(enc_data));
- /* basic rsa decrypt */
- dec_data_bi = RSA_private(rsa_ctx, enc_data_bi);
- bi_export(bi_ctx, dec_data_bi, dec_data, sizeof(dec_data));
- if (memcmp(dec_data, plaintext, strlen(plaintext)))
- {
- printf("Error: DECRYPT #1 failed\n");
- goto end;
- }
- RSA_encrypt(rsa_ctx, (const uint8_t *)"abc", 3, enc_data2, 0);
- size = RSA_decrypt(rsa_ctx, enc_data2, dec_data2, 1);
- if (memcmp("abc", dec_data2, 3))
- {
- printf("Error: ENCRYPT/DECRYPT #2 failed\n");
- goto end;
- }
- RSA_free(rsa_ctx);
- res = 0;
- printf("All RSA tests passed\n");
- end:
- return res;
- }
- /**************************************************************************
- * Cert Testing
- *
- **************************************************************************/
- static int cert_tests(void)
- {
- int res = -1, len;
- X509_CTX *x509_ctx;
- SSL_CTX *ssl_ctx;
- uint8_t *buf;
- /* check a bunch of 3rd party certificates */
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/microsoft.x509_ca", &buf);
- if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0)
- {
- printf("Cert #1\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/thawte.x509_ca", &buf);
- if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0)
- {
- printf("Cert #2\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/deutsche_telecom.x509_ca", &buf);
- if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0)
- {
- printf("Cert #3\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/equifax.x509_ca", &buf);
- if ((res = add_cert_auth(ssl_ctx, buf, len)) < 0)
- {
- printf("Cert #4\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/gnutls.cer", &buf);
- if ((res = add_cert(ssl_ctx, buf, len)) < 0)
- {
- printf("Cert #5\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/socgen.cer", &buf);
- if ((res = add_cert(ssl_ctx, buf, len)) < 0)
- {
- printf("Cert #6\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- len = get_file("../ssl/test/verisign.x509_ca", &buf);
- if ((res = add_cert_auth(ssl_ctx, buf, len)) <0)
- {
- printf("Cert #7\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- free(buf);
- if (get_file("../ssl/test/verisign.x509_my_cert", &buf) < 0 ||
- x509_new(buf, &len, &x509_ctx))
- {
- printf("Cert #8\n");
- ssl_display_error(res);
- goto bad_cert;
- }
- x509_free(x509_ctx);
- free(buf);
- ssl_ctx = ssl_ctx_new(0, 0);
- if ((res = ssl_obj_load(ssl_ctx,
- SSL_OBJ_X509_CERT, "../ssl/test/ms_iis.cer", NULL)) != SSL_OK)
- {
- ssl_display_error(res);
- goto bad_cert;
- }
- ssl_ctx_free(ssl_ctx);
- res = 0; /* all ok */
- printf("All Certificate tests passed\n");
- bad_cert:
- if (res)
- printf("Error: A certificate test failed\n");
- return res;
- }
- /**
- * init a server socket.
- */
- static int server_socket_init(int *port)
- {
- struct sockaddr_in serv_addr;
- int server_fd;
- char yes = 1;
- /* Create socket for incoming connections */
- if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- return -1;
- }
-
- setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
- go_again:
- /* Construct local address structure */
- memset(&serv_addr, 0, sizeof(serv_addr)); /* Zero out structure */
- serv_addr.sin_family = AF_INET; /* Internet address family */
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
- serv_addr.sin_port = htons(*port); /* Local port */
- /* Bind to the local address */
- if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
- {
- (*port)++;
- goto go_again;
- }
- /* Mark the socket so it will listen for incoming connections */
- if (listen(server_fd, 3000) < 0)
- {
- return -1;
- }
- return server_fd;
- }
- /**
- * init a client socket.
- */
- static int client_socket_init(uint16_t port)
- {
- struct sockaddr_in address;
- int client_fd;
- address.sin_family = AF_INET;
- address.sin_port = htons(port);
- address.sin_addr.s_addr = inet_addr("127.0.0.1");
- client_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (connect(client_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
- {
- perror("socket");
- SOCKET_CLOSE(client_fd);
- client_fd = -1;
- }
- return client_fd;
- }
- /**************************************************************************
- * SSL Server Testing
- *
- **************************************************************************/
- typedef struct
- {
- /* not used as yet */
- int dummy;
- } SVR_CTX;
- typedef struct
- {
- const char *testname;
- const char *openssl_option;
- } client_t;
- static void do_client(client_t *clnt)
- {
- char openssl_buf[2048];
- /* make sure the main thread goes first */
- sleep(0);
- /* show the session ids in the reconnect test */
- if (strcmp(clnt->testname, "Session Reuse") == 0)
- {
- sprintf(openssl_buf, "echo \"hello client\" | openssl s_client "
- "-connect localhost:%d %s 2>&1 | grep \"Session-ID:\"",
- g_port, clnt->openssl_option);
- }
- else
- {
- sprintf(openssl_buf, "echo \"hello client\" | openssl s_client "
- #ifdef WIN32
- "-connect localhost:%d -quiet %s",
- #else
- "-connect localhost:%d -quiet %s > /dev/null 2>&1",
- #endif
- g_port, clnt->openssl_option);
- }
- system(openssl_buf);
- }
- static int SSL_server_test(
- const char *testname,
- const char *openssl_option,
- const char *device_cert,
- const char *product_cert,
- const char *private_key,
- const char *ca_cert,
- const char *password,
- int axtls_option)
- {
- int server_fd, ret = 0;
- SSL_CTX *ssl_ctx = NULL;
- struct sockaddr_in client_addr;
- uint8_t *read_buf;
- socklen_t clnt_len = sizeof(client_addr);
- client_t client_data;
- #ifndef WIN32
- pthread_t thread;
- #endif
- g_port++;
- client_data.testname = testname;
- client_data.openssl_option = openssl_option;
- if ((server_fd = server_socket_init(&g_port)) < 0)
- goto error;
- if (private_key)
- {
- axtls_option |= SSL_NO_DEFAULT_KEY;
- }
- if ((ssl_ctx = ssl_ctx_new(axtls_option, SSL_DEFAULT_SVR_SESS)) == NULL)
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto error;
- }
- if (private_key)
- {
- int obj_type = SSL_OBJ_RSA_KEY;
- if (strstr(private_key, ".p8"))
- obj_type = SSL_OBJ_PKCS8;
- else if (strstr(private_key, ".p12"))
- obj_type = SSL_OBJ_PKCS12;
- if (ssl_obj_load(ssl_ctx, obj_type, private_key, password))
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto error;
- }
- }
- if (device_cert) /* test chaining */
- {
- if ((ret = ssl_obj_load(ssl_ctx,
- SSL_OBJ_X509_CERT, device_cert, NULL)) != SSL_OK)
- goto error;
- }
- if (product_cert) /* test chaining */
- {
- if ((ret = ssl_obj_load(ssl_ctx,
- SSL_OBJ_X509_CERT, product_cert, NULL)) != SSL_OK)
- goto error;
- }
- if (ca_cert) /* test adding certificate authorities */
- {
- if ((ret = ssl_obj_load(ssl_ctx,
- SSL_OBJ_X509_CACERT, ca_cert, NULL)) != SSL_OK)
- goto error;
- }
- #ifndef WIN32
- pthread_create(&thread, NULL,
- (void *(*)(void *))do_client, (void *)&client_data);
- pthread_detach(thread);
- #else
- CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_client,
- (LPVOID)&client_data, 0, NULL);
- #endif
- for (;;)
- {
- int client_fd, size = 0;
- SSL *ssl;
- /* Wait for a client to connect */
- if ((client_fd = accept(server_fd,
- (struct sockaddr *)&client_addr, &clnt_len)) < 0)
- {
- ret = SSL_ERROR_SOCK_SETUP_FAILURE;
- goto error;
- }
-
- /* we are ready to go */
- ssl = ssl_server_new(ssl_ctx, client_fd);
- while ((size = ssl_read(ssl, &read_buf)) == SSL_OK);
- SOCKET_CLOSE(client_fd);
-
- if (size < SSL_OK) /* got some alert or something nasty */
- {
- ret = size;
- if (ret == SSL_ERROR_CONN_LOST)
- {
- ret = SSL_OK;
- continue;
- }
- break; /* we've got a problem */
- }
- else /* looks more promising */
- {
- if (strstr("hello client", (char *)read_buf) == NULL)
- {
- printf("SSL server test \"%s\" passed\n", testname);
- TTY_FLUSH();
- ret = 0;
- break;
- }
- }
- ssl_free(ssl);
- }
- SOCKET_CLOSE(server_fd);
- error:
- ssl_ctx_free(ssl_ctx);
- return ret;
- }
- int SSL_server_tests(void)
- {
- int ret = -1;
- struct stat stat_buf;
- SVR_CTX svr_test_ctx;
- memset(&svr_test_ctx, 0, sizeof(SVR_CTX));
- printf("### starting server tests\n"); TTY_FLUSH();
- /* Go through the algorithms */
- /*
- * TLS1 client hello
- */
- if ((ret = SSL_server_test("TLSv1", "-cipher RC4-SHA -tls1",
- NULL, NULL, NULL, NULL, NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * AES128-SHA
- */
- if ((ret = SSL_server_test("AES256-SHA", "-cipher AES128-SHA",
- DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
- DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * AES256-SHA
- */
- if ((ret = SSL_server_test("AES256-SHA", "-cipher AES128-SHA",
- DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
- DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * RC4-SHA
- */
- if ((ret = SSL_server_test("RC4-SHA", "-cipher RC4-SHA",
- DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
- DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * RC4-MD5
- */
- if ((ret = SSL_server_test("RC4-MD5", "-cipher RC4-MD5",
- DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
- DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * Session Reuse
- * all the session id's should match for session resumption.
- */
- if ((ret = SSL_server_test("Session Reuse",
- "-cipher RC4-SHA -reconnect",
- DEFAULT_CERT, NULL, DEFAULT_KEY, NULL, NULL,
- DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * 512 bit RSA key
- */
- if ((ret = SSL_server_test("512 bit key", "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_512.cer", NULL,
- "../ssl/test/axTLS.key_512",
- NULL, NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * 1024 bit RSA key (check certificate chaining)
- */
- if ((ret = SSL_server_test("1024 bit key",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_device.cer",
- "../ssl/test/axTLS.x509_512.cer",
- "../ssl/test/axTLS.device_key",
- NULL, NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * 2048 bit RSA key
- */
- if ((ret = SSL_server_test("2048 bit key",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_2048.cer", NULL,
- "../ssl/test/axTLS.key_2048",
- NULL, NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * 4096 bit RSA key
- */
- if ((ret = SSL_server_test("4096 bit key",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_4096.cer", NULL,
- "../ssl/test/axTLS.key_4096",
- NULL, NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * Client Verification
- */
- if ((ret = SSL_server_test("Client Verification",
- "-cipher RC4-SHA -tls1 "
- "-cert ../ssl/test/axTLS.x509_2048.pem "
- "-key ../ssl/test/axTLS.key_2048.pem ",
- NULL, NULL, NULL,
- "../ssl/test/axTLS.ca_x509.cer", NULL,
- DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)))
- goto cleanup;
- /* this test should fail */
- if (stat("../ssl/test/axTLS.x509_bad_before.pem", &stat_buf) >= 0)
- {
- if ((ret = SSL_server_test("Error: Bad Before Cert",
- "-cipher RC4-SHA -tls1 "
- "-cert ../ssl/test/axTLS.x509_bad_before.pem "
- "-key ../ssl/test/axTLS.key_512.pem ",
- NULL, NULL, NULL,
- "../ssl/test/axTLS.ca_x509.cer", NULL,
- DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) !=
- SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID))
- goto cleanup;
- printf("SSL server test \"%s\" passed\n", "Bad Before Cert");
- TTY_FLUSH();
- ret = 0; /* is ok */
- }
- /* this test should fail */
- if ((ret = SSL_server_test("Error: Bad After Cert",
- "-cipher RC4-SHA -tls1 "
- "-cert ../ssl/test/axTLS.x509_bad_after.pem "
- "-key ../ssl/test/axTLS.key_512.pem ",
- NULL, NULL, NULL,
- "../ssl/test/axTLS.ca_x509.cer", NULL,
- DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) !=
- SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED))
- goto cleanup;
- printf("SSL server test \"%s\" passed\n", "Bad After Cert");
- TTY_FLUSH();
- /*
- * No trusted cert
- */
- if ((ret = SSL_server_test("Error: No trusted certificate",
- "-cipher RC4-SHA -tls1 "
- "-cert ../ssl/test/axTLS.x509_512.pem "
- "-key ../ssl/test/axTLS.key_512.pem ",
- NULL, NULL, NULL,
- NULL, NULL,
- DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) !=
- SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT))
- goto cleanup;
- printf("SSL server test \"%s\" passed\n", "No trusted certificate");
- TTY_FLUSH();
- /*
- * Self-signed (from the server)
- */
- if ((ret = SSL_server_test("Error: Self-signed certificate (from server)",
- "-cipher RC4-SHA -tls1 "
- "-cert ../ssl/test/axTLS.x509_512.pem "
- "-key ../ssl/test/axTLS.key_512.pem "
- "-CAfile ../ssl/test/axTLS.ca_x509.pem ",
- NULL, NULL, NULL,
- NULL, NULL,
- DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) !=
- SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED))
- goto cleanup;
- printf("SSL server test \"%s\" passed\n",
- "Self-signed certificate (from server)");
- TTY_FLUSH();
- /*
- * Self-signed (from the client)
- */
- if ((ret = SSL_server_test("Self-signed certificate (from client)",
- "-cipher RC4-SHA -tls1 "
- "-cert ../ssl/test/axTLS.x509_512.pem "
- "-key ../ssl/test/axTLS.key_512.pem ",
- NULL, NULL, NULL,
- "../ssl/test/axTLS.ca_x509.cer",
- NULL,
- DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)))
- goto cleanup;
- /*
- * Key in PEM format
- */
- if ((ret = SSL_server_test("Key in PEM format",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_512.cer", NULL,
- "../ssl/test/axTLS.key_512.pem", NULL,
- NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * Cert in PEM format
- */
- if ((ret = SSL_server_test("Cert in PEM format",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_512.pem", NULL,
- "../ssl/test/axTLS.key_512.pem", NULL,
- NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * Cert chain in PEM format
- */
- if ((ret = SSL_server_test("Cert chain in PEM format",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_device.pem",
- NULL, "../ssl/test/axTLS.device_key.pem",
- "../ssl/test/axTLS.ca_x509.pem", NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * AES128 Encrypted key
- */
- if ((ret = SSL_server_test("AES128 encrypted key",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_aes128.pem", NULL,
- "../ssl/test/axTLS.key_aes128.pem",
- NULL, "abcd", DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * AES256 Encrypted key
- */
- if ((ret = SSL_server_test("AES256 encrypted key",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_aes256.pem", NULL,
- "../ssl/test/axTLS.key_aes256.pem",
- NULL, "abcd", DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * AES128 Encrypted invalid key
- */
- if ((ret = SSL_server_test("AES128 encrypted invalid key",
- "-cipher RC4-SHA",
- "../ssl/test/axTLS.x509_aes128.pem", NULL,
- "../ssl/test/axTLS.key_aes128.pem",
- NULL, "xyz", DEFAULT_SVR_OPTION)) != SSL_ERROR_INVALID_KEY)
- goto cleanup;
- printf("SSL server test \"%s\" passed\n", "AES128 encrypted invalid key");
- TTY_FLUSH();
- /*
- * PKCS#8 key (encrypted)
- */
- if ((ret = SSL_server_test("pkcs#8 encrypted", "-cipher RC4-SHA",
- DEFAULT_CERT, NULL, "../ssl/test/axTLS.encrypted.p8",
- NULL, "abcd", DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * PKCS#8 key (unencrypted)
- */
- if ((ret = SSL_server_test("pkcs#8 unencrypted", "-cipher RC4-SHA",
- DEFAULT_CERT, NULL, "../ssl/test/axTLS.unencrypted.p8",
- NULL, NULL, DEFAULT_SVR_OPTION)))
- goto cleanup;
- /*
- * PKCS#12 key/certificate
- */
- if ((ret = SSL_server_test("pkcs#12 with CA", "-cipher RC4-SHA",
- NULL, NULL, "../ssl/test/axTLS.withCA.p12",
- NULL, "abcd", DEFAULT_SVR_OPTION)))
- goto cleanup;
- if ((ret = SSL_server_test("pkcs#12 no CA", "-cipher RC4-SHA",
- DEFAULT_CERT, NULL, "../ssl/test/axTLS.withoutCA.p12",
- NULL, "abcd", DEFAULT_SVR_OPTION)))
- goto cleanup;
- ret = 0;
- cleanup:
- if (ret)
- {
- printf("Error: A server test failed\n");
- ssl_display_error(ret);
- exit(1);
- }
- else
- {
- printf("All server tests passed\n"); TTY_FLUSH();
- }
- return ret;
- }
- /**************************************************************************
- * SSL Client Testing
- *
- **************************************************************************/
- typedef struct
- {
- uint8_t session_id[SSL_SESSION_ID_SIZE];
- #ifndef WIN32
- pthread_t server_thread;
- #endif
- int start_server;
- int stop_server;
- int do_reneg;
- } CLNT_SESSION_RESUME_CTX;
- typedef struct
- {
- const char *testname;
- const char *openssl_option;
- } server_t;
- static void do_server(server_t *svr)
- {
- char openssl_buf[2048];
- #ifndef WIN32
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
- #endif
- sprintf(openssl_buf, "openssl s_server -tls1 "
- "-accept %d -quiet %s ", g_port, svr->openssl_option);
- system(openssl_buf);
- }
- static int SSL_client_test(
- const char *test,
- SSL_CTX **ssl_ctx,
- const char *openssl_option,
- CLNT_SESSION_RESUME_CTX *sess_resume,
- uint32_t client_options,
- const char *private_key,
- const char *password,
- const char *cert)
- {
- server_t server_data;
- SSL *ssl = NULL;
- int client_fd = -1;
- uint8_t *session_id = NULL;
- int ret = 1;
- #ifndef WIN32
- pthread_t thread;
- #endif
- if (sess_resume == NULL || sess_resume->start_server)
- {
- g_port++;
- server_data.openssl_option = openssl_option;
- #ifndef WIN32
- pthread_create(&thread, NULL,
- (void *(*)(void *))do_server, (void *)&server_data);
- pthread_detach(thread);
- #else
- CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_server,
- (LPVOID)&server_data, 0, NULL);
- #endif
- }
-
- usleep(200000); /* allow server to start */
- if (*ssl_ctx == NULL)
- {
- if (private_key)
- {
- client_options |= SSL_NO_DEFAULT_KEY;
- }
- if ((*ssl_ctx = ssl_ctx_new(
- client_options, SSL_DEFAULT_CLNT_SESS)) == NULL)
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto client_test_exit;
- }
- if (private_key)
- {
- int obj_type = SSL_OBJ_RSA_KEY;
- if (strstr(private_key, ".p8"))
- obj_type = SSL_OBJ_PKCS8;
- else if (strstr(private_key, ".p12"))
- obj_type = SSL_OBJ_PKCS12;
- if (ssl_obj_load(*ssl_ctx, obj_type, private_key, password))
- {
- ret = SSL_ERROR_INVALID_KEY;
- goto client_test_exit;
- }
- }
- if (cert)
- {
- if ((ret = ssl_obj_load(*ssl_ctx,
- SSL_OBJ_X509_CERT, cert, NULL)) != SSL_OK)
- {
- printf("could not add cert %s (%d)\n", cert, ret);
- TTY_FLUSH();
- goto client_test_exit;
- }
- }
- if (ssl_obj_load(*ssl_ctx, SSL_OBJ_X509_CACERT,
- "../ssl/test/axTLS.ca_x509.cer", NULL))
- {
- printf("could not add cert auth\n"); TTY_FLUSH();
- goto client_test_exit;
- }
- }
-
- if (sess_resume && !sess_resume->start_server)
- {
- session_id = sess_resume->session_id;
- }
- if ((client_fd = client_socket_init(g_port)) < 0)
- {
- printf("could not start socket on %d\n", g_port); TTY_FLUSH();
- goto client_test_exit;
- }
- ssl = ssl_client_new(*ssl_ctx, client_fd, session_id, sizeof(session_id));
- /* check the return status */
- if ((ret = ssl_handshake_status(ssl)))
- goto client_test_exit;
- /* renegotiate client */
- if (sess_resume && sess_resume->do_reneg)
- {
- if (ssl_renegotiate(ssl) < 0)
- goto client_test_exit;
- }
- if (sess_resume)
- {
- memcpy(sess_resume->session_id,
- ssl_get_session_id(ssl), SSL_SESSION_ID_SIZE);
- }
- if (IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER) &&
- (ret = ssl_verify_cert(ssl)))
- {
- goto client_test_exit;
- }
- ssl_write(ssl, (uint8_t *)"hello world\n", 13);
- if (sess_resume)
- {
- const uint8_t *sess_id = ssl_get_session_id(ssl);
- int i;
- printf(" Session-ID: ");
- for (i = 0; i < SSL_SESSION_ID_SIZE; i++)
- {
- printf("%02X", sess_id[i]);
- }
- printf("\n");
- TTY_FLUSH();
- }
- ret = 0;
- client_test_exit:
- ssl_free(ssl);
- SOCKET_CLOSE(client_fd);
- usleep(200000); /* allow openssl to say something */
- if (sess_resume)
- {
- if (sess_resume->stop_server)
- {
- ssl_ctx_free(*ssl_ctx);
- *ssl_ctx = NULL;
- #ifndef WIN32
- pthread_cancel(sess_resume->server_thread);
- #endif
- }
- else if (sess_resume->start_server)
- {
- #ifndef WIN32
- sess_resume->server_thread = thread;
- #endif
- }
- }
- else
- {
- ssl_ctx_free(*ssl_ctx);
- *ssl_ctx = NULL;
- #ifndef WIN32
- pthread_cancel(thread);
- #endif
- }
- if (ret == 0)
- {
- printf("SSL client test \"%s\" passed\n", test);
- TTY_FLUSH();
- }
- return ret;
- }
- int SSL_client_tests(void)
- {
- int ret = -1;
- SSL_CTX *ssl_ctx = NULL;
- CLNT_SESSION_RESUME_CTX sess_resume;
- memset(&sess_resume, 0, sizeof(CLNT_SESSION_RESUME_CTX));
- sess_resume.start_server = 1;
- printf("### starting client tests\n");
-
- if ((ret = SSL_client_test("512 bit key",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_512.pem "
- "-key ../ssl/test/axTLS.key_512.pem", &sess_resume,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- /* all the session id's should match for session resumption */
- sess_resume.start_server = 0;
- if ((ret = SSL_client_test("Client session resumption #1",
- &ssl_ctx, NULL, &sess_resume,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- sess_resume.do_reneg = 1;
- if ((ret = SSL_client_test("Client renegotiation",
- &ssl_ctx, NULL, &sess_resume,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- sess_resume.do_reneg = 0;
- sess_resume.stop_server = 1;
- if ((ret = SSL_client_test("Client session resumption #2",
- &ssl_ctx, NULL, &sess_resume,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- if ((ret = SSL_client_test("1024 bit key",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_1024.pem "
- "-key ../ssl/test/axTLS.key_1024.pem", NULL,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- if ((ret = SSL_client_test("2048 bit key",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_2048.pem "
- "-key ../ssl/test/axTLS.key_2048.pem", NULL,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- if ((ret = SSL_client_test("4096 bit key",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_4096.pem "
- "-key ../ssl/test/axTLS.key_4096.pem", NULL,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- if ((ret = SSL_client_test("Server cert chaining",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_device.pem "
- "-key ../ssl/test/axTLS.device_key.pem "
- "-CAfile ../ssl/test/axTLS.x509_512.pem ", NULL,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)))
- goto cleanup;
- /* Check the server can verify the client */
- if ((ret = SSL_client_test("Client peer authentication",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_2048.pem "
- "-key ../ssl/test/axTLS.key_2048.pem "
- "-CAfile ../ssl/test/axTLS.ca_x509.pem "
- "-verify 1 ", NULL, DEFAULT_CLNT_OPTION,
- "../ssl/test/axTLS.key_1024", NULL,
- "../ssl/test/axTLS.x509_1024.cer")))
- goto cleanup;
- /* Should get an "ERROR" from openssl (as the handshake fails as soon as
- * the certificate verification fails) */
- if ((ret = SSL_client_test("Error: Expired cert (verify now)",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_bad_after.pem "
- "-key ../ssl/test/axTLS.key_512.pem", NULL,
- DEFAULT_CLNT_OPTION, NULL, NULL, NULL)) !=
- SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED))
- {
- printf("*** Error: %d\n", ret);
- goto cleanup;
- }
- printf("SSL client test \"Expired cert (verify now)\" passed\n");
- /* There is no "ERROR" from openssl */
- if ((ret = SSL_client_test("Error: Expired cert (verify later)",
- &ssl_ctx,
- "-cert ../ssl/test/axTLS.x509_bad_after.pem "
- "-key ../ssl/test/axTLS.key_512.pem", NULL,
- DEFAULT_CLNT_OPTION|SSL_SERVER_VERIFY_LATER, NULL,
- NULL, NULL)) != SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED))
- {
- printf("*** Error: %d\n", ret);
- goto cleanup;
- }
- printf("SSL client test \"Expired cert (verify later)\" passed\n");
- ret = 0;
- cleanup:
- if (ret)
- {
- ssl_display_error(ret);
- printf("Error: A client test failed\n");
- exit(1);
- }
- else
- {
- printf("All client tests passed\n"); TTY_FLUSH();
- }
- return ret;
- }
- /**************************************************************************
- * SSL Basic Testing (test a big packet handshake)
- *
- **************************************************************************/
- static uint8_t basic_buf[256*1024];
- static void do_basic(void)
- {
- int client_fd;
- SSL *ssl_clnt;
- SSL_CTX *ssl_clnt_ctx = ssl_ctx_new(
- DEFAULT_CLNT_OPTION, SSL_DEFAULT_CLNT_SESS);
- usleep(200000); /* allow server to start */
- if ((client_fd = client_socket_init(g_port)) < 0)
- goto error;
- if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT,
- "../ssl/test/axTLS.ca_x509.cer", NULL))
- goto error;
- ssl_clnt = ssl_client_new(ssl_clnt_ctx, client_fd, NULL, 0);
- /* check the return status */
- if (ssl_handshake_status(ssl_clnt) < 0)
- {
- printf("YA YA\n");
- ssl_display_error(ssl_handshake_status(ssl_clnt));
- goto error;
- }
- ssl_write(ssl_clnt, basic_buf, sizeof(basic_buf));
- ssl_free(ssl_clnt);
- error:
- ssl_ctx_free(ssl_clnt_ctx);
- SOCKET_CLOSE(client_fd);
- /* exit this thread */
- }
- static int SSL_basic_test(void)
- {
- int server_fd, client_fd, ret = 0, size = 0, offset = 0;
- SSL_CTX *ssl_svr_ctx = NULL;
- struct sockaddr_in client_addr;
- uint8_t *read_buf;
- socklen_t clnt_len = sizeof(client_addr);
- SSL *ssl_svr;
- #ifndef WIN32
- pthread_t thread;
- #endif
- memset(basic_buf, 0xA5, sizeof(basic_buf)/2);
- memset(&basic_buf[sizeof(basic_buf)/2], 0x5A, sizeof(basic_buf)/2);
- if ((server_fd = server_socket_init(&g_port)) < 0)
- goto error;
- ssl_svr_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS);
- #ifndef WIN32
- pthread_create(&thread, NULL,
- (void *(*)(void *))do_basic, NULL);
- pthread_detach(thread);
- #else
- CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_basic, NULL, 0, NULL);
- #endif
- /* Wait for a client to connect */
- if ((client_fd = accept(server_fd,
- (struct sockaddr *) &client_addr, &clnt_len)) < 0)
- {
- ret = SSL_ERROR_SOCK_SETUP_FAILURE;
- goto error;
- }
-
- /* we are ready to go */
- ssl_svr = ssl_server_new(ssl_svr_ctx, client_fd);
-
- do
- {
- while ((size = ssl_read(ssl_svr, &read_buf)) == SSL_OK);
- if (size < SSL_OK) /* got some alert or something nasty */
- {
- printf("Server ");
- ssl_display_error(size);
- ret = size;
- break;
- }
- else /* looks more promising */
- {
- if (memcmp(read_buf, &basic_buf[offset], size) != 0)
- {
- ret = SSL_NOT_OK;
- break;
- }
- }
- offset += size;
- } while (offset < sizeof(basic_buf));
- printf(ret == SSL_OK && offset == sizeof(basic_buf) ?
- "SSL basic test passed\n" :
- "SSL basic test failed\n");
- TTY_FLUSH();
- ssl_free(ssl_svr);
- SOCKET_CLOSE(server_fd);
- SOCKET_CLOSE(client_fd);
- error:
- ssl_ctx_free(ssl_svr_ctx);
- return ret;
- }
- #if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING)
- /**************************************************************************
- * Multi-Threading Tests
- *
- **************************************************************************/
- #define NUM_THREADS 100
- typedef struct
- {
- SSL_CTX *ssl_clnt_ctx;
- int port;
- int thread_id;
- } multi_t;
- void do_multi_clnt(multi_t *multi_data)
- {
- int res = 1, client_fd, i;
- SSL *ssl = NULL;
- char tmp[5];
- if ((client_fd = client_socket_init(multi_data->port)) < 0)
- goto client_test_exit;
- sleep(1);
- ssl = ssl_client_new(multi_data->ssl_clnt_ctx, client_fd, NULL, 0);
- if ((res = ssl_handshake_status(ssl)))
- {
- printf("Client ");
- ssl_display_error(res);
- goto client_test_exit;
- }
- sprintf(tmp, "%d\n", multi_data->thread_id);
- for (i = 0; i < 10; i++)
- ssl_write(ssl, (uint8_t *)tmp, strlen(tmp)+1);
- client_test_exit:
- ssl_free(ssl);
- SOCKET_CLOSE(client_fd);
- free(multi_data);
- }
- void do_multi_svr(SSL *ssl)
- {
- uint8_t *read_buf;
- int *res_ptr = malloc(sizeof(int));
- int res;
- for (;;)
- {
- res = ssl_read(ssl, &read_buf);
- /* kill the client */
- if (res != SSL_OK)
- {
- if (res == SSL_ERROR_CONN_LOST)
- {
- SOCKET_CLOSE(ssl->client_fd);
- ssl_free(ssl);
- break;
- }
- else if (res > 0)
- {
- /* do nothing */
- }
- else /* some problem */
- {
- printf("Server ");
- ssl_display_error(res);
- goto error;
- }
- }
- }
- res = SSL_OK;
- error:
- *res_ptr = res;
- pthread_exit(res_ptr);
- }
- int multi_thread_test(void)
- {
- int server_fd = -1;
- SSL_CTX *ssl_server_ctx;
- SSL_CTX *ssl_clnt_ctx;
- pthread_t clnt_threads[NUM_THREADS];
- pthread_t svr_threads[NUM_THREADS];
- int i, res = 0;
- struct sockaddr_in client_addr;
- socklen_t clnt_len = sizeof(client_addr);
- printf("Do multi-threading test (takes a minute)\n");
- ssl_server_ctx = ssl_ctx_new(DEFAULT_SVR_OPTION, SSL_DEFAULT_SVR_SESS);
- ssl_clnt_ctx = ssl_ctx_new(DEFAULT_CLNT_OPTION, SSL_DEFAULT_CLNT_SESS);
- if (ssl_obj_load(ssl_clnt_ctx, SSL_OBJ_X509_CACERT,
- "../ssl/test/axTLS.ca_x509.cer", NULL))
- goto error;
- if ((server_fd = server_socket_init(&g_port)) < 0)
- goto error;
- for (i = 0; i < NUM_THREADS; i++)
- {
- multi_t *multi_data = (multi_t *)malloc(sizeof(multi_t));
- multi_data->ssl_clnt_ctx = ssl_clnt_ctx;
- multi_data->port = g_port;
- multi_data->thread_id = i+1;
- pthread_create(&clnt_threads[i], NULL,
- (void *(*)(void *))do_multi_clnt, (void *)multi_data);
- pthread_detach(clnt_threads[i]);
- }
- for (i = 0; i < NUM_THREADS; i++)
- {
- SSL *ssl_svr;
- int client_fd = accept(server_fd,
- (struct sockaddr *)&client_addr, &clnt_len);
- if (client_fd < 0)
- goto error;
- ssl_svr = ssl_server_new(ssl_server_ctx, client_fd);
- pthread_create(&svr_threads[i], NULL,
- (void *(*)(void *))do_multi_svr, (void *)ssl_svr);
- }
- /* make sure we've run all of the threads */
- for (i = 0; i < NUM_THREADS; i++)
- {
- void *thread_res;
- pthread_join(svr_threads[i], &thread_res);
- if (*((int *)thread_res) != 0)
- res = 1;
- free(thread_res);
- }
- if (res)
- goto error;
- printf("Multi-thread test passed (%d)\n", NUM_THREADS);
- error:
- ssl_ctx_free(ssl_server_ctx);
- ssl_ctx_free(ssl_clnt_ctx);
- SOCKET_CLOSE(server_fd);
- return res;
- }
- #endif /* !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING) */
- /**************************************************************************
- * Header issue
- *
- **************************************************************************/
- static void do_header_issue(void)
- {
- char axtls_buf[2048];
- #ifndef WIN32
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
- #endif
- sprintf(axtls_buf, "./axssl s_client -connect localhost:%d", g_port);
- system(axtls_buf);
- }
- static int header_issue(void)
- {
- FILE *f = fopen("../ssl/test/header_issue.dat", "r");
- int server_fd = -1, client_fd = -1, ret = 1;
- uint8_t buf[2048];
- int size = 0;
- struct sockaddr_in client_addr;
- socklen_t clnt_len = sizeof(client_addr);
- #ifndef WIN32
- pthread_t thread;
- #endif
- if (f == NULL || (server_fd = server_socket_init(&g_port)) < 0)
- goto error;
- #ifndef WIN32
- pthread_create(&thread, NULL,
- (void *(*)(void *))do_header_issue, NULL);
- pthread_detach(thread);
- #else
- CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_header_issue,
- NULL, 0, NULL);
- #endif
- if ((client_fd = accept(server_fd,
- (struct sockaddr *) &client_addr, &clnt_len)) < 0)
- {
- ret = SSL_ERROR_SOCK_SETUP_FAILURE;
- goto error;
- }
- size = fread(buf, 1, sizeof(buf), f);
- SOCKET_WRITE(client_fd, buf, size);
- usleep(200000);
- ret = 0;
- error:
- fclose(f);
- SOCKET_CLOSE(client_fd);
- SOCKET_CLOSE(server_fd);
- TTY_FLUSH();
- system("killall axssl");
- return ret;
- }
- /**************************************************************************
- * main()
- *
- **************************************************************************/
- int main(int argc, char *argv[])
- {
- int ret = 1;
- BI_CTX *bi_ctx;
- int fd;
- #ifdef WIN32
- WSADATA wsaData;
- WORD wVersionRequested = MAKEWORD(2, 2);
- WSAStartup(wVersionRequested, &wsaData);
- fd = _open("test_result.txt", O_WRONLY|O_TEMPORARY|O_CREAT, _S_IWRITE);
- dup2(fd, 2); /* write stderr to this file */
- #else
- fd = open("/dev/null", O_WRONLY); /* write stderr to /dev/null */
- signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */
- dup2(fd, 2);
- #endif
- /* can't do testing in this mode */
- #if defined CONFIG_SSL_GENERATE_X509_CERT
- printf("Error: Must compile with default key/certificates\n");
- exit(1);
- #endif
- bi_ctx = bi_initialize();
- if (AES_test(bi_ctx))
- {
- printf("AES tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- if (RC4_test(bi_ctx))
- {
- printf("RC4 tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- if (MD5_test(bi_ctx))
- {
- printf("MD5 tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- if (SHA1_test(bi_ctx))
- {
- printf("SHA1 tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- if (HMAC_test(bi_ctx))
- {
- printf("HMAC tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- if (BIGINT_test(bi_ctx))
- {
- printf("BigInt tests failed!\n");
- goto cleanup;
- }
- TTY_FLUSH();
- bi_terminate(bi_ctx);
- if (RSA_test())
- {
- printf("RSA tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- if (cert_tests())
- {
- printf("CERT tests failed\n");
- goto cleanup;
- }
- TTY_FLUSH();
- #if !defined(WIN32) && defined(CONFIG_SSL_CTX_MUTEXING)
- if (multi_thread_test())
- goto cleanup;
- #endif
- if (SSL_basic_test())
- goto cleanup;
- system("sh ../ssl/test/killopenssl.sh");
- if (SSL_client_tests())
- goto cleanup;
- system("sh ../ssl/test/killopenssl.sh");
- if (SSL_server_tests())
- goto cleanup;
- system("sh ../ssl/test/killopenssl.sh");
- if (header_issue())
- {
- printf("Header tests failed\n"); TTY_FLUSH();
- goto cleanup;
- }
- ret = 0; /* all ok */
- printf("**** ALL TESTS PASSED ****\n"); TTY_FLUSH();
- cleanup:
- if (ret)
- printf("Error: Some tests failed!\n");
- close(fd);
- return ret;
- }
|