00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00189
00190 unsigned int length = s.length();
00191
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
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
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
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 }