Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

InitCallback.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: InitCallback.cc,v 1.3 2004/05/19 15:56:24 mmarsh Exp $
00008 //
00009 // $Log: InitCallback.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:24  mmarsh
00011 // Added copyright and license statements.
00012 //
00013 // Revision 1.2  2003/11/04 22:31:45  mmarsh
00014 // *** empty log message ***
00015 //
00016 //
00017 
00018 #include "InitCallback.h"
00019 #include "ComputeCallback.h"
00020 #include "StateInfo.h"
00021 #include "CODEX_Server/ServerState.h"
00022 
00023 #include "CODEX_Exceptions/BignumExceptions.h"
00024 #include "CODEX_Server/ServerExceptions.h"
00025 
00026 #include "timing.h"
00027 
00028 using namespace CODEX_APSS;
00029 
00030 InitCallback::InitCallback( unsigned int version, const LabelType& label ) :
00031    m_version( version ),
00032    m_label( label ),
00033    m_completed( false )
00034 {
00035 }
00036 
00037 InitCallback::~InitCallback()
00038 {
00039 }
00040 
00041 bool
00042 InitCallback::operator()( unsigned int server, CODEX_Quorum::Message* msg )
00043 {
00044    if ( m_completed )
00045    {
00046       if ( 0 != msg ) delete msg;
00047       return true;
00048    }
00049 
00050    if ( 0 == msg )
00051    {
00052       return false;
00053    }
00054 
00055 #ifdef TIMING
00056    ActiveTimer.start();
00057 #endif
00058    CODEX_Server::ServerState* serverState =
00059       CODEX_Server::ServerState::instance();
00060    if ( 0 == serverState )
00061    {
00062       delete msg;
00063 #ifdef TIMING
00064       ActiveTimer.stop();
00065 #endif
00066       return false;
00067    }
00068 
00069    StateInfo* stateInfo = StateInfo::instance();
00070    if ( 0 == stateInfo )
00071    {
00072       delete msg;
00073 #ifdef TIMING
00074       ActiveTimer.stop();
00075 #endif
00076       return false;
00077    }
00078 
00079    CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00080    if ( 0 == qs )
00081    {
00082 #ifdef TIMING
00083       ActiveTimer.stop();
00084 #endif
00085       throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00086    }
00087 
00088    // See if we're already in the next epoch.
00089    const unsigned long epoch = stateInfo->version( m_label.num().value() );
00090    if ( epoch >= m_version )
00091    {
00092       delete msg;
00093       m_completed = true;
00094 #ifdef TIMING
00095       ActiveTimer.stop();
00096 #endif
00097       return true;
00098    }
00099 
00100    // Unmarshal the message.
00101    unsigned char* data = (unsigned char*)msg->buffer();
00102    int length = msg->length();
00103 
00104    if ( length < 2 )
00105    {
00106       delete msg;
00107 #ifdef TIMING
00108       ActiveTimer.stop();
00109 #endif
00110       return false;
00111    }
00112 
00113    if ( stateInfo->domain() != data[0] )
00114    {
00115       delete msg;
00116 #ifdef TIMING
00117       ActiveTimer.stop();
00118 #endif
00119       return false;
00120    }
00121    ++data;
00122    --length;
00123 
00124    if ( ( kContributeMsg | SignatureMask ) != data[0] )
00125    {
00126       delete msg;
00127 #ifdef TIMING
00128       ActiveTimer.stop();
00129 #endif
00130       return false;
00131    }
00132    ++data;
00133    --length;
00134 
00135    SignedContributeMsg signedResponse;
00136    if ( 0 == signedResponse.unmarshal( 0, &data, length ) )
00137    {
00138       delete msg;
00139 #ifdef TIMING
00140       ActiveTimer.stop();
00141 #endif
00142       return false;
00143    }
00144    delete msg;
00145 
00146    // Make sure the response is valid.
00147    const ContributeMsg& response = signedResponse.message();
00148 
00149    unsigned int contributor = response.contributor().value();
00150    if ( contributor != server )
00151    {
00152 #ifdef TIMING
00153       ActiveTimer.stop();
00154 #endif
00155       return false;
00156    }
00157 
00158    // Check the signature.
00159    BIGNUM * digest = 0;
00160    try
00161    {
00162       digest = response.digest( serverState->hashFunc() );
00163       if ( 0 == digest )
00164       {
00165          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00166       }
00167       if ( ! serverState->publicKey(server).verifySignature(
00168          signedResponse.signature(),
00169          digest ) )
00170       {
00171          throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00172                                                                    __LINE__ );
00173       }
00174       BN_free(digest);
00175    }
00176    catch ( ... )
00177    {
00178       if ( 0 != digest ) BN_free(digest);
00179 #ifdef TIMING
00180       ActiveTimer.stop();
00181 #endif
00182       return false;
00183    }
00184 
00185    // Check the validity of all the established messages.
00186    unsigned int coordinator = serverState->hostNum();
00187    unsigned int num = m_label.num().value();
00188    OneWay oneWay( stateInfo->witness(num).args() );
00189    const EstablishedArray& evidence = response.evidence();
00190    EstablishedArray::ArrayItr itr = evidence.begin();
00191    EstablishedArray::ArrayItr end = evidence.end();
00192    SublabelType currentSublabel;
00193    unsigned int shareIndex = 0;
00194    unsigned int sublabelCount = 0;
00195    bool badSublabel = true; // Initial sublabel is uninitialized
00196    for ( ; itr != end ; ++itr )
00197    {
00198       const SublabelType& sl = (*itr)->message().sublabel();
00199       if ( sl != currentSublabel )
00200       {
00201          badSublabel = false;
00202          currentSublabel = sl;
00203          sublabelCount = 0;
00204          shareIndex = sl.id().value();
00205          if ( shareIndex >= ShareType::NumShares )
00206          {
00207 #ifdef TIMING
00208             ActiveTimer.stop();
00209 #endif
00210             throw CODEX_Exceptions::IllegalIndexException( __FILE__ ,
00211                                                            __LINE__ );
00212          }
00213          // Test the validity of the subsharing w.r.t. the purported share.
00214          if ( ! sl.verify( oneWay ) )
00215          {
00216             badSublabel = true;
00217          }
00218       }
00219 
00220       if ( badSublabel )
00221       {
00222          continue;
00223       }
00224 
00225       // Have we already selected a subsharing for this share?
00226       if ( m_subshareLabels[ shareIndex ].initialized() )
00227       {
00228          continue;
00229       }
00230 
00231       // Check validity of this message (version and signature)
00232       unsigned int slVersion = (*itr)->message().version().value();
00233       if ( slVersion != m_version )
00234       {
00235          continue;
00236       }
00237 
00238       digest = 0;
00239       try
00240       {
00241          digest = (*itr)->message().digest( serverState->hashFunc() );
00242          if ( 0 == digest )
00243          {
00244             throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00245          }
00246          if ( ! serverState->publicKey(
00247             (*itr)->message().recipient().value()).verifySignature(
00248             (*itr)->signature(),
00249             digest ) )
00250          {
00251             throw
00252                CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00253                                                                    __LINE__ );
00254          }
00255          BN_free(digest);
00256       }
00257       catch ( ... )
00258       {
00259          if ( 0 != digest ) BN_free(digest);
00260          continue;
00261       }
00262 
00263       ++sublabelCount;
00264       if ( sublabelCount >= qs->quorumSize() )
00265       {
00266          m_subshareLabels[ shareIndex ] = currentSublabel;
00267       }
00268    }
00269 
00270    // This is equivalent to testing for T+1 valid responses.
00271    bool haveAll = true;
00272    for ( unsigned int i = 0 ;
00273          haveAll && ( i < ShareType::NumShares ) ;
00274          ++i )
00275    {
00276       // See if any share does not yet have a selected subsharing.
00277       if ( ! m_subshareLabels[i].initialized() )
00278       {
00279          haveAll = false;
00280       }
00281    }
00282 
00283    if ( haveAll )
00284    {
00285       // Compute the new label.
00286       LabelType::VType::ValueType labelVals[ ShareType::NumShares ];
00287       LabelType::VType vr( oneWay );
00288       for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00289       {
00290          // Compute the label
00291          LabelType::VType::ValueType sublabelVals[ ShareType::NumShares ];
00292          for ( unsigned int j = 0 ; j < ShareType::NumShares ; ++j )
00293          {
00294             sublabelVals[j] = m_subshareLabels[j].vc(i);
00295          }
00296          vr( sublabelVals, labelVals[i] );
00297       }
00298       LabelType newLabel( num, m_version, coordinator, labelVals );
00299 
00300       // Compose the finished message.
00301       ComputeMsg cm( coordinator, m_subshareLabels );
00302 
00303       // Sign the finished message.
00304       digest = 0;
00305       CODEX_Ciphers::RSASignature* signature = 0;
00306       try
00307       {
00308          const CODEX_Ciphers::HashFunction& hashFunc = serverState->hashFunc();
00309          digest = cm.digest( hashFunc );
00310          const CODEX_Ciphers::RSAPrivateKey& key = serverState->privateKey();
00311          signature = key.sign( digest );
00312          BN_free(digest);
00313          digest = 0;
00314          if ( 0 == signature )
00315          {
00316             throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00317          }
00318       }
00319       catch ( ... )
00320       {
00321          if ( 0 != digest ) BN_free( digest );
00322          if ( 0 != signature ) delete signature;
00323 #ifdef TIMING
00324          ActiveTimer.stop();
00325 #endif
00326          throw;
00327       }
00328       SignedComputeMsg signedCM( cm, *signature );
00329       delete signature;
00330 
00331       // Create the marshalled message.
00332       CODEX_Quorum::Message m;
00333       m.fill( serverState->hostNum() |
00334               CODEX_Server::ServerState::OutgoingMask );
00335       const unsigned char* seqNum = serverState->newSequenceNumber();
00336       m.fill( seqNum, CODEX_Server::ServerState::nMID );
00337       m.fill( stateInfo->domain() );
00338       m.fill( kComputeMsg | SignatureMask );
00339       int length = signedCM.marshal(0);
00340       unsigned char* buffer = new unsigned char[length];
00341       unsigned char* pBuffer = buffer;
00342       signedCM.marshal(&pBuffer);
00343       m.fill( buffer, length );
00344       delete [] buffer;
00345 
00346       ComputeCallback* cb = new ComputeCallback( newLabel );
00347 
00348       // Broadcast compute message.
00349       stateInfo->broadcast( m, cb );
00350 
00351       m_completed = true;
00352 
00353 #ifdef TIMING
00354       InitTimer[num].stop();
00355       ComputeTimer[num].start();
00356 #endif
00357 
00358    }
00359 
00360 #ifdef TIMING
00361    ActiveTimer.stop();
00362 #endif
00363    return true;
00364 }

Generated on Fri May 6 17:39:58 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1