00001
00002
00003 const char *XrdCryptotestCVSID = "$Id: XrdCryptotest.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011
00012 #include <XrdOuc/XrdOucString.hh>
00013
00014 #include <XrdSut/XrdSutAux.hh>
00015 #include <XrdSut/XrdSutBucket.hh>
00016
00017 #include <XrdCrypto/XrdCryptoAux.hh>
00018 #include <XrdCrypto/XrdCryptoFactory.hh>
00019 #include <XrdCrypto/XrdCryptoCipher.hh>
00020 #include <XrdCrypto/XrdCryptoMsgDigest.hh>
00021 #include <XrdCrypto/XrdCryptoRSA.hh>
00022 #include <XrdCrypto/XrdCryptoX509.hh>
00023
00024
00025
00026
00027 #define PRINT(x) {cerr <<x <<endl;}
00028 XrdCryptoFactory *gCryptoFactory = 0;
00029
00030 int main( int argc, char **argv )
00031 {
00032
00033 char cryptomod[64] = "ssl";
00034 char outname[256] = {0};
00035
00036
00037
00038 XrdSutSetTrace(sutTRACE_Debug);
00039 XrdCryptoSetTrace(cryptoTRACE_Debug);
00040
00041
00042
00043 char *p = argv[0];
00044 int k = strlen(argv[0]);
00045 while (k--)
00046 if (p[k] == '/') break;
00047 strcpy(outname,p+k+1);
00048
00049
00050
00051 if(!argv[1]) {
00052 printf("\n Usage: %s <crypto_module_name>\n",outname);
00053 printf(" e.g. %s ssl\n",outname);
00054 printf(" Assuming <crypto_module_name> = ssl\n\n");
00055 } else {
00056 strcpy(cryptomod,argv[1]);
00057 }
00058 bool local = !strcmp(cryptomod,"local");
00059
00060
00061
00062 if (!(gCryptoFactory = XrdCryptoFactory::GetCryptoFactory(cryptomod))) {
00063 PRINT(outname<<": cannot instantiate factory "<<cryptomod);
00064 exit(1);
00065 }
00066 gCryptoFactory->SetTrace(cryptoTRACE_Debug);
00067
00068
00069
00070 PRINT(outname<<": --------------------------------------------------- ");
00071 PRINT(outname<<": Testing MD ... ");
00072 XrdCryptoMsgDigest *MD_1 = gCryptoFactory->MsgDigest("md5");
00073 if (MD_1) {
00074 MD_1->Update("prova",strlen("prova"));
00075 MD_1->Final();
00076
00077 char MD5prova[128] = "189bbbb00c5f1fb7fba9ad9285f193d1";
00078 if (strncmp(MD_1->AsHexString(),MD5prova,MD_1->Length())) {
00079 PRINT(outname<<": MD mismatch: ");
00080 PRINT(outname<<": got: "<<MD_1->AsHexString());
00081 PRINT(outname<<": instead of: "<<MD5prova);
00082 } else {
00083 PRINT(outname<<": MD test OK ");
00084 }
00085 delete MD_1;
00086 } else
00087 PRINT(outname<<": MD object could not be instantiated: ");
00088
00089
00090
00091 PRINT(outname<<": --------------------------------------------------- ");
00092 PRINT(outname<<": Testing symmetric cipher ... ");
00093 XrdCryptoCipher *BF_1 = gCryptoFactory->Cipher("bf-cbc");
00094 if (BF_1) {
00095 PRINT(outname<<": cipher length: "<<BF_1->Length());
00096 PRINT(outname<<": cipher hex: "<<BF_1->AsHexString());
00097 char tm_1[64] = "Test message for cipher - 001";
00098 PRINT(outname<<": Test message: "<<tm_1);
00099 int ltm_1 = strlen(tm_1);
00100 char *tmp_1 = new char[BF_1->EncOutLength(ltm_1)];
00101 if (tmp_1) {
00102 int ltmp = BF_1->Encrypt(tm_1,ltm_1,tmp_1);
00103 char tm_2[128] = {0};
00104 XrdSutToHex(tmp_1,ltmp,&tm_2[0]);
00105 PRINT(outname<<": cipher encrypted (hex):");
00106 PRINT(tm_2);
00107 char *tm_3 = new char[BF_1->DecOutLength(ltmp)];
00108 int lfin = BF_1->Decrypt(tmp_1,ltmp,tm_3);
00109 delete[] tmp_1;
00110 if (tm_3) {
00111 PRINT(outname<<": cipher decrypted: "<<tm_3);
00112 if (strncmp(tm_1,tm_3,ltm_1)) {
00113 PRINT(outname<<": symmetric cipher test failed: ");
00114 PRINT(outname<<": got: "<<tm_3<<" ("<<lfin<<" bytes)");
00115 PRINT(outname<<": instead of: "<<tm_1<<" ("<<ltm_1<<" bytes)");
00116 } else {
00117 PRINT(outname<<": symmetric cipher test OK ");
00118 }
00119 delete[] tm_3;
00120 } else
00121 PRINT(outname<<": cipher decryption failure");
00122 } else
00123 PRINT(outname<<": cipher encryption failure");
00124
00125
00126 PRINT(outname<<": testing bucket encryption");
00127 XrdOucString Astr("TestBucket");
00128 XrdSutBucket Bck0(Astr);
00129 PRINT(outname<<": length of string: "<<Bck0.size);
00130 XrdSutBucket Bck1(Astr);
00131 int lo1 = BF_1->Encrypt(Bck1);
00132 PRINT(outname<<": length of encryption: "<<lo1);
00133 int lo2 = BF_1->Decrypt(Bck1);
00134 PRINT(outname<<": length of decryption: "<<lo2);
00135 if (Bck1 != Bck0) {
00136 PRINT(outname<<": test bucket encryption failed: ");
00137 PRINT(outname<<": got: "<<lo2<<" bytes)");
00138 PRINT(outname<<": instead of: "<<lo1<<" bytes)");
00139 } else {
00140 PRINT(outname<<": test bucket encryption OK");
00141 }
00142
00143 } else
00144 PRINT(outname<<": cipher object could not be instantiated: ");
00145
00146
00147
00148 PRINT(outname<<": --------------------------------------------------- ");
00149 PRINT(outname<<": Testing KDFun ... ");
00150 XrdCryptoKDFun_t KDFun = gCryptoFactory->KDFun();
00151 if (KDFun) {
00152 const char *pass = "pippo";
00153 int plen = strlen(pass);
00154 const char *salt = "$$10000$derek";
00155 int slen = strlen(salt);
00156 char key[128];
00157 char KDFunprova[128] = {0};
00158 bool matching = 0;
00159 if (local) {
00160 int klen = (*KDFun)(pass,plen,salt,slen,key,0);
00161 PRINT(outname<<": key is: "<< key<< " ("<<klen<<" bytes)");
00162 strcpy(KDFunprova,"igcdgcbcebkplgajngjkfjlbcbiponnkifmeafpdmglp"
00163 "lnfkpkjgbmlgbnhehnec");
00164 matching = !strncmp(key,KDFunprova,klen);
00165 } else {
00166 int klen = (*KDFun)(pass,plen,salt,slen,key,0);
00167 char khex[2046] = {0};
00168 int i = 0;
00169 for(; i < klen; i++) sprintf(khex,"%s%02x",khex, 0xFF & key[i]);
00170 PRINT(outname<<": key is: "<< khex<< " ("<<klen<<" bytes)");
00171 strcpy(KDFunprova,"b8d309875d91b050eea1527d91559f6ffa023601da0976de");
00172 matching = !strncmp(khex,KDFunprova,strlen(khex));
00173 }
00174
00175 if (!matching) {
00176 PRINT(outname<<": KDFun mismatch: ");
00177 PRINT(outname<<": key should have been: "<<KDFunprova);
00178 } else {
00179 PRINT(outname<<": KDFun test OK ");
00180 }
00181 } else
00182 PRINT(outname<<": KDFun object could not be instantiated: ");
00183
00184
00185
00186 PRINT(outname<<": --------------------------------------------------- ");
00187 PRINT(outname<<": Testing RSA ... ");
00188 XrdCryptoRSA *TestRSA_1 = gCryptoFactory->RSA(1024);
00189 if (TestRSA_1) {
00190 XrdCryptoRSA *CpyRSA = gCryptoFactory->RSA(*TestRSA_1);
00191 if (CpyRSA)
00192 CpyRSA->Dump();
00193
00194 char RSApubexp[4096];
00195 TestRSA_1->ExportPublic(RSApubexp,4096);
00196 PRINT(outname<<": public export:"<<endl<<RSApubexp);
00197 PRINT(outname<<": The two printouts above should be equal");
00198 PRINT(outname<<": --------------------------------------------------- ");
00199 PRINT(outname<<": outlen : "<<TestRSA_1->GetPublen());
00200 PRINT(outname<<": --------------------------------------------------- ");
00201 char RSApriexp[4096];
00202 TestRSA_1->ExportPrivate(RSApriexp,4096);
00203 PRINT(outname<<": private export:"<<endl<<RSApriexp);
00204 PRINT(outname<<": --------------------------------------------------- ");
00205 PRINT(outname<<": outlen : "<<TestRSA_1->GetPrilen());
00206 PRINT(outname<<": --------------------------------------------------- ");
00207 PRINT(outname<<": --------------------------------------------------- ");
00208 PRINT(outname<<": testing import/export ");
00209 XrdCryptoRSA *TestRSA_2 = gCryptoFactory->RSA(1024);
00210 TestRSA_2->ImportPublic(RSApubexp,strlen(RSApubexp));
00211 TestRSA_2->ImportPrivate(RSApriexp,strlen(RSApriexp));
00212
00213 PRINT(outname<<": --------------------------------------------------- ");
00214 char buf_1[128] = "Here I am ... in test";
00215 int lin = strlen(buf_1);
00216 char buf_2[4096];
00217 PRINT(outname<<": encrypting (public): "<<buf_1<<" ("<<strlen(buf_1)<<" bytes)");
00218 int lout1 = TestRSA_1->EncryptPublic(buf_1,strlen(buf_1),buf_2,512);
00219 char buf_2_hex[4096];
00220 XrdSutToHex(buf_2,lout1,buf_2_hex);
00221 PRINT(outname<<": output has "<<lout1<<" bytes: here is its hex:");
00222 PRINT(outname<<": "<<buf_2_hex);
00223 char buf_3[4096];
00224 PRINT(outname<<": decrypting (private): ("<<lout1<<" bytes)");
00225 int lout2 = TestRSA_2->DecryptPrivate(buf_2,lout1,buf_3,512);
00226 PRINT(outname<<": got: "<<buf_3<<" ("<<lout2<<" bytes)");
00227 if (memcmp(buf_1,buf_3,lin)) {
00228 PRINT(outname<<": RSA public enc / private dec mismatch: ");
00229 PRINT(outname<<": got: "<<buf_3<<" ("<<lout2<<" bytes)");
00230 PRINT(outname<<": instead of: "<<buf_1<<" ("<<strlen(buf_1)<<" bytes)");
00231 } else if (lout2 > lin) {
00232 PRINT(outname<<": RSA public enc / private dec length mismatch: ");
00233 PRINT(outname<<": got: "<<lout2<<" instead of "<<lin);
00234 int j = lin;
00235 for (; j<lout2; j++) printf("%s: %d: 0x%x\n",outname,j,(int)buf_3[j]);
00236 } else {
00237 PRINT(outname<<": RSA public enc / private dec test OK ");
00238 }
00239 PRINT(outname<<": --------------------------------------------------- ");
00240 PRINT(outname<<": encrypting (private): "<<buf_1<<" ("<<strlen(buf_1)<<" bytes)");
00241 lout1 = TestRSA_1->EncryptPrivate(buf_1,strlen(buf_1),buf_2,512);
00242 XrdSutToHex(buf_2,lout1,buf_2_hex);
00243 PRINT(outname<<": output has "<<lout1<<" bytes: here is its hex:");
00244 PRINT(outname<<": "<<buf_2_hex);
00245 PRINT(outname<<": decrypting (public): ("<<lout1<<" bytes)");
00246 lout2 = TestRSA_2->DecryptPublic(buf_2,lout1,buf_3,512);
00247 PRINT(outname<<": got: "<<buf_3<<" ("<<lout2<<" bytes)");
00248 if (memcmp(buf_1,buf_3,lin)) {
00249 PRINT(outname<<": RSA private enc / public dec mismatch: ");
00250 PRINT(outname<<": got: "<<buf_3<<" ("<<lout2<<" bytes)");
00251 PRINT(outname<<": instead of: "<<buf_1<<" ("<<strlen(buf_1)<<" bytes)");
00252 } else if (lout2 > lin) {
00253 PRINT(outname<<": RSA private enc / public dec length mismatch: ");
00254 PRINT(outname<<": got: "<<lout2<<" instead of "<<lin);
00255 int j = lin;
00256 for (; j<lout2; j++) printf("%s: %d: 0x%x\n",outname,j,(int)buf_3[j]);
00257 } else {
00258 PRINT(outname<<": RSA private enc / public dec test OK ");
00259 }
00260
00261
00262 PRINT(outname<<": testing bucket RSA encryption");
00263 XrdOucString Astr("TestBucket");
00264 XrdSutBucket Bck0(Astr);
00265 PRINT(outname<<": length of string: "<<Bck0.size);
00266 XrdSutBucket Bck1(Astr);
00267 int lo1 = TestRSA_1->EncryptPrivate(Bck1);
00268 PRINT(outname<<": length of private encryption: "<<lo1);
00269 int lo2 = TestRSA_1->DecryptPublic(Bck1);
00270 PRINT(outname<<": length of public decryption: "<<lo2);
00271 if (Bck1 != Bck0) {
00272 PRINT(outname<<": test bucket RSA priv enc / pub dec failed: ");
00273 PRINT(outname<<": got: "<<lo2<<" bytes)");
00274 PRINT(outname<<": instead of: "<<lo1<<" bytes)");
00275 } else {
00276 PRINT(outname<<": test bucket RSA priv enc / pub dec OK");
00277 }
00278 XrdSutBucket Bck2(Astr);
00279 lo1 = TestRSA_1->EncryptPublic(Bck2);
00280 PRINT(outname<<": length of public encryption: "<<lo1);
00281 lo2 = TestRSA_1->DecryptPrivate(Bck2);
00282 PRINT(outname<<": length of private decryption: "<<lo2);
00283 if (Bck2 != Bck0) {
00284 PRINT(outname<<": test bucket RSA pub enc / priv dec failed: ");
00285 PRINT(outname<<": got: "<<lo2<<" bytes)");
00286 PRINT(outname<<": instead of: "<<lo1<<" bytes)");
00287 } else {
00288 PRINT(outname<<": test bucket RSA pub enc / priv dec OK");
00289 }
00290
00291 delete TestRSA_1;
00292 #if 0
00293 PRINT(outname<<": --------------------------------------------------- ");
00294
00295 DebugON = 0;
00296 bool match = 1;
00297 int i = 0;
00298 for (; i<1000; i++) {
00299
00300 TestRSA_1 = gCryptoFactory->RSA(2048);
00301
00302 lout1 = TestRSA_1->EncryptPrivate(buf_1,strlen(buf_1),buf_2,4096);
00303 lout2 = TestRSA_1->DecryptPublic(buf_2,lout1,buf_3,4096);
00304 if (memcmp(buf_1,buf_3,lin)) {
00305 PRINT(outname<<": RSA private enc / public dec mismatch: "<<i);
00306 PRINT(outname<<": got: "<<buf_3<<" ("<<lout2<<" bytes)");
00307 PRINT(outname<<": instead of: "<<buf_1<<" ("<<strlen(buf_1)<<" bytes)");
00308 } else if (lout2 > lin) {
00309 PRINT(outname<<": RSA private enc / public dec length mismatch: "<<i);
00310 PRINT(outname<<": got: "<<lout2<<" instead of "<<lin);
00311 int j = lin;
00312 for (; j<lout2; j++) printf("%s: %d: 0x%x\n",outname,j,(int)buf_3[j]);
00313 }
00314 delete TestRSA_1;
00315
00316 if (i && !(i % 10)) PRINT(outname<<": done "<<i);
00317 }
00318 #endif
00319 } else
00320 PRINT(outname<<": RSA object could not be instantiated: ");
00321
00322
00323
00324 PRINT(outname<<": --------------------------------------------------- ");
00325 PRINT(outname<<": Testing key agreement for ciphers ... ");
00326
00327 char *bp1 = 0;
00328 int lp1 = 0;
00329 PRINT(outname<<": CF_1: prepare ...");
00330 XrdCryptoCipher *CF_1 = gCryptoFactory->Cipher(0,0,0);
00331 if (CF_1 && CF_1->IsValid()) {
00332
00333 if (!(bp1 = CF_1->Public(lp1))) {
00334 PRINT(outname<<": CF_1 cipher: problems getting public part ");
00335 exit(1);
00336 }
00337 } else {
00338 PRINT(outname<<": CF_1 cipher object could not be instantiated: ");
00339 }
00340
00341 char *bp3 = 0;
00342 int lp3 = 0;
00343 PRINT(outname<<": CF_3: instantiate ... with pub");
00344 if (!local)
00345 PRINT(bp1);
00346 XrdCryptoCipher *CF_3 = gCryptoFactory->Cipher(0,bp1,lp1);
00347 if (CF_3 && CF_3->IsValid()) {
00348
00349 if (!(bp3 = CF_3->Public(lp3))) {
00350 PRINT(outname<<": CF_3 cipher: problems getting public part ");
00351 exit(1);
00352 }
00353 } else {
00354 PRINT(outname<<": CF_3 cipher object could not be instantiated: ");
00355 }
00356
00357 if (CF_1 && CF_1->IsValid() && bp3) {
00358 PRINT(outname<<": CF_1: finalize ... with pub");
00359 if (!local)
00360 PRINT(bp3);
00361 CF_1->Finalize(bp3,lp3,"default");
00362 } else {
00363 PRINT(outname<<": CF_1 cipher object could not be finalized ");
00364 }
00365
00366 if (CF_1 && CF_1->IsValid() && CF_3 && CF_3->IsValid()) {
00367 char chex[128] = {0};
00368 XrdSutToHex(CF_1->Buffer(),CF_1->Length(),&chex[0]);
00369 PRINT(outname<<": cipher 1 encrypted (hex):");
00370 PRINT(chex);
00371 PRINT(outname<<": cipher 1 used length: "<<CF_1->Length());
00372 XrdSutToHex(CF_3->Buffer(),CF_3->Length(),&chex[0]);
00373 PRINT(outname<<": cipher 3 encrypted (hex):");
00374 PRINT(chex);
00375 PRINT(outname<<": cipher 3 used length: "<<CF_3->Length());
00376 if (CF_1->Length() == CF_3->Length()) {
00377 if (!memcmp(CF_1->Buffer(),CF_3->Buffer(),CF_3->Length())) {
00378 PRINT(outname<<": ciphers match !");
00379 } else {
00380 PRINT(outname<<": ciphers DO NOT match !");
00381 }
00382 }
00383 }
00384
00385
00386 if (CF_1 && CF_1->IsValid() && CF_3 && CF_3->IsValid()) {
00387 char tm_1[64] = "Test message for cipher - 001";
00388 PRINT(outname<<": Test message: "<<tm_1);
00389 int ltm_1 = strlen(tm_1);
00390 char *tmp_1 = new char[CF_1->EncOutLength(ltm_1)];
00391 if (tmp_1) {
00392 int ltmp = CF_1->Encrypt(tm_1,ltm_1,tmp_1);
00393 char tm_2[128] = {0};
00394 XrdSutToHex(tmp_1,ltmp,&tm_2[0]);
00395 PRINT(outname<<": cipher encrypted (hex):");
00396 PRINT(tm_2);
00397 char *tm_3 = new char[CF_3->DecOutLength(ltmp)+1];
00398 int lfin = CF_3->Decrypt(tmp_1,ltmp,tm_3);
00399 delete[] tmp_1;
00400 if (tm_3) {
00401 tm_3[lfin] = 0;
00402 PRINT(outname<<": cipher decrypted: "<<tm_3);
00403 if (strncmp(tm_1,tm_3,ltm_1)) {
00404 PRINT(outname<<": symmetric cipher test failed: ");
00405 PRINT(outname<<": got: "<<tm_3<<" ("<<lfin<<" bytes)");
00406 PRINT(outname<<": instead of: "<<tm_1<<" ("<<ltm_1<<" bytes)");
00407 } else {
00408 PRINT(outname<<": symmetric cipher test OK ");
00409 }
00410 delete[] tm_3;
00411 } else
00412 PRINT(outname<<": cipher decryption failure");
00413 } else
00414 PRINT(outname<<": cipher encryption failure");
00415 }
00416
00417 if (CF_1) delete CF_1;
00418 if (CF_3) delete CF_3;
00419
00420 if (bp1) delete bp1;
00421 if (bp3) delete bp3;
00422
00423
00424
00425
00426 if (gCryptoFactory->ID() == 1) {
00427 PRINT(outname<<": --------------------------------------------------- ");
00428 PRINT(outname<<": Testing X509 functionality ... ");
00429 XrdCryptoX509 *x509 = gCryptoFactory->X509("/home/ganis/.globus/usercert.pem");
00430 if (x509) {
00431 x509->Dump();
00432 }
00433 }
00434
00435 PRINT(outname<<": --------------------------------------------------- ");
00436 exit(0);
00437 }