Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

verify_private_keys.cc

00001 /*
00002  * Copyright 2003 Michael A. Marsh, Cornell University. All rights reserved.
00003  * This software is released under the modified BSD license.
00004  * See the file LICENSE in the top-level directory for details.
00005  */
00006 //
00007 // $Id: verify_private_keys.cc,v 1.5 2005/01/21 19:44:16 mmarsh Exp $
00008 //
00009 // $Log: verify_private_keys.cc,v $
00010 // Revision 1.5  2005/01/21 19:44:16  mmarsh
00011 // Updated for compatibility with Doxygen 1.4.1
00012 //
00013 // Revision 1.4  2004/05/19 15:56:46  mmarsh
00014 // *** empty log message ***
00015 //
00016 // Revision 1.3  2003/11/06 18:11:51  mmarsh
00017 // Cleaned up doxygen page label and title.
00018 //
00019 // Revision 1.2  2003/11/04 22:07:36  mmarsh
00020 // General code cleanup and reorganization.
00021 //
00022 //
00023 
00066 #include <fstream>
00067 #include <sstream>
00068 #include <openssl/ssl.h>
00069 #include <openssl/conf.h>
00070 #include <unistd.h>
00071 
00072 #include "CODEX_Ciphers/RSA.h"
00073 #include "CODEX_Ciphers/ElGamal.h"
00074 #include "CODEX_Ciphers/SHA1HashFunction.h"
00075 #include "CODEX_Server/ConfigurationExceptions.h"
00076 #include "CODEX_Server/ServerState.h"
00077 #include "CODEX_ThresholdCrypto/CombinatoricThresholdRSA.h"
00078 
00079 using namespace CODEX_Server;
00080 
00081 int main( int argc, char** argv )
00082 {
00083    SSLeay_add_ssl_algorithms();
00084 
00085    int arg = 0;
00086    string fname;
00087    string config_section;
00088    string usage_string(
00089       "Usage: split_private_keys -c <config_file> [-s <section>]");
00090    while ( -1 != arg )
00091    {
00092       arg = getopt(argc,argv,"c:s:");
00093       switch(arg)
00094       {
00095          case 'c' :
00096             fname = optarg;
00097             break;
00098          case 's' :
00099             config_section = optarg;
00100             break;
00101          case ':' :
00102          case '?' :
00103             cerr << usage_string << endl;
00104             ::exit(1);
00105       }
00106    }
00107    if ( 0 == fname.size() )
00108    {
00109       cerr << usage_string << endl;
00110       ::exit(1);
00111    }
00112 
00113    unsigned int nerror = 0;
00114    try
00115    {
00116       CONF* conf = NCONF_new(NCONF_default());
00117       if ( 0 == NCONF_load(conf,fname.c_str(),0) )
00118       {
00119          throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00120                                                           __LINE__ ,
00121                                                           fname );
00122       }
00123       char* section = (char*) config_section.c_str();
00124 
00125       const unsigned int N = ServerState::nServers;
00126       const unsigned int T = 1 + ServerState::nFaults;
00127 
00128       long dummy;
00129       if ( ! NCONF_get_number_e(conf,section,"nhosts",&dummy) )
00130       {
00131          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00132                                                fname, "nhosts" );
00133       }
00134       if ( N != dummy )
00135       {
00136          throw BCBadValueException( __FILE__ , __LINE__ , fname, "nhosts" );
00137       }
00138       if ( ! NCONF_get_number_e(conf,section,"nfaults",&dummy) )
00139       {
00140          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00141                                                fname, "nfaults" );
00142       }
00143       if ( (T-1) != dummy )
00144       {
00145          throw BCBadValueException( __FILE__ , __LINE__ , fname, "nfaults" );
00146       }
00147 
00148       const char* privKeyFile =
00149          NCONF_get_string(conf,section,"private_key_file");
00150       if ( 0 == privKeyFile )
00151       {
00152          throw BCBadValueException( __FILE__ , __LINE__ ,
00153                                     fname, "private_key_file" );
00154       }
00155       const char* privKeyPasswd =
00156          NCONF_get_string(conf,section,"private_key_passwd");
00157       CODEX_Ciphers::RSAPrivateKey privKey;
00158       privKey.fromPEMFile( privKeyFile, privKeyPasswd );
00159 
00160       const char* pubEGKeyFile =
00161          NCONF_get_string(conf,section,"public_eg_key_file");
00162       if ( 0 == pubEGKeyFile )
00163       {
00164          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00165                                                fname, "public_eg_key_file" );
00166       }
00167       const char* privEGKeyFile =
00168          NCONF_get_string(conf,section,"private_eg_key_file");
00169       if ( 0 == privEGKeyFile )
00170       {
00171          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00172                                                fname, "private_eg_key_file" );
00173       }
00174       CODEX_Server::SignedAugmentedEGPublicKey pubEGKey;
00175       ifstream is(pubEGKeyFile);
00176       if ( ! is.is_open() )
00177       {
00178          throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00179                                                           __LINE__ ,
00180                                                           pubEGKeyFile );
00181       }
00182       string s;
00183       char ch;
00184       while ( is.get(ch) )
00185       {
00186          s.push_back(ch);
00187       }
00188       //basic_string<unsigned char> s;
00189       //is >> s;
00190       unsigned int length = s.length();
00191       //unsigned char* p = (unsigned char*)s.data();
00192       unsigned char* p = new unsigned char[length];
00193       unsigned char* pOrig = p;
00194       for ( unsigned int i = 0 ; i < length ; ++i )
00195       {
00196          p[i] = s.data()[i];
00197       }
00198       if ( 0 == pubEGKey.unmarshal(0,&p,length) )
00199       {
00200          delete [] pOrig;
00201          throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00202       }
00203       delete [] pOrig;
00204       CODEX_Ciphers::ElGamalPrivateKey privEGKey;
00205       privEGKey.fromFile( privEGKeyFile );
00206 
00207       typedef CODEX_VSS::ModExpFunctional                     OneWay;
00208       typedef CODEX_VSS::Combinatoric< N , T >                ShareType;
00209       typedef CODEX_VSS::LabeledShare< ShareType , OneWay >   LSType;
00210       typedef CODEX_VSS::SecretWitness< ShareType , OneWay >  WitnessType;
00211 
00212       const char* output_dir =
00213          NCONF_get_string(conf,section,"output_directory");
00214       if ( 0 == output_dir )
00215       {
00216          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00217                                                fname, "output_directory" );
00218       }
00219 
00220       WitnessType rsaWitness;
00221       ostringstream rwstr;
00222       rwstr << output_dir << "/rsa.witness\0";
00223       rsaWitness.fromFile( rwstr.str().c_str() );
00224 
00225       WitnessType egWitness;
00226       ostringstream ewstr;
00227       ewstr << output_dir << "/elgamal.witness\0";
00228       egWitness.fromFile( ewstr.str().c_str() );
00229 
00230       LSType rsaSharings[N];
00231       LSType elgamalSharings[N];
00232       for ( unsigned int i = 0 ; i < N ; ++i )
00233       {
00234          ostringstream rstr;
00235          rstr << output_dir << "/rsa." << i << ".shares" << '\0';
00236          rsaSharings[i].fromFile( rstr.str().c_str() );
00237          ostringstream estr;
00238          estr << output_dir << "/elgamal." << i << ".shares" << '\0';
00239          elgamalSharings[i].fromFile( estr.str().c_str() );
00240       }
00241 
00242       // Check consistency of each share
00243       const unsigned int nShares = ShareType::NumShares;
00244       ShareType fullRSA;
00245       ShareType fullElGamal;
00246       OneWay rsaOneWay( rsaWitness.args() );
00247       OneWay egOneWay( egWitness.args() );
00248       for ( unsigned int i = 0 ; i < N ; ++i )
00249       {
00250          if ( ! ( rsaSharings[i].label().verify( rsaWitness.witness(),
00251                                                  rsaOneWay ) &&
00252                   rsaSharings[i].label().check( rsaSharings[i].share(),
00253                                                 rsaOneWay ) ) )
00254          {
00255             cerr << "RSA shares for " << i << " inconsistent" << endl;
00256             ++nerror;
00257          }
00258          fullRSA += rsaSharings[i].share();
00259          if ( ! ( elgamalSharings[i].label().verify( egWitness.witness(),
00260                                                      egOneWay ) &&
00261                   elgamalSharings[i].label().check( elgamalSharings[i].share(),
00262                                                     egOneWay ) ) )
00263          {
00264             cerr << "ElGamal shares for " << i << " inconsistent" << endl;
00265             ++nerror;
00266          }
00267          fullElGamal += elgamalSharings[i].share();
00268       }
00269       for ( unsigned int i = 0 ; i < N ; ++i )
00270       {
00271          for ( unsigned int j = 0 ; j < nShares ; ++j )
00272          {
00273             if ( rsaSharings[i].share().share(j).initialized() )
00274             {
00275                if ( 0 != BN_cmp( rsaSharings[i].share().share(j).value(),
00276                                  fullRSA.share(j).value() ) )
00277                {
00278                   cerr << "disagreement in RSA share " << j << endl;
00279                   ++nerror;
00280                }
00281             }
00282             if ( elgamalSharings[i].share().share(j).initialized() )
00283             {
00284                if ( 0 != BN_cmp( elgamalSharings[i].share().share(j).value(),
00285                                  fullElGamal.share(j).value() ) )
00286                {
00287                   cerr << "disagreement in ElGamal share " << j << endl;
00288                   ++nerror;
00289                }
00290             }
00291          }
00292       }
00293 
00294       // Now recover the private keys from the sharings.
00295       CODEX_ASN1::SecureBigNumber d;
00296       fullRSA.recover( d );
00297       if ( 0 != BN_cmp( privKey.d().value(), d.value() ) )
00298       {
00299          cerr << "disagreement recovering RSA key" << endl;
00300          ++nerror;
00301       }
00302       CODEX_ASN1::SecureBigNumber x;
00303       fullElGamal.recover( x );
00304       if ( 0 != BN_cmp( privEGKey.x().value(), x.value() ) )
00305       {
00306          cerr << "disagreement recovering ElGamal key" << endl;
00307          ++nerror;
00308       }
00309 
00310       // Now test threshold cryptography
00311       BIGNUM * two = BN_new();
00312       BN_add( two, BN_value_one(), BN_value_one() );
00313       CODEX_ThresholdCrypto::ThresholdRSACrypto< ShareType >
00314          tRSA( privKey.n() );
00315       ShareType rsaSigShares;
00316       tRSA.sign( fullRSA, two, rsaSigShares );
00317       CODEX_VSS::ShareSet< ShareType > rsaSigSet;
00318       for ( unsigned int i = 0 ; i < nShares ; ++i )
00319       {
00320          rsaSigSet.setShare(i, rsaSigShares.share(i));
00321       }
00322       BIGNUM * rsaSig1 = tRSA.threshold(rsaSigSet);
00323       CODEX_Ciphers::RSASignature* rsaSig2 = privKey.sign(two);
00324       if ( 0 != BN_cmp( rsaSig1 , rsaSig2->value() ) )
00325       {
00326          cerr << "threshold RSA signature bad" << endl;
00327          ++nerror;
00328       }
00329    }
00330    catch ( CODEX_Exceptions::ExceptionBase& e )
00331    {
00332       e.report();
00333       return 1;
00334    }
00335 
00336    cout << nerror << " errors detected" << endl;
00337    return 0;
00338 }

Generated on Fri May 6 17:41:27 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1