00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <fstream>
00019 #include <sstream>
00020 #include <openssl/conf.h>
00021
00022 #include "StateInfo.h"
00023 #include "CODEX_ThresholdCrypto/ThresholdRSA.h"
00024 #include "CODEX_VSS/ModIntRange.h"
00025 #include "APSSShareCallback.h"
00026 #include "RecoverCallback.h"
00027
00028 #include "CODEX_Exceptions/FileExceptions.h"
00029 #include "CODEX_Server/ConfigurationExceptions.h"
00030 #include "CODEX_Exceptions/POSIXExceptions.h"
00031 #include "Exceptions.h"
00032
00033 using namespace CODEX_APSS;
00034
00035 StateInfo* StateInfo::m_instance = 0;
00036
00037
00038
00039
00040
00041
00042 StateInfo*
00043 StateInfo::instance()
00044 {
00045 if ( 0 == m_instance )
00046 {
00047 m_instance = new StateInfo;
00048 }
00049 return m_instance;
00050 }
00051
00052 void
00053 StateInfo::destroy()
00054 {
00055 if ( 0 != m_instance )
00056 {
00057 delete m_instance;
00058 }
00059 m_instance = 0;
00060 }
00061
00062 StateInfo::StateInfo() :
00063 m_domain( 0 ),
00064 m_refreshInterval( 0 ),
00065 m_rsaSubshareRange( 0 ),
00066 m_elgamalSubshareRange( 0 ),
00067 m_interval( 0 )
00068 {
00069 }
00070
00071 StateInfo::~StateInfo()
00072 {
00073 if ( 0 != m_rsaSubshareRange ) delete m_rsaSubshareRange;
00074 if ( 0 != m_elgamalSubshareRange ) delete m_elgamalSubshareRange;
00075 if ( 0 != m_rsaCallback ) delete m_rsaCallback;
00076 if ( 0 != m_elgamalCallback ) delete m_elgamalCallback;
00077 }
00078
00079
00080
00081
00082
00083
00084 void
00085 StateInfo::configure( const CONF* conf,
00086 const char* sec,
00087 const string& fname )
00088 {
00089
00090 CODEX_Server::ServerState* serverState =
00091 CODEX_Server::ServerState::instance();
00092
00093
00094 const unsigned int RSAKeyNum = CODEX_Server::ServerState::RSAKeyNum;
00095
00096 const LSType::LabelType& defaultRSALabel = serverState->defaultRSALabel();
00097 const LSType& rsaShares = serverState->rsaShares( defaultRSALabel,
00098 serverState->hostNum() );
00099 LSType* rsaBootstrap = new LSType( rsaShares );
00100 m_secrets[RSAKeyNum].setNum( RSAKeyNum );
00101 m_secrets[RSAKeyNum].addSharing( rsaBootstrap );
00102 m_secrets[RSAKeyNum].setWitness( serverState->rsaWitness() );
00103
00104 const CODEX_Ciphers::RSAPublicKey& pubRSAKey = serverState->serviceKey();
00105 m_rsaSubshareRange =
00106 new CODEX_ThresholdCrypto::ThresholdRSASubRange( pubRSAKey.n().value() );
00107 m_secrets[RSAKeyNum].setSubshareRange( m_rsaSubshareRange );
00108
00109
00110 const unsigned int EGKeyNum = CODEX_Server::ServerState::EGKeyNum;
00111
00112 const LSType::LabelType& defaultEGLabel = serverState->defaultEGLabel();
00113 const LSType& egShares =
00114 serverState->elgamalShares( defaultEGLabel, serverState->hostNum() );
00115 LSType* egBootstrap = new LSType( egShares );
00116 m_secrets[EGKeyNum].setNum( EGKeyNum );
00117 m_secrets[EGKeyNum].addSharing( egBootstrap );
00118 m_secrets[EGKeyNum].setWitness( serverState->egWitness() );
00119
00120 const CODEX_Ciphers::ElGamalPublicKey& pubEGKey =
00121 serverState->publicEGKey();
00122 m_elgamalSubshareRange = new CODEX_VSS::ModIntRange( pubEGKey.q() );
00123 m_secrets[EGKeyNum].setSubshareRange( m_elgamalSubshareRange );
00124
00125
00126
00127 m_rsaCallback = new APSSShareCallback( RSAKeyNum );
00128 serverState->setShareCallback( RSAKeyNum, m_rsaCallback );
00129
00130 m_elgamalCallback = new APSSShareCallback( EGKeyNum );
00131 serverState->setShareCallback( EGKeyNum, m_elgamalCallback );
00132
00133
00134
00135 long dummy;
00136 if ( ! NCONF_get_number_e(conf,sec,"apss_interval",&dummy) )
00137 {
00138 throw CODEX_Server::BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00139 fname, "nhosts" );
00140 }
00141 if ( dummy < 0 )
00142 {
00143 throw CODEX_Server::BCBadValueException( __FILE__ , __LINE__ ,
00144 fname, "apss_interval" );
00145 }
00146 m_interval = dummy;
00147
00148
00149
00150 m_secrets[RSAKeyNum].setEpochTime();
00151 m_secrets[EGKeyNum].setEpochTime();
00152 }
00153
00154 void
00155 StateInfo::addSharing( LSType* sharing )
00156 {
00157 if ( 0 == sharing )
00158 {
00159 return;
00160 }
00161 unsigned int num = sharing->label().num().value();
00162 checkSecretNum( num );
00163 m_secrets[num].addSharing( sharing );
00164 }
00165
00166 const LSType&
00167 StateInfo::sharing( const LSType::LabelType& label, unsigned int server ) const
00168 {
00169 unsigned int num = label.num().value();
00170 checkSecretNum( num );
00171 return m_secrets.find(num)->second.sharing( label, server );
00172 }
00173
00174 const WitnessType&
00175 StateInfo::witness( unsigned int num ) const
00176 {
00177 checkSecretNum( num );
00178 return m_secrets.find(num)->second.witness();
00179 }
00180
00181 const ShareSetType&
00182 StateInfo::subsharing( const SublabelType& sublabel,
00183 unsigned int server ) const
00184 {
00185 unsigned int num = sublabel.label().num().value();
00186 checkSecretNum( num );
00187 return m_secrets.find(num)->second.subsharing( sublabel, server );
00188 }
00189
00190 void
00191 StateInfo::addSubsharing( const SublabelType& sublabel,
00192 const ShareType& subsharing )
00193 {
00194 unsigned int num = sublabel.label().num().value();
00195 checkSecretNum( num );
00196 m_secrets[ num ].addSubsharing( sublabel, subsharing );
00197 }
00198
00199 void
00200 StateInfo::recover( const SublabelType& sublabel )
00201 {
00202
00203 RecoveryList::const_iterator itr = m_recoverLabels.begin();
00204 RecoveryList::const_iterator end = m_recoverLabels.end();
00205 for ( ; itr != end ; ++itr )
00206 {
00207 if ( sublabel == *itr )
00208 {
00209 return;
00210 }
00211 }
00212
00213 CODEX_Server::ServerState* serverState =
00214 CODEX_Server::ServerState::instance();
00215 StateInfo* stateInfo = StateInfo::instance();
00216
00217
00218 unsigned int version = sublabel.label().version().value() + 1;
00219 RecoverMsg request( version,
00220 sublabel,
00221 serverState->hostNum(),
00222 serverState->hostNum() );
00223
00224
00225 BIGNUM * digest = 0;
00226 CODEX_Ciphers::RSASignature* signature = 0;
00227 try
00228 {
00229 const CODEX_Ciphers::HashFunction& hashFunc = serverState->hashFunc();
00230 digest = request.digest( hashFunc );
00231 if ( 0 == digest )
00232 {
00233 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00234 }
00235 const CODEX_Ciphers::RSAPrivateKey& key = serverState->privateKey();
00236 signature = key.sign( digest );
00237 BN_free(digest);
00238 digest = 0;
00239 if ( 0 == signature )
00240 {
00241 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00242 }
00243 }
00244 catch ( ... )
00245 {
00246 if ( 0 != digest ) BN_free( digest );
00247 if ( 0 != signature ) delete signature;
00248 throw;
00249 }
00250 SignedRecoverMsg signedRequest( request, *signature );
00251 delete signature;
00252
00253
00254 CODEX_Quorum::Message m;
00255 const unsigned char* seqNum = serverState->newSequenceNumber();
00256 unsigned char ucSelf =
00257 serverState->hostNum() | CODEX_Server::ServerState::OutgoingMask;
00258 m.fill( ucSelf );
00259 m.fill( seqNum, CODEX_Server::ServerState::nMID );
00260 m.fill( stateInfo->domain() );
00261 m.fill( kRecoverMsg | SignatureMask );
00262 int length = signedRequest.marshal(0);
00263 unsigned char* buffer = new unsigned char[length];
00264 unsigned char* pBuffer = buffer;
00265 signedRequest.marshal(&pBuffer);
00266 m.fill( buffer, length );
00267 delete [] buffer;
00268
00269
00270 RecoverCallback* cb =
00271 new RecoverCallback( version, sublabel );
00272
00273
00274 stateInfo->broadcast( m, cb );
00275
00276
00277 m_recoverLabels.push_back( sublabel );
00278 }
00279
00280 void
00281 StateInfo::markRecovered( const SublabelType& label )
00282 {
00283 m_recoverLabels.remove( label );
00284 }
00285
00286 SubshareList&
00287 StateInfo::splittings( const LabelType& label )
00288 {
00289 unsigned int num = label.num().value();
00290 checkSecretNum( num );
00291 return m_secrets[num].splittings( label );
00292 }
00293
00294 const CODEX_VSS::Range&
00295 StateInfo::subshareRange( unsigned int num ) const
00296 {
00297 checkSecretNum( num );
00298 return m_secrets.find(num)->second.subshareRange();
00299 }
00300
00301 void
00302 StateInfo::updateExpired()
00303 {
00304 struct timeval tv;
00305 int gtod = gettimeofday( &tv, 0 );
00306 if ( 0 != gtod )
00307 {
00308 CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ , errno );
00309 }
00310 unsigned long currentTime = tv.tv_sec;
00311
00312 SecretManagementMap::iterator itr = m_secrets.begin();
00313 SecretManagementMap::iterator end = m_secrets.end();
00314 for ( ; itr != end ; ++itr )
00315 {
00316 #if 0
00317 if ( itr->first != CODEX_Server::ServerState::RSAKeyNum )
00318 {
00319 continue;
00320 }
00321 #endif
00322 unsigned long elapsed = itr->second.elapsed( currentTime );
00323 if ( elapsed >= m_interval )
00324 {
00325 itr->second.beginRun();
00326 }
00327 }
00328 }
00329
00330 void
00331 StateInfo::updateAll()
00332 {
00333 SecretManagementMap::iterator itr = m_secrets.begin();
00334 SecretManagementMap::iterator end = m_secrets.end();
00335 for ( ; itr != end ; ++itr )
00336 {
00337 itr->second.beginRun();
00338 }
00339 }
00340
00341 bool
00342 StateInfo::addInitMsg( const SignedInitMsg& im )
00343 {
00344 unsigned int num = im.message().label().num().value();
00345 checkSecretNum( num );
00346 return m_secrets[num].addInitMsg( im );
00347 }
00348
00349 bool
00350 StateInfo::addEstablishMsg( const SignedEstablishMsg& em )
00351 {
00352 unsigned int num = em.message().sublabel().label().num().value();
00353 checkSecretNum( num );
00354 return m_secrets[num].addEstablishMsg( em );
00355 }
00356
00357 bool
00358 StateInfo::addComputeMsg( const SignedComputeMsg& cm )
00359 {
00360 unsigned int num = cm.message().subshareLabel(0).label().num().value();
00361 checkSecretNum( num );
00362 return m_secrets[num].addComputeMsg( cm );
00363 }
00364
00365 bool
00366 StateInfo::addFinishedMsg( const SignedFinishedMsg& fm )
00367 {
00368 unsigned int num =
00369 fm.message().evidence().element(0)->message().shareLabel().num().value();
00370 checkSecretNum( num );
00371 bool retVal = m_secrets[num].addFinishedMsg( fm );
00372 return retVal;
00373 }
00374
00375 bool
00376 StateInfo::addInitResponse( const SignedContributeMsg& cm )
00377 {
00378 const SignedEstablishedMsg& sem = *(cm.message().evidence().element(0));
00379 unsigned int num = sem.message().sublabel().label().num().value();
00380 checkSecretNum( num );
00381 return m_secrets[num].addInitResponse( cm );
00382 }
00383
00384 bool
00385 StateInfo::addEstablishResponse( const SignedEstablishedMsg& em )
00386 {
00387 unsigned int num = em.message().sublabel().label().num().value();
00388 checkSecretNum( num );
00389 return m_secrets[num].addEstablishResponse( em );
00390 }
00391
00392 bool
00393 StateInfo::addComputeResponse( const SignedComputedMsg& cm )
00394 {
00395 unsigned int num = cm.message().shareLabel().num().value();
00396 checkSecretNum( num );
00397 return m_secrets[num].addComputeResponse( cm );
00398 }
00399
00400 void
00401 StateInfo::clearEstablishMsgs( unsigned int num )
00402 {
00403 checkSecretNum( num );
00404 m_secrets[num].clearEstablishMsgs();
00405 }
00406
00407 void
00408 StateInfo::clearEstablishMsgs( unsigned int num, unsigned int establisher )
00409 {
00410 checkSecretNum( num );
00411 m_secrets[num].clearEstablishMsgs( establisher );
00412 }
00413
00414 unsigned long
00415 StateInfo::version( unsigned int num ) const
00416 {
00417 checkSecretNum( num );
00418 return m_secrets.find(num)->second.version();
00419 }
00420
00421 const InitRecord&
00422 StateInfo::initRecord( unsigned int num, unsigned int i ) const
00423 {
00424 checkSecretNum( num );
00425 return m_secrets.find(num)->second.initRecord(i);
00426 }
00427
00428 const EstablishRecord&
00429 StateInfo::establishRecord( unsigned int num,
00430 unsigned int establisher,
00431 unsigned int shareNum,
00432 const LabelType& label ) const
00433 {
00434 checkSecretNum( num );
00435 return m_secrets.find(num)->second.establishRecord( establisher,
00436 shareNum,
00437 label );
00438 }
00439
00440 const ComputeRecord&
00441 StateInfo::computeRecord( unsigned int num, unsigned int i ) const
00442 {
00443 checkSecretNum( num );
00444 return m_secrets.find(num)->second.computeRecord(i);
00445 }
00446
00447 const SignedFinishedMsg&
00448 StateInfo::finishedMsg( unsigned int num, unsigned int i ) const
00449 {
00450 checkSecretNum( num );
00451 return m_secrets.find(num)->second.finishedMsg(i);
00452 }
00453
00454 void
00455 StateInfo::sendFinished( unsigned int num, unsigned int server ) const
00456 {
00457 checkSecretNum( num );
00458 m_secrets.find(num)->second.sendFinished( server );
00459 }
00460
00461 void
00462 StateInfo::sendFinished( unsigned int num,
00463 unsigned int coord,
00464 unsigned int server ) const
00465 {
00466 checkSecretNum( num );
00467 m_secrets.find(num)->second.sendFinished( coord, server );
00468 }
00469
00470 void
00471 StateInfo::sendTo( unsigned int server, const CODEX_Quorum::Message& message )
00472 {
00473 if ( 0 != m_deliverer )
00474 {
00475 m_deliverer->sendTo( server, message );
00476 }
00477 }
00478
00479 void
00480 StateInfo::broadcast( const CODEX_Quorum::Message& message,
00481 CODEX_Quorum::ResponseCallback* cb )
00482 {
00483 if ( 0 != m_deliverer )
00484 {
00485 m_deliverer->broadcast( message, cb );
00486 }
00487 }
00488
00489 void
00490 StateInfo::checkSecretNum( unsigned int num ) const
00491 {
00492 SecretManagementMap::const_iterator itr = m_secrets.find(num);
00493 if ( m_secrets.end() == itr )
00494 {
00495 throw BadSecretNumberException( __FILE__ , __LINE__ );
00496 }
00497 }