00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "MessageVerifier.h"
00019 #include "StateInfo.h"
00020 #include "CODEX_Server/ServerResponseEvent.h"
00021 #include "FailureEvent.h"
00022
00023 #include "timing.h"
00024
00025 using namespace CODEX_APSS;
00026
00027 MessageVerifier::MessageVerifier(
00028 CODEX_Events::DeadPileType& deadPile,
00029 CODEX_Events::QType& eventQueue,
00030 RoutedMessageHandler* destination,
00031 CODEX_Server::ServerResponseHandler* responder ) :
00032 CODEX_Events::Activity( deadPile, eventQueue ),
00033 m_destination( destination ),
00034 m_responder( responder )
00035 {
00036 }
00037
00038 MessageVerifier::~MessageVerifier()
00039 {
00040 }
00041
00045 bool
00046 MessageVerifier::handler( RoutedMessageEvent< SignedInitMsg >& event )
00047 {
00048 #ifdef TIMING
00049 ActiveTimer.start();
00050 #endif
00051 StateInfo* stateInfo = StateInfo::instance();
00052 CODEX_Server::ServerState* serverState =
00053 CODEX_Server::ServerState::instance();
00054 const SignedInitMsg& signedMessage = event.message();
00055 const InitMsg& message = signedMessage.message();
00056 unsigned int coordinator = message.coordinator().value();
00057
00058 BIGNUM * digest = 0;
00059 try
00060 {
00061 const CODEX_Ciphers::RSAPublicKey& serverKey =
00062 serverState->publicKey( coordinator );
00063
00064
00065 digest = message.digest( serverState->hashFunc() );
00066 if ( ! serverKey.verifySignature( signedMessage.signature(), digest ) )
00067 {
00068 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00069 __LINE__ );
00070 }
00071 BN_free( digest ); digest = 0;
00072
00073
00074 unsigned int num = message.label().num().value();
00075 unsigned int version = message.version().value();
00076 if ( version < stateInfo->version(num) )
00077 {
00078 stateInfo->sendFinished( num, coordinator );
00079 sendEvent( new FailureEvent( this, m_responder, event ),
00080 event.source(), true );
00081 #ifdef TIMING
00082 ActiveTimer.stop();
00083 #endif
00084 return true;
00085 }
00086
00087
00088 const InitRecord& priorInit = stateInfo->initRecord( num, coordinator );
00089 if ( priorInit.request().initialized() )
00090 {
00091 unsigned int pVersion = priorInit.request().version().value();
00092 if ( pVersion == version )
00093 {
00094 if ( priorInit.request().label() != message.label() )
00095 {
00096
00097
00098 sendEvent( 0, event.source(), true );
00099 #ifdef TIMING
00100 ActiveTimer.stop();
00101 #endif
00102 return true;
00103 }
00104
00105 if ( priorInit.response().initialized() )
00106 {
00107
00108 CODEX_Quorum::Message m;
00109 unsigned char server[CODEX_Server::ServerState::nSID];
00110 memcpy( server,
00111 event.server(),
00112 CODEX_Server::ServerState::nSID );
00113
00114 server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00115 int serverNum = server[0];
00116
00117
00118 m.fill( server, CODEX_Server::ServerState::nSID );
00119 m.fill( event.seqNum(), CODEX_Server::ServerState::nMID );
00120 m.fill( stateInfo->domain() );
00121 m.fill( kContributeMsg | SignatureMask );
00122 const SignedContributeMsg& cm = priorInit.response();
00123 int length = cm.marshal(0);
00124 unsigned char* buffer = new unsigned char[length];
00125 unsigned char* pBuffer = buffer;
00126 cm.marshal(&pBuffer);
00127 m.fill( buffer, length );
00128 delete [] buffer;
00129
00130 sendEvent(
00131 new CODEX_Server::ServerResponseEvent( this,
00132 m_responder,
00133 m,
00134 serverNum ),
00135 event.source() );
00136 #ifdef TIMING
00137 ActiveTimer.stop();
00138 #endif
00139 return true;
00140 }
00141 else
00142 {
00143
00144 sendEvent( 0, event.source() );
00145 #ifdef TIMING
00146 ActiveTimer.stop();
00147 #endif
00148 return true;
00149 }
00150 }
00151 }
00152
00153
00154 if ( ( message.version().value() -
00155 message.label().version().value() ) != 1 )
00156 {
00157 sendEvent( 0, event.source(), true );
00158 #ifdef TIMING
00159 ActiveTimer.stop();
00160 #endif
00161 return true;
00162 }
00163
00164
00165 stateInfo->addInitMsg( signedMessage );
00166 event.reRoute( m_destination );
00167 #ifdef TIMING
00168 InitActTimer[num].start();
00169 ActiveTimer.stop();
00170 #endif
00171 return false;
00172 }
00173 catch ( ... )
00174 {
00175 if ( 0 != digest ) BN_free( digest );
00176 sendEvent( 0, event.source(), true );
00177 #ifdef TIMING
00178 ActiveTimer.stop();
00179 #endif
00180 return true;
00181 }
00182 }
00183
00187 bool
00188 MessageVerifier::handler( RoutedMessageEvent< SignedEstablishMsg >& event )
00189 {
00190 #ifdef TIMING
00191 ActiveTimer.start();
00192 #endif
00193 StateInfo* stateInfo = StateInfo::instance();
00194 CODEX_Server::ServerState* serverState =
00195 CODEX_Server::ServerState::instance();
00196 const SignedEstablishMsg& signedMessage = event.message();
00197 const EstablishMsg& message = signedMessage.message();
00198 unsigned int establisher = message.establisher().value();
00199
00200 BIGNUM * digest = 0;
00201 try
00202 {
00203 const CODEX_Ciphers::RSAPublicKey& serverKey =
00204 serverState->publicKey( establisher );
00205
00206 const CODEX_Ciphers::HashFunction& hashFunc = serverState->hashFunc();
00207
00208
00209 digest = message.digest( hashFunc );
00210 if ( ! serverKey.verifySignature( signedMessage.signature(), digest ) )
00211 {
00212 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00213 __LINE__ );
00214 }
00215 BN_free( digest ); digest = 0;
00216
00217
00218 unsigned int num = message.sublabel().label().num().value();
00219 unsigned int version = message.version().value();
00220 if ( version < stateInfo->version(num) )
00221 {
00222 stateInfo->sendFinished( num, establisher );
00223 sendEvent( new FailureEvent( this, m_responder, event ),
00224 event.source(), true );
00225 #ifdef TIMING
00226 ActiveTimer.stop();
00227 #endif
00228 return true;
00229 }
00230
00231
00232 const EstablishRecord& priorEst =
00233 stateInfo->establishRecord( num,
00234 establisher,
00235 message.sublabel().id().value(),
00236 message.sublabel().label() );
00237 if ( priorEst.request().initialized() )
00238 {
00239 unsigned int pVersion = priorEst.request().version().value();
00240 if ( pVersion == version )
00241 {
00242 if ( priorEst.request().sublabel() != message.sublabel() )
00243 {
00244
00245
00246 sendEvent( 0, event.source(), true );
00247 #ifdef TIMING
00248 ActiveTimer.stop();
00249 #endif
00250 return true;
00251 }
00252
00253 if ( priorEst.response().initialized() )
00254 {
00255
00256 CODEX_Quorum::Message m;
00257 unsigned char server[CODEX_Server::ServerState::nSID];
00258 memcpy( server,
00259 event.server(),
00260 CODEX_Server::ServerState::nSID );
00261
00262 server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00263 int serverNum = server[0];
00264
00265
00266 m.fill( server, CODEX_Server::ServerState::nSID );
00267 m.fill( event.seqNum(), CODEX_Server::ServerState::nMID );
00268 m.fill( stateInfo->domain() );
00269 m.fill( kEstablishedMsg | SignatureMask );
00270 const SignedEstablishedMsg& em = priorEst.response();
00271 int length = em.marshal(0);
00272 unsigned char* buffer = new unsigned char[length];
00273 unsigned char* pBuffer = buffer;
00274 em.marshal(&pBuffer);
00275 m.fill( buffer, length );
00276 delete [] buffer;
00277
00278 sendEvent(
00279 new CODEX_Server::ServerResponseEvent( this,
00280 m_responder,
00281 m,
00282 serverNum ),
00283 event.source() );
00284 #ifdef TIMING
00285 ActiveTimer.stop();
00286 #endif
00287 return true;
00288 }
00289 else
00290 {
00291
00292 sendEvent( 0, event.source() );
00293 #ifdef TIMING
00294 ActiveTimer.stop();
00295 #endif
00296 return true;
00297 }
00298 }
00299 }
00300
00301 OneWay oneWay( stateInfo->witness(num).args() );
00302
00303
00304 if ( ! message.sublabel().label().verify(
00305 stateInfo->witness(num).witness(), oneWay ) )
00306 {
00307 sendEvent( 0, event.source(), true );
00308 #ifdef TIMING
00309 ActiveTimer.stop();
00310 #endif
00311 return true;
00312 }
00313
00314
00315 if ( ! message.sublabel().verify( oneWay ) )
00316 {
00317 sendEvent( 0, event.source(), true );
00318 #ifdef TIMING
00319 ActiveTimer.stop();
00320 #endif
00321 return true;
00322 }
00323
00324
00325 if ( ! message.sublabel().check(message.shares(),oneWay) )
00326 {
00327 sendEvent( 0, event.source(), true );
00328 #ifdef TIMING
00329 ActiveTimer.stop();
00330 #endif
00331 return true;
00332 }
00333
00334
00335 stateInfo->addEstablishMsg( signedMessage );
00336 event.reRoute( m_destination );
00337 #ifdef TIMING
00338 ActiveTimer.stop();
00339 #endif
00340 return false;
00341 }
00342 catch ( ... )
00343 {
00344 if ( 0 != digest ) BN_free( digest );
00345 sendEvent( 0, event.source(), true );
00346 #ifdef TIMING
00347 ActiveTimer.stop();
00348 #endif
00349 return true;
00350 }
00351 }
00352
00356 bool
00357 MessageVerifier::handler( RoutedMessageEvent< SignedComputeMsg >& event )
00358 {
00359 #ifdef TIMING
00360 ActiveTimer.start();
00361 #endif
00362 StateInfo* stateInfo = StateInfo::instance();
00363 CODEX_Server::ServerState* serverState =
00364 CODEX_Server::ServerState::instance();
00365 const SignedComputeMsg& signedMessage = event.message();
00366 const ComputeMsg& message = signedMessage.message();
00367 unsigned int coordinator = message.coordinator().value();
00368
00369 BIGNUM * digest = 0;
00370 try
00371 {
00372 const CODEX_Ciphers::RSAPublicKey& serverKey =
00373 serverState->publicKey( coordinator );
00374
00375
00376 digest = message.digest( serverState->hashFunc() );
00377 if ( ! serverKey.verifySignature( signedMessage.signature(), digest ) )
00378 {
00379 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00380 __LINE__ );
00381 }
00382 BN_free( digest ); digest = 0;
00383
00384
00385 unsigned int num = message.subshareLabel(0).label().num().value();
00386 unsigned int version =
00387 message.subshareLabel(0).label().version().value();
00388 if ( version < stateInfo->version(num) )
00389 {
00390 stateInfo->sendFinished( num, coordinator );
00391 sendEvent( new FailureEvent( this, m_responder, event ),
00392 event.source(), true );
00393 #ifdef TIMING
00394 ActiveTimer.stop();
00395 #endif
00396 return true;
00397 }
00398
00399
00400 const ComputeRecord& priorComp = stateInfo->computeRecord( num,
00401 coordinator );
00402 if ( priorComp.request().initialized() )
00403 {
00404 unsigned int pVersion =
00405 priorComp.request().subshareLabel(0).label().version().value();
00406 if ( pVersion == version )
00407 {
00408 for ( unsigned int i = 0 ; i < ComputeMsg::NumShares ; ++i )
00409 {
00410 if ( priorComp.request().subshareLabel(i) !=
00411 message.subshareLabel(i) )
00412 {
00413
00414
00415 sendEvent( 0, event.source(), true );
00416 #ifdef TIMING
00417 ActiveTimer.stop();
00418 #endif
00419 return true;
00420 }
00421 }
00422
00423 if ( priorComp.response().initialized() )
00424 {
00425
00426 CODEX_Quorum::Message m;
00427 unsigned char server[CODEX_Server::ServerState::nSID];
00428 memcpy( server,
00429 event.server(),
00430 CODEX_Server::ServerState::nSID );
00431
00432 server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00433 int serverNum = server[0];
00434
00435
00436 m.fill( server, CODEX_Server::ServerState::nSID );
00437 m.fill( event.seqNum(), CODEX_Server::ServerState::nMID );
00438 m.fill( stateInfo->domain() );
00439 m.fill( kComputedMsg | SignatureMask );
00440 const SignedComputedMsg& cm = priorComp.response();
00441 int length = cm.marshal(0);
00442 unsigned char* buffer = new unsigned char[length];
00443 unsigned char* pBuffer = buffer;
00444 cm.marshal(&pBuffer);
00445 m.fill( buffer, length );
00446 delete [] buffer;
00447
00448 sendEvent(
00449 new CODEX_Server::ServerResponseEvent( this,
00450 m_responder,
00451 m,
00452 serverNum ),
00453 event.source() );
00454 #ifdef TIMING
00455 ActiveTimer.stop();
00456 #endif
00457 return true;
00458 }
00459 else
00460 {
00461
00462 sendEvent( 0, event.source() );
00463 #ifdef TIMING
00464 ActiveTimer.stop();
00465 #endif
00466 return true;
00467 }
00468 }
00469 }
00470
00471
00472 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00473 {
00474 unsigned int id = message.subshareLabel(i).id().value();
00475 if ( id != i )
00476 {
00477 sendEvent( 0, event.source(), true );
00478 #ifdef TIMING
00479 ActiveTimer.stop();
00480 #endif
00481 return true;
00482 }
00483 }
00484
00485
00486 stateInfo->addComputeMsg( signedMessage );
00487 event.reRoute( m_destination );
00488 #ifdef TIMING
00489 ActiveTimer.stop();
00490 #endif
00491 return false;
00492 }
00493 catch ( ... )
00494 {
00495 if ( 0 != digest ) BN_free( digest );
00496 sendEvent( 0, event.source(), true );
00497 #ifdef TIMING
00498 ActiveTimer.stop();
00499 #endif
00500 return true;
00501 }
00502 }
00503
00504 bool
00505 MessageVerifier::handler( RoutedMessageEvent< SignedRecoverMsg >& event )
00506 {
00507 #ifdef TIMING
00508 ActiveTimer.start();
00509 #endif
00510 StateInfo* stateInfo = StateInfo::instance();
00511 CODEX_Server::ServerState* serverState =
00512 CODEX_Server::ServerState::instance();
00513 const SignedRecoverMsg& signedMessage = event.message();
00514 const RecoverMsg& message = signedMessage.message();
00515 unsigned int requester = message.requester().value();
00516
00517 BIGNUM * digest = 0;
00518 try
00519 {
00520 const CODEX_Ciphers::RSAPublicKey& serverKey =
00521 serverState->publicKey( requester );
00522
00523
00524 digest = message.digest( serverState->hashFunc() );
00525 if ( ! serverKey.verifySignature( signedMessage.signature(), digest ) )
00526 {
00527 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00528 __LINE__ );
00529 }
00530 BN_free( digest ); digest = 0;
00531
00532
00533 unsigned int num = message.sublabel().label().num().value();
00534 unsigned int version = message.version().value();
00535 if ( version < stateInfo->version(num) )
00536 {
00537 stateInfo->sendFinished( num, requester );
00538 sendEvent( new FailureEvent( this, m_responder, event ),
00539 event.source(), true );
00540 #ifdef TIMING
00541 ActiveTimer.stop();
00542 #endif
00543 return true;
00544 }
00545
00546
00547 event.reRoute( m_destination );
00548 #ifdef TIMING
00549 ActiveTimer.stop();
00550 #endif
00551 return false;
00552 }
00553 catch ( ... )
00554 {
00555 if ( 0 != digest ) BN_free( digest );
00556 sendEvent( 0, event.source(), true );
00557 #ifdef TIMING
00558 ActiveTimer.stop();
00559 #endif
00560 return true;
00561 }
00562 }
00563
00564 bool
00565 MessageVerifier::handler( RoutedMessageEvent< SignedFinishedMsg >& event )
00566 {
00567 #ifdef TIMING
00568 ActiveTimer.start();
00569 #endif
00570 StateInfo* stateInfo = StateInfo::instance();
00571 CODEX_Server::ServerState* serverState =
00572 CODEX_Server::ServerState::instance();
00573 const SignedFinishedMsg& signedMessage = event.message();
00574 const FinishedMsg& message = signedMessage.message();
00575 unsigned int coordinator = message.coordinator().value();
00576
00577 BIGNUM * digest = 0;
00578 try
00579 {
00580 const CODEX_Ciphers::RSAPublicKey& serverKey =
00581 serverState->publicKey( coordinator );
00582
00583
00584 digest = message.digest( serverState->hashFunc() );
00585 if ( ! serverKey.verifySignature( signedMessage.signature(), digest ) )
00586 {
00587 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00588 __LINE__ );
00589 }
00590 BN_free( digest ); digest = 0;
00591
00592
00593 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00594 if ( 0 == qs )
00595 {
00596 throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00597 }
00598 unsigned int quorumSize = qs->quorumSize();
00599 if ( message.evidence().size() < quorumSize )
00600 {
00601 sendEvent( 0, event.source(), true );
00602 #ifdef TIMING
00603 ActiveTimer.stop();
00604 #endif
00605 return true;
00606 }
00607
00608
00609
00610 unsigned int num =
00611 message.evidence().element(0)->message().shareLabel().num().value();
00612 unsigned int version = message.version().value();
00613 if ( version < stateInfo->version(num) )
00614 {
00615 sendEvent( new FailureEvent( this, m_responder, event ),
00616 event.source(), true );
00617 #ifdef TIMING
00618 ActiveTimer.stop();
00619 #endif
00620 return true;
00621 }
00622 unsigned int coord = message.coordinator().value();
00623 const SignedFinishedMsg& fm = stateInfo->finishedMsg( num, coord );
00624 if ( fm.message().initialized() )
00625 {
00626 unsigned int pVers = fm.message().version().value();
00627 if ( version <= pVers )
00628 {
00629
00630 sendEvent( 0, event.source() );
00631 #ifdef TIMING
00632 ActiveTimer.stop();
00633 #endif
00634 return true;
00635 }
00636 }
00637
00638
00639 ComputedArray::ArrayItr itr = message.evidence().begin();
00640 ComputedArray::ArrayItr end = message.evidence().end();
00641 for ( ; itr != end ; ++itr )
00642 {
00643 const ComputedMsg& cm = (*itr)->message();
00644
00645
00646 unsigned int eCoord = cm.shareLabel().id().value();
00647 if ( eCoord != coordinator )
00648 {
00649 sendEvent( 0, event.source(), true );
00650 #ifdef TIMING
00651 ActiveTimer.stop();
00652 #endif
00653 return true;
00654 }
00655
00656
00657
00658 unsigned int eVers = cm.shareLabel().version().value();
00659 if ( eVers != version )
00660 {
00661 sendEvent( 0, event.source(), true );
00662 #ifdef TIMING
00663 ActiveTimer.stop();
00664 #endif
00665 return true;
00666 }
00667
00668
00669 unsigned int s = cm.computor().value();
00670 digest = cm.digest( serverState->hashFunc() );
00671 if ( ! serverState->publicKey(s).verifySignature( (*itr)->signature(),
00672 digest ) )
00673 {
00674 throw
00675 CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00676 __LINE__ );
00677 }
00678 BN_free( digest ); digest = 0;
00679 }
00680
00681 #ifdef TIMING
00682
00683
00684 ActiveTimer.stop();
00685 #endif
00686
00687 stateInfo->addFinishedMsg( signedMessage );
00688 return false;
00689 }
00690 catch ( ... )
00691 {
00692 if ( 0 != digest ) BN_free( digest );
00693 sendEvent( 0, event.source(), true );
00694 #ifdef TIMING
00695 ActiveTimer.stop();
00696 #endif
00697 return true;
00698 }
00699 }