Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

StateInfo.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: StateInfo.cc,v 1.3 2004/05/19 15:56:25 mmarsh Exp $
00008 //
00009 // $Log: StateInfo.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:25  mmarsh
00011 // Added copyright and license statements.
00012 //
00013 // Revision 1.2  2003/11/04 22:04:05  mmarsh
00014 // General code cleanup.
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 // Constructors and destructors
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 // Configuration
00082 //=============================================================
00083 
00084 void
00085 StateInfo::configure( const CONF* conf,
00086                       const char* sec,
00087                       const string& fname )
00088 {
00089    // Grab the initial share configuration from the server.
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    // Attach the APSS share callback to the server, so that requests for
00126    // shares will be directed to the APSS package.
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    // Read the APSS refresh interval from the configuration file, specified
00134    // in seconds.
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    // For each secret, store the time (to the second) at which the current
00149    // epoch was entered.
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    // See if we're already recovering this label
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    // Create the request
00218    unsigned int version = sublabel.label().version().value() + 1;
00219    RecoverMsg request( version,
00220                        sublabel,
00221                        serverState->hostNum(),
00222                        serverState->hostNum() ); // <-- ignored by verifier
00223 
00224    // Sign the request
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    // Create the outgoing message
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    // Create the callback
00270    RecoverCallback* cb =
00271       new RecoverCallback( version, sublabel );
00272 
00273    // Broadcast the message
00274    stateInfo->broadcast( m, cb );
00275 
00276    // Make sure we don't try to recover this label again.
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 }

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