XrdCryptotest.cc

Go to the documentation of this file.
00001 // $Id: XrdCryptotest.cc 30949 2009-11-02 16:37:58Z ganis $
00002 
00003 const char *XrdCryptotestCVSID = "$Id: XrdCryptotest.cc 30949 2009-11-02 16:37:58Z ganis $";
00004 //
00005 //  Test program for XrdCrypto
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 // Globals 
00026 
00027 #define PRINT(x) {cerr <<x <<endl;}
00028 XrdCryptoFactory *gCryptoFactory = 0;
00029 
00030 int main( int argc, char **argv )
00031 {
00032    // Test implemented functionality
00033    char cryptomod[64] = "ssl";
00034    char outname[256] = {0};
00035 
00036    //
00037    // Set debug flags
00038    XrdSutSetTrace(sutTRACE_Debug);
00039    XrdCryptoSetTrace(cryptoTRACE_Debug);
00040 
00041    //
00042    // Determine application name
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    // Check/Use inputs
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    // Load the crypto factory
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    // Message Digest of a simple message
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       // Check result
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    // Instantiate a cipher
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       // Bucket encryption
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    // Try KDFun ...
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       // Check result
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    // Instantiate a RSA pair
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       // Bucket encryption
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       // repeat 1000 times
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    // Test key agreement
00324    PRINT(outname<<": --------------------------------------------------- ");
00325    PRINT(outname<<": Testing key agreement for ciphers ... ");
00326    // Get first cipher
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       // Get public part and save it to a buffer
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    // Get a third cipher directly from constructor
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       // Get public part and save it to a buffer
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    // Complete initialization
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    // Test matching now
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    // Encryption
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    // Test X509 ...
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 }

Generated on Tue Jul 5 14:46:34 2011 for ROOT_528-00b_version by  doxygen 1.5.1