00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <sys/time.h>
00019 #include <errno.h>
00020
00021 #include "SecretManagement.h"
00022 #include "StateInfo.h"
00023 #include "InitCallback.h"
00024 #include "Exceptions.h"
00025 #include "CODEX_Exceptions/POSIXExceptions.h"
00026 #include "CODEX_Server/ServerExceptions.h"
00027
00028 #include "timing.h"
00029 #ifdef TIMING
00030 #include <sstream>
00031 #endif
00032
00033 using namespace CODEX_APSS;
00034
00035 SecretManagement::SecretManagement() :
00036 m_shareCallback( 0 ),
00037 m_subshareRange( 0 ),
00038 m_version( 0 ),
00039 m_num( 0 ),
00040 m_epochTime( 0 ),
00041 m_runTime( 0 )
00042 {
00043 }
00044
00045 SecretManagement::~SecretManagement()
00046 {
00047 if ( 0 != m_shareCallback ) delete m_shareCallback;
00048 while ( ! m_sharings.empty() )
00049 {
00050 SharingList::value_type back = m_sharings.back();
00051 if ( 0 != back ) delete back;
00052 m_sharings.pop_back();
00053 }
00054 m_subsharings.clear();
00055 clearEstablishMsgs();
00056 }
00057
00058 void
00059 SecretManagement::setSubshareRange( const CODEX_VSS::Range* subshareRange )
00060 {
00061 m_subshareRange = subshareRange;
00062 }
00063
00064 const CODEX_VSS::Range&
00065 SecretManagement::subshareRange() const
00066 {
00067 if ( 0 == m_subshareRange )
00068 {
00069 throw MissingRangeException( __FILE__ , __LINE__ );
00070 }
00071 return *m_subshareRange;
00072 }
00073
00074 void
00075 SecretManagement::addSharing( LSType* sharing )
00076 {
00077 if ( 0 == sharing )
00078 {
00079 return;
00080 }
00081
00082 const CODEX_ASN1::Integer& version = sharing->label().version();
00083 if ( ! version.initialized() )
00084 {
00085 delete sharing;
00086 return;
00087 }
00088
00089 unsigned int vnum = version.value();
00090 if ( vnum < m_version )
00091 {
00092 delete sharing;
00093 return;
00094 }
00095
00096
00097
00098 SharingList::const_iterator sItr = m_sharings.begin();
00099 SharingList::const_iterator sEnd = m_sharings.end();
00100 for ( ; sItr != sEnd ; ++sItr )
00101 {
00102 if ( ( (*sItr)->label().id().value() ==
00103 sharing->label().id().value() ) &&
00104 ( (*sItr)->label().version().value() ==
00105 sharing->label().version().value() ) )
00106 {
00107 delete sharing;
00108 return;
00109 }
00110 }
00111 m_sharings.push_back( sharing );
00112 }
00113
00114 bool
00115 SecretManagement::labelValid( const LabelType& label ) const
00116 {
00117 for ( unsigned int i = 0 ; i < NumServers ; ++i )
00118 {
00119 if ( m_finishedLog[i].initialized() )
00120 {
00121 if ( m_finishedLog[i].message().evidence().element(0)->
00122 message().shareLabel() ==
00123 label )
00124 {
00125 return true;
00126 }
00127 }
00128 }
00129 return false;
00130 }
00131
00132 const LSType&
00133 SecretManagement::sharing( const LSType::LabelType& label,
00134 unsigned int server ) const
00135 {
00136 unsigned int version = label.version().value();
00137 if ( version < m_version )
00138 {
00139
00140 sendFinished( server );
00141 throw CODEX_Server::InvalidLabelException( __FILE__ , __LINE__ );
00142 }
00143 if ( version > m_version )
00144 {
00145
00146 throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00147 }
00148 SharingList::const_iterator sItr = m_sharings.begin();
00149 SharingList::const_iterator sEnd = m_sharings.end();
00150 for ( ; sItr != sEnd ; ++sItr )
00151 {
00152 if ( (*sItr)->label() == label )
00153 {
00154 return **sItr;
00155 }
00156 else if ( (*sItr)->label().id().value() == label.id().value() )
00157 {
00158
00159 throw CODEX_Server::InvalidLabelException( __FILE__ , __LINE__ );
00160 }
00161 }
00162 if ( ! labelValid( label ) )
00163 {
00164 sendFinished( server );
00165 throw CODEX_Server::InvalidLabelException( __FILE__ , __LINE__ );
00166 }
00167
00168 throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00169 }
00170
00171 void
00172 SecretManagement::addSubsharing( const SublabelType& label,
00173 const ShareType& subsharing )
00174 {
00175 const CODEX_ASN1::Integer& version = label.label().version();
00176 if ( ! version.initialized() )
00177 {
00178 return;
00179 }
00180
00181 unsigned int vnum = version.value();
00182 if ( vnum < m_version )
00183 {
00184 return;
00185 }
00186 m_subsharings[label].addShare( subsharing );
00187 }
00188
00189 const ShareSetType&
00190 SecretManagement::subsharing( const SublabelType& sublabel,
00191 unsigned int server ) const
00192 {
00193 unsigned int vnum = sublabel.label().version().value();
00194 if ( vnum < m_version )
00195 {
00196
00197 sendFinished( server );
00198 throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00199 }
00200 SubsharingMap::const_iterator sItr = m_subsharings.find( sublabel );
00201 if ( sItr == m_subsharings.end() )
00202 {
00203
00204 throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00205 }
00206 return sItr->second;
00207 }
00208
00209 SubshareList&
00210 SecretManagement::splittings( const LabelType& label )
00211 {
00212 return m_splittings[ label ];
00213 }
00214
00215 bool
00216 SecretManagement::addInitMsg( const SignedInitMsg& im )
00217 {
00218 unsigned int coord = im.message().coordinator().value();
00219 int version = im.message().version().value();
00220 const InitMsg& stored = m_initLog[coord].request();
00221
00222 if ( ! stored.initialized() )
00223 {
00224 m_initLog[coord].addRequest(im.message());
00225 return true;
00226 }
00227
00228 if ( version > stored.version().value() )
00229 {
00230 m_initLog[coord].addRequest(im.message());
00231 return true;
00232 }
00233
00234
00235
00236
00237
00238 if ( im.message().label() == stored.label() )
00239 {
00240
00241 return false;
00242 }
00243
00244
00245 throw InitMsgConflictException( __FILE__ ,
00246 __LINE__ ,
00247 coord,
00248 im.message().label(),
00249 stored.label() );
00250 return false;
00251 }
00252
00253 bool
00254 SecretManagement::addEstablishMsg( const SignedEstablishMsg& em )
00255 {
00256 unsigned int estab = em.message().establisher().value();
00257 unsigned int snum = em.message().sublabel().id().value();
00258 EstablishRecord& er =
00259 m_establishLog[ estab ][ snum ][ em.message().sublabel().label() ];
00260 bool retVal = false;
00261 if ( ! er.request().initialized() )
00262 {
00263 retVal = true;
00264 }
00265 else
00266 {
00267 if ( er.request().sublabel() != em.message().sublabel() )
00268 {
00269 throw EstablishMsgConflictException(
00270 __FILE__ , __LINE__ , estab, em.message().sublabel(),
00271 er.request().sublabel() );
00272 }
00273 }
00274 if (retVal)
00275 {
00276
00277
00278 er.addRequest( EstablishMsg( em.message().version(),
00279 em.message().sublabel(),
00280 em.message().establisher(),
00281 em.message().recipient(),
00282 ShareType() ) );
00283 addSubsharing( em.message().sublabel(), em.message().shares() );
00284 }
00285 return retVal;
00286 }
00287
00288 bool
00289 SecretManagement::addComputeMsg( const SignedComputeMsg& cm )
00290 {
00291 unsigned int coord = cm.message().coordinator().value();
00292 int version = cm.message().subshareLabel(0).label().version().value();
00293 const ComputeMsg& stored = m_computeLog[coord].request();
00294
00295 if ( ! stored.initialized() )
00296 {
00297 m_computeLog[coord].addRequest(cm.message());
00298 return true;
00299 }
00300
00301 if ( version > stored.subshareLabel(0).label().version().value() )
00302 {
00303 m_computeLog[coord].addRequest(cm.message());
00304 return true;
00305 }
00306
00307
00308
00309
00310
00311 for ( unsigned int i = 0 ; i < NumShares ; ++i )
00312 {
00313 if ( cm.message().subshareLabel(i) != stored.subshareLabel(i) )
00314 {
00315
00316 throw ComputeMsgConflictException( __FILE__ , __LINE__ , coord,
00317 cm.message(), stored );
00318 }
00319 }
00320
00321 return false;
00322 }
00323
00324 bool
00325 SecretManagement::addFinishedMsg( const SignedFinishedMsg& fm )
00326 {
00327 CODEX_Server::ServerState* serverState =
00328 CODEX_Server::ServerState::instance();
00329
00330 unsigned int coord = fm.message().coordinator().value();
00331 unsigned int version = fm.message().version().value();
00332
00333 if ( coord >= NumServers )
00334 {
00335 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00336 }
00337
00338
00339 if ( version < m_version )
00340 {
00341 return false;
00342 }
00343
00344
00345 m_finishedLog[coord] = fm;
00346
00347
00348 if ( version > m_version )
00349 {
00350
00351
00352
00353
00354
00355
00356 m_version = version;
00357
00358 for ( unsigned int i = 0 ; i < NumServers ; ++i )
00359 {
00360 if ( m_finishedLog[i].initialized() && ( i != coord ) )
00361 {
00362 m_finishedLog[i] = SignedFinishedMsg();
00363 }
00364 }
00365
00366 SharingList::iterator slItr = m_sharings.begin();
00367 SharingList::iterator slEnd = m_sharings.end();
00368 SharingList tempList;
00369 for ( ; slItr != slEnd ; ++slItr )
00370 {
00371 unsigned int slVers = (*slItr)->label().version().value();
00372 if ( slVers >= m_version )
00373 {
00374 tempList.push_back( *slItr );
00375 }
00376 else
00377 {
00378 delete (*slItr);
00379 }
00380 }
00381 m_sharings = tempList;
00382
00383 SubsharingMap::iterator sslItr = m_subsharings.begin();
00384 SubsharingMap::iterator sslEnd = m_subsharings.end();
00385 SubsharingMap tempMap;
00386
00387 for ( ; sslItr != sslEnd ; ++sslItr )
00388 {
00389
00390 unsigned int sslVers = sslItr->first.label().version().value() + 1;
00391 if ( sslVers >= m_version )
00392 {
00393 tempMap.insert( *sslItr );
00394
00395
00396
00397 }
00398 }
00399 m_subsharings = tempMap;
00400
00401 SplittingMap::iterator smItr = m_splittings.begin();
00402 SplittingMap::iterator smEnd = m_splittings.end();
00403 SplittingMap tempSMap;
00404 for ( ; smItr != smEnd ; ++smItr )
00405 {
00406 unsigned int smVers = smItr->first.version().value() + 1;
00407 if ( smVers >= m_version )
00408 {
00409 tempSMap.insert( *smItr );
00410 }
00411 }
00412 m_splittings = tempSMap;
00413
00414 for ( unsigned int i = 0 ; i < NumServers ; ++i )
00415 {
00416 for ( unsigned int j = 0 ; j < NumShares ; ++j )
00417 {
00418 EstablishMap tempEMap;
00419 EstablishMap::iterator emItr = m_establishLog[i][j].begin();
00420 EstablishMap::iterator emEnd = m_establishLog[i][j].end();
00421 for ( ; emItr != emEnd ; ++emItr )
00422 {
00423 unsigned int eVers = emItr->first.version().value() + 1;
00424 if ( eVers >= m_version )
00425 {
00426 tempEMap.insert( *emItr );
00427 }
00428 }
00429 m_establishLog[i][j] = tempEMap;
00430 }
00431 }
00432
00433 struct timeval tv;
00434 int gtod = gettimeofday( &tv, 0 );
00435 if ( 0 != gtod )
00436 {
00437 CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ ,
00438 errno );
00439 }
00440 cout << "entering epoch " << m_version
00441 << " (" << tv.tv_sec - m_runTime
00442 << ")" << endl;
00443
00444 setEpochTime();
00445
00446 #ifdef TIMING
00447 if ( serverState->hostNum() == coord )
00448 {
00449 APSSTimer[m_num].stop();
00450 }
00451
00452
00453 ActiveTimer.print(cout);
00454 SSLTimer.print(cout);
00455 OneWayTimer.print(cout);
00456 SignTimer.print(cout);
00457 SignVerifyTimer.print(cout);
00458 APSSTimer[m_num].print(cout);
00459 InitTimer[m_num].print(cout);
00460 InitIdleTimer[m_num].print(cout);
00461 InitActTimer[m_num].print(cout);
00462 InitActIdleTimer[m_num].print(cout);
00463 ComputeTimer[m_num].print(cout);
00464 ComputeIdleTimer[m_num].print(cout);
00465
00466 ActiveTimer.clear();
00467 SSLTimer.clear();
00468 OneWayTimer.clear();
00469 SignTimer.clear();
00470 SignVerifyTimer.clear();
00471 APSSTimer[m_num].clear();
00472 InitTimer[m_num].clear();
00473 InitIdleTimer[m_num].clear();
00474 InitActTimer[m_num].clear();
00475 InitActIdleTimer[m_num].clear();
00476 ComputeTimer[m_num].clear();
00477 ComputeIdleTimer[m_num].clear();
00478 #endif
00479
00480 }
00481
00482
00483
00484
00485 for ( unsigned int i = 0 ; i < NumServers ; ++i )
00486 {
00487
00488
00489 if ( m_finishedLog[i].initialized() )
00490 {
00491 if ( i == coord )
00492 {
00493 const SignedComputedMsg& ev =
00494 *(m_finishedLog[i].message().evidence().element(0));
00495 serverState->setDefaultLabel( &(ev.message().shareLabel()) );
00496 }
00497 break;
00498 }
00499 }
00500
00501 return true;
00502 }
00503
00504 bool
00505 SecretManagement::addInitResponse( const SignedContributeMsg& cm )
00506 {
00507 unsigned int coord = cm.message().coordinator().value();
00508 if ( ! m_initLog[coord].request().initialized() )
00509 {
00510 return false;
00511 }
00512 if ( m_initLog[coord].request().version().value() !=
00513 cm.message().version().value() )
00514 {
00515 return false;
00516 }
00517 m_initLog[coord].addResponse( cm );
00518 return true;
00519 }
00520
00521 bool
00522 SecretManagement::addEstablishResponse( const SignedEstablishedMsg& em )
00523 {
00524 unsigned int estab = em.message().establisher().value();
00525 unsigned int snum = em.message().sublabel().id().value();
00526 EstablishRecord& er =
00527 m_establishLog[ estab ][ snum ][ em.message().sublabel().label() ];
00528 if ( ! er.request().initialized() )
00529 {
00530 return false;
00531 }
00532 if ( er.request().version().value() != em.message().version().value() )
00533 {
00534 return false;
00535 }
00536 er.addResponse( em );
00537 return true;
00538 }
00539
00540 bool
00541 SecretManagement::addComputeResponse( const SignedComputedMsg& cm )
00542 {
00543 unsigned int coord = cm.message().shareLabel().id().value();
00544 if ( ! m_computeLog[ coord ].request().initialized() )
00545 {
00546 return false;
00547 }
00548 if (
00549 m_computeLog[coord].request().subshareLabel(0).label().version().value()
00550 != (cm.message().shareLabel().version().value()-1)
00551 )
00552 {
00553 return false;
00554 }
00555 m_computeLog[ coord ].addResponse( cm );
00556 return true;
00557 }
00558
00559 void
00560 SecretManagement::clearEstablishMsgs()
00561 {
00562 for ( unsigned int i = 0 ; i < NumServers ; ++i )
00563 {
00564 for ( unsigned int j = 0 ; j < NumShares ; ++j )
00565 {
00566 m_establishLog[i][j].clear();
00567 }
00568 }
00569 }
00570
00571 void
00572 SecretManagement::clearEstablishMsgs( unsigned int establisher )
00573 {
00574 for ( unsigned int i = 0 ; i < NumShares ; ++i )
00575 {
00576 m_establishLog[establisher][i].clear();
00577 }
00578 }
00579
00580 const InitRecord&
00581 SecretManagement::initRecord( unsigned int i ) const
00582 {
00583 if ( i >= NumServers )
00584 {
00585 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00586 }
00587 return m_initLog[i];
00588 }
00589
00590 const EstablishRecord&
00591 SecretManagement::establishRecord( unsigned int establisher,
00592 unsigned int shareNum,
00593 const LabelType& label ) const
00594 {
00595 if ( establisher >= NumServers )
00596 {
00597 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00598 }
00599 if ( shareNum >= NumShares )
00600 {
00601 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00602 }
00603 return m_establishLog[establisher][shareNum][label];
00604 }
00605
00606 const ComputeRecord&
00607 SecretManagement::computeRecord( unsigned int i ) const
00608 {
00609 if ( i >= NumServers )
00610 {
00611 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00612 }
00613 return m_computeLog[i];
00614 }
00615
00616 const SignedFinishedMsg&
00617 SecretManagement::finishedMsg( unsigned int i ) const
00618 {
00619 if ( i >= NumServers )
00620 {
00621 throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00622 }
00623 return m_finishedLog[i];
00624 }
00625
00626 void
00627 SecretManagement::setEpochTime()
00628 {
00629 struct timeval tv;
00630 int gtod = gettimeofday( &tv, 0 );
00631 if ( 0 != gtod )
00632 {
00633 CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ , errno );
00634 }
00635 m_epochTime = tv.tv_sec;
00636 }
00637
00638 void
00639 SecretManagement::setRunTime()
00640 {
00641 struct timeval tv;
00642 int gtod = gettimeofday( &tv, 0 );
00643 if ( 0 != gtod )
00644 {
00645 CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ , errno );
00646 }
00647 m_runTime = tv.tv_sec;
00648 }
00649
00650 unsigned long
00651 SecretManagement::elapsed( unsigned long current ) const
00652 {
00653 if ( m_epochTime > current )
00654 {
00655 return 0;
00656 }
00657 return ( current - m_epochTime );
00658 }
00659
00660 void
00661 SecretManagement::beginRun()
00662 {
00663
00664 if ( m_runTime >= m_epochTime )
00665 {
00666 return;
00667 }
00668
00669 cout << "starting a run" << endl;
00670
00671 #ifdef TIMING
00672 APSSTimer[m_num].start();
00673 InitTimer[m_num].start();
00674 ActiveTimer.start();
00675 #endif
00676
00677 CODEX_Server::ServerState* serverState =
00678 CODEX_Server::ServerState::instance();
00679 if ( 0 == serverState )
00680 {
00681 #ifdef TIMING
00682 ActiveTimer.stop();
00683 #endif
00684 return;
00685 }
00686
00687 StateInfo* stateInfo = StateInfo::instance();
00688 if ( 0 == stateInfo )
00689 {
00690 #ifdef TIMING
00691 ActiveTimer.stop();
00692 #endif
00693 return;
00694 }
00695
00696 unsigned int version = m_version + 1;
00697 unsigned int coordinator = serverState->hostNum();
00698 const LabelType& label = serverState->defaultLabel( m_num );
00699 CODEX_ASN1::Integer versionInt( version );
00700 CODEX_ASN1::Integer coordInt( coordinator );
00701 InitMsg request( version, coordinator, label );
00702
00703 BIGNUM * digest = 0;
00704 CODEX_Ciphers::RSASignature* signature = 0;
00705 try
00706 {
00707 const CODEX_Ciphers::HashFunction& hashFunc = serverState->hashFunc();
00708 digest = request.digest( hashFunc );
00709 const CODEX_Ciphers::RSAPrivateKey& key = serverState->privateKey();
00710 signature = key.sign( digest );
00711 BN_free(digest);
00712 digest = 0;
00713 if ( 0 == signature )
00714 {
00715 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00716 }
00717 }
00718 catch ( ... )
00719 {
00720 if ( 0 != digest ) BN_free( digest );
00721 if ( 0 != signature ) delete signature;
00722 #ifdef TIMING
00723 ActiveTimer.stop();
00724 #endif
00725 throw;
00726 }
00727 SignedInitMsg signedRequest( request, *signature );
00728 delete signature;
00729
00730
00731 CODEX_Quorum::Message m;
00732
00733
00734 m.fill( coordinator | CODEX_Server::ServerState::OutgoingMask );
00735 m.fill( serverState->newSequenceNumber(), CODEX_Server::ServerState::nMID );
00736 m.fill( stateInfo->domain() );
00737 m.fill( kInitMsg | SignatureMask );
00738 int length = signedRequest.marshal(0);
00739 unsigned char* buffer = new unsigned char[length];
00740 unsigned char* pBuffer = buffer;
00741 signedRequest.marshal(&pBuffer);
00742 m.fill( buffer, length );
00743 delete [] buffer;
00744
00745
00746 InitCallback* cb = new InitCallback( version, label );
00747
00748
00749 setRunTime();
00750 stateInfo->broadcast( m, cb );
00751 #ifdef TIMING
00752 ActiveTimer.stop();
00753 #endif
00754 }
00755
00757 void
00758 SecretManagement::sendFinished( unsigned int server ) const
00759 {
00760 for ( unsigned int i = 0 ; i < NumServers ; ++i )
00761 {
00762 if ( m_finishedLog[i].initialized() )
00763 {
00764 sendFinished( i, server );
00765 return;
00766 }
00767 }
00768
00769 }
00770
00771 void
00772 SecretManagement::sendFinished( unsigned int coord, unsigned int server ) const
00773 {
00774 const SignedFinishedMsg& fm = m_finishedLog[coord];
00775 if ( ! fm.initialized() )
00776 {
00777 return;
00778 }
00779
00780 StateInfo* stateInfo = StateInfo::instance();
00781 CODEX_Server::ServerState* serverState =
00782 CODEX_Server::ServerState::instance();
00783
00784 CODEX_Quorum::Message m;
00785
00786
00787 unsigned char self = serverState->hostNum();
00788 m.fill( self | CODEX_Server::ServerState::OutgoingMask );
00789
00790
00791 const unsigned char* seqNum = serverState->newSequenceNumber();
00792 m.fill( seqNum, CODEX_Server::ServerState::nMID );
00793
00794
00795 m.fill( stateInfo->domain() );
00796 m.fill( kFinishedMsg | SignatureMask );
00797
00798
00799 int length = fm.marshal(0);
00800 unsigned char* buffer = new unsigned char[length];
00801 unsigned char* pBuffer = buffer;
00802 fm.marshal(&pBuffer);
00803 m.fill( buffer, length );
00804 delete [] buffer;
00805
00806 stateInfo->sendTo( server, m );
00807 }