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

Generated on Wed Jun 2 16:32:57 2004 for COrnell Data EXchange (CODEX) by doxygen1.2.18