00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
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
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
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
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;
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
00214 if ( ! sl.verify( oneWay ) )
00215 {
00216 badSublabel = true;
00217 }
00218 }
00219
00220 if ( badSublabel )
00221 {
00222 continue;
00223 }
00224
00225
00226 if ( m_subshareLabels[ shareIndex ].initialized() )
00227 {
00228 continue;
00229 }
00230
00231
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
00271 bool haveAll = true;
00272 for ( unsigned int i = 0 ;
00273 haveAll && ( i < ShareType::NumShares ) ;
00274 ++i )
00275 {
00276
00277 if ( ! m_subshareLabels[i].initialized() )
00278 {
00279 haveAll = false;
00280 }
00281 }
00282
00283 if ( haveAll )
00284 {
00285
00286 LabelType::VType::ValueType labelVals[ ShareType::NumShares ];
00287 LabelType::VType vr( oneWay );
00288 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00289 {
00290
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
00301 ComputeMsg cm( coordinator, m_subshareLabels );
00302
00303
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
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
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 }