00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00186
00187 unsigned int length = s.length();
00188
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
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
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
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 }