00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "DelegateResponseVerifier.h"
00019 #include "CODEX_Server/ServerResponseEvent.h"
00020 #include "CODEX_Server/ServerState.h"
00021 #include "StateInfo.h"
00022 #include "ClientDelegation.h"
00023 #include "VerifiableBlindKeyMsg.h"
00024
00025 #include "CODEX_Server/ServerExceptions.h"
00026 #include "Exceptions.h"
00027
00028 #include "timing.h"
00029
00030 using namespace CODEX_KeyService;
00031
00032 DelegateResponseVerifier::DelegateResponseVerifier(
00033 CODEX_Events::DeadPileType& deadPile,
00034 CODEX_Events::QType& eventQueue,
00035 SupportedClientResponseHandler* destination ):
00036 CODEX_Events::Activity( deadPile, eventQueue ),
00037 m_destination( destination )
00038 {
00039 }
00040
00041 DelegateResponseVerifier::~DelegateResponseVerifier()
00042 {
00043 }
00044
00045 bool
00046 DelegateResponseVerifier::handler(
00047 SupportedClientResponseEvent< BoundNameMsg, SignedCreateKeyMsg >& event )
00048 {
00049 #ifdef TIMING
00050 ActiveTimer.start();
00051 #endif
00052 const BoundNameMsg& response = event.message().response();
00053 const CreateKeyMsg& request = response.request().message();
00054
00055
00056
00057
00058 const SignedCreateKeyMsg& sRequest = event.message().request();
00059
00060 if ( response.name().value() != request.name().value() )
00061 {
00062 #ifdef TIMING
00063 ActiveTimer.stop();
00064 #endif
00065 return true;
00066 }
00067 if ( request.name().value() != sRequest.message().name().value() )
00068 {
00069 #ifdef TIMING
00070 ActiveTimer.stop();
00071 #endif
00072 return true;
00073 }
00074
00075
00076 if ( 0 != BN_cmp( response.request().signature().value(),
00077 sRequest.signature().value() ) )
00078 {
00079 #ifdef TIMING
00080 ActiveTimer.stop();
00081 #endif
00082 return true;
00083 }
00084
00085
00086 CODEX_Server::ServerState* serverState =
00087 CODEX_Server::ServerState::instance();
00088 if ( 0 == serverState )
00089 {
00090 #ifdef TIMING
00091 ActiveTimer.stop();
00092 #endif
00093 return true;
00094 }
00095
00096 StateInfo* stateInfo = StateInfo::instance();
00097 if ( 0 == stateInfo )
00098 {
00099 #ifdef TIMING
00100 ActiveTimer.stop();
00101 #endif
00102 return true;
00103 }
00104
00105
00106
00107
00108 CODEX_Ciphers::RSAPublicKey ownerKey( request.owner().value() );
00109 BIGNUM * digest = 0;
00110 try
00111 {
00112 digest = request.digest( serverState->hashFunc() );
00113 bool sigOK = ownerKey.verifySignature( response.request().signature(),
00114 digest );
00115 BN_free(digest);
00116 digest = 0;
00117 if ( ! sigOK )
00118 {
00119 #ifdef TIMING
00120 ActiveTimer.stop();
00121 #endif
00122 return true;
00123 }
00124 }
00125 catch ( ... )
00126 {
00127 if ( 0 != digest ) BN_free(digest);
00128 #ifdef TIMING
00129 ActiveTimer.stop();
00130 #endif
00131 throw;
00132 }
00133
00134
00135 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00136 if ( 0 == qs )
00137 {
00138 #ifdef TIMING
00139 ActiveTimer.stop();
00140 #endif
00141 return true;
00142 }
00143
00144
00145 try
00146 {
00147 digest = sRequest.digest( serverState->hashFunc() );
00148 }
00149 catch ( ... )
00150 {
00151 if ( 0 != digest ) BN_free(digest);
00152 #ifdef TIMING
00153 ActiveTimer.stop();
00154 #endif
00155 return true;
00156 }
00157 if ( 0 == digest )
00158 {
00159 #ifdef TIMING
00160 ActiveTimer.stop();
00161 #endif
00162 return true;
00163 }
00164
00165 bool retVal =
00166 process( digest, event.message().evidence(), qs->quorumSize() );
00167
00168 BN_free(digest);
00169
00170 if ( retVal )
00171 {
00172
00173
00174
00175 const KeyInfo* keyInfo =
00176 stateInfo->getKeyInfo( response.name().value() );
00177 if ( 0 == keyInfo )
00178 {
00179 if ( ! stateInfo->addKeyName( response.name().value(), response ) )
00180 {
00181 #ifdef TIMING
00182 ActiveTimer.stop();
00183 #endif
00184 throw KeyExistsException( __FILE__ , __LINE__ );
00185 }
00186 }
00187 else
00188 {
00189
00190
00191 if ( ! stateInfo->replaceKeyBinding(
00192 response.name().value(),
00193 CODEX_Client::SignedBoundNameMsg(
00194 response,
00195 CODEX_Ciphers::RSASignature() ) ) )
00196 {
00197 #ifdef TIMING
00198 ActiveTimer.stop();
00199 #endif
00200 throw KeyNotFoundException( __FILE__ , __LINE__ );
00201 }
00202 }
00203
00204 event.reRoute( m_destination );
00205 }
00206 else
00207 {
00208 sendEvent( 0, event.source(), true );
00209 }
00210 #ifdef TIMING
00211 ActiveTimer.stop();
00212 #endif
00213 return (!retVal);
00214 }
00215
00216 bool
00217 DelegateResponseVerifier::handler(
00218 SupportedClientResponseEvent< KeyStoredMsg, SignedWriteKeyMsg >& event )
00219 {
00220 #ifdef TIMING
00221 ActiveTimer.start();
00222 #endif
00223 const KeyStoredMsg& response = event.message().response();
00224
00225
00226
00227 const SignedWriteKeyMsg& request = event.message().request();
00228 if ( response.name().value() != request.message().name().value() )
00229 {
00230 #ifdef TIMING
00231 ActiveTimer.stop();
00232 #endif
00233 return true;
00234 }
00235
00236
00237 if ( 0 != BN_cmp( response.requestSignature().value(),
00238 request.signature().value() ) )
00239 {
00240 #ifdef TIMING
00241 ActiveTimer.stop();
00242 #endif
00243 return true;
00244 }
00245
00246
00247 CODEX_Server::ServerState* serverState =
00248 CODEX_Server::ServerState::instance();
00249 if ( 0 == serverState )
00250 {
00251 #ifdef TIMING
00252 ActiveTimer.stop();
00253 #endif
00254 return true;
00255 }
00256
00257 StateInfo* stateInfo = StateInfo::instance();
00258 if ( 0 == stateInfo )
00259 {
00260 #ifdef TIMING
00261 ActiveTimer.stop();
00262 #endif
00263 return true;
00264 }
00265
00266
00267 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00268 if ( 0 == qs )
00269 {
00270 #ifdef TIMING
00271 ActiveTimer.stop();
00272 #endif
00273 return true;
00274 }
00275
00276
00277 BIGNUM * digest = 0;
00278 try
00279 {
00280 digest = request.digest( serverState->hashFunc() );
00281 }
00282 catch ( ... )
00283 {
00284 if ( 0 != digest ) BN_free(digest);
00285 #ifdef TIMING
00286 ActiveTimer.stop();
00287 #endif
00288 return true;
00289 }
00290 if ( 0 == digest )
00291 {
00292 #ifdef TIMING
00293 ActiveTimer.stop();
00294 #endif
00295 return true;
00296 }
00297
00298 bool retVal =
00299 process( digest, event.message().evidence(), qs->quorumSize() );
00300
00301 BN_free( digest );
00302
00303 if ( retVal )
00304 {
00305
00306
00307
00308 const KeyInfo* keyInfo =
00309 stateInfo->getKeyInfo( request.message().name().value() );
00310 if ( 0 == keyInfo )
00311 {
00312 if ( ! stateInfo->addKeyName( response.name().value(),
00313 request.message().binding() ) )
00314 {
00315 #ifdef TIMING
00316 ActiveTimer.stop();
00317 #endif
00318 throw KeyExistsException( __FILE__ , __LINE__ );
00319 }
00320 if ( ! stateInfo->addKeyValue( response.name().value(),
00321 request.message().encryption() ) )
00322 {
00323 #ifdef TIMING
00324 ActiveTimer.stop();
00325 #endif
00326 throw KeyNotFoundException( __FILE__ , __LINE__ );
00327 }
00328 }
00329 else
00330 {
00331
00332
00333 if ( ! ( keyInfo->keyValue().initialized() &&
00334 ( keyInfo->keyValue() == request.message().encryption() ) ) )
00335 {
00336 if ( ! stateInfo->addKeyValue( response.name().value(),
00337 request.message().encryption() ) )
00338 {
00339 #ifdef TIMING
00340 ActiveTimer.stop();
00341 #endif
00342 throw KeyNotFoundException( __FILE__ , __LINE__ );
00343 }
00344 }
00345 }
00346
00347 if ( ! stateInfo->verifyKeyValue( response.name().value() ) )
00348 {
00349 #ifdef TIMING
00350 ActiveTimer.stop();
00351 #endif
00352 throw KeyNotFoundException( __FILE__ , __LINE__ );
00353 }
00354
00355 event.reRoute( m_destination );
00356 }
00357 else
00358 {
00359 sendEvent( 0, event.source(), true );
00360 }
00361 #ifdef TIMING
00362 ActiveTimer.stop();
00363 #endif
00364 return (!retVal);
00365 }
00366
00367 bool
00368 DelegateResponseVerifier::handler( SupportedKeyStoredEvent& event )
00369 {
00370 #ifdef TIMING
00371 ActiveTimer.start();
00372 #endif
00373 const KeyStoredMsg& response = event.message().response();
00374
00375
00376 CODEX_Server::ServerState* serverState =
00377 CODEX_Server::ServerState::instance();
00378 if ( 0 == serverState )
00379 {
00380 #ifdef TIMING
00381 ActiveTimer.stop();
00382 #endif
00383 return true;
00384 }
00385
00386 StateInfo* stateInfo = StateInfo::instance();
00387 if ( 0 == stateInfo )
00388 {
00389 #ifdef TIMING
00390 ActiveTimer.stop();
00391 #endif
00392 return true;
00393 }
00394
00395
00396 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00397 if ( 0 == qs )
00398 {
00399 #ifdef TIMING
00400 ActiveTimer.stop();
00401 #endif
00402 return true;
00403 }
00404
00405
00406 BIGNUM * digest = 0;
00407 try
00408 {
00409 digest = response.digest( serverState->hashFunc() );
00410 }
00411 catch ( ... )
00412 {
00413 if ( 0 != digest ) BN_free(digest);
00414 #ifdef TIMING
00415 ActiveTimer.stop();
00416 #endif
00417 return true;
00418 }
00419 if ( 0 == digest )
00420 {
00421 #ifdef TIMING
00422 ActiveTimer.stop();
00423 #endif
00424 return true;
00425 }
00426
00427 bool retVal =
00428 process( digest, event.message().evidence(), qs->quorumSize() );
00429
00430 BN_free( digest );
00431
00432 if ( retVal )
00433 {
00434 event.reRoute( m_destination );
00435 }
00436 else
00437 {
00438 sendEvent( 0, event.source(), true );
00439 }
00440 #ifdef TIMING
00441 ActiveTimer.stop();
00442 #endif
00443 return (!retVal);
00444 }
00445
00446 bool
00447 DelegateResponseVerifier::handler(
00448 SupportedClientResponseEvent< VerifiableBlindKeyMsg, SignedReadKeyMsg >&
00449 event )
00450 {
00451 #ifdef TIMING
00452 ActiveTimer.start();
00453 #endif
00454 const BlindKeyMsg& response = event.message().response();
00455 const VerifiableBlindKeyMsg& vResponse = event.message().response();
00456
00457
00458
00459 const SignedReadKeyMsg& request = event.message().request();
00460
00461 if ( response.name().value() != request.message().name().value() )
00462 {
00463 #ifdef TIMING
00464 ActiveTimer.stop();
00465 #endif
00466 return true;
00467 }
00468
00469
00470
00471 if ( 0 != BN_cmp( response.requestSignature().value(),
00472 request.signature().value() ) )
00473 {
00474 #ifdef TIMING
00475 ActiveTimer.stop();
00476 #endif
00477 return true;
00478 }
00479
00480
00481 CODEX_Server::ServerState* serverState =
00482 CODEX_Server::ServerState::instance();
00483 if ( 0 == serverState )
00484 {
00485 #ifdef TIMING
00486 ActiveTimer.stop();
00487 #endif
00488 return true;
00489 }
00490
00491
00492 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00493 if ( 0 == qs )
00494 {
00495 #ifdef TIMING
00496 ActiveTimer.stop();
00497 #endif
00498 return true;
00499 }
00500
00501
00502 BIGNUM * digest = 0;
00503 unsigned char* buff = 0;
00504 CODEX_ASN1::ustring* str = 0;
00505 try
00506 {
00507 int length = request.marshal(0);
00508 length += vResponse.blindCipher().marshal(0);
00509 buff = new unsigned char[ length ];
00510 unsigned char* pBuff = buff;
00511 request.marshal(&pBuff);
00512 vResponse.blindCipher().marshal(&pBuff);
00513
00514 str = serverState->hashFunc()( CODEX_ASN1::ustring( buff, length ) );
00515
00516 delete [] buff;
00517 buff = 0;
00518
00519 digest = BN_new();
00520 if ( 0 == digest )
00521 {
00522 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00523 }
00524 if ( 0 == BN_bin2bn( str->data(), str->length(), digest ) )
00525 {
00526 throw CODEX_Exceptions::BignumBin2BNException( __FILE__ , __LINE__ );
00527 }
00528
00529 delete str;
00530 }
00531 catch ( ... )
00532 {
00533 if ( 0 != digest ) BN_free(digest);
00534 if ( 0 != buff ) delete [] buff;
00535 if ( 0 != str ) delete str;
00536 #ifdef TIMING
00537 ActiveTimer.stop();
00538 #endif
00539 return true;
00540 }
00541 if ( 0 == digest )
00542 {
00543 #ifdef TIMING
00544 ActiveTimer.stop();
00545 #endif
00546 return true;
00547 }
00548
00549 #ifndef ELGAMAL
00550
00551 CODEX_Ciphers::RSACipherText* blindEncryption = 0;
00552 try
00553 {
00554 blindEncryption = serverState->serviceKey().encrypt(
00555 response.blindedKey().b1().value() );
00556 bool cipherTest1 = ( *blindEncryption == vResponse.blindCipher().c1() );
00557 delete blindEncryption;
00558 blindEncryption = 0;
00559 bool cipherTest2 =
00560 ( response.blindedKey().b2() == vResponse.blindCipher().c2() );
00561 if ( ! ( cipherTest1 && cipherTest2 ) )
00562 {
00563 #ifdef TIMING
00564 ActiveTimer.stop();
00565 #endif
00566 return true;
00567 }
00568 }
00569 catch ( ... )
00570 {
00571 if ( 0 != blindEncryption ) delete blindEncryption;
00572 #ifdef TIMING
00573 ActiveTimer.stop();
00574 #endif
00575 return true;
00576 }
00577 #else
00578
00579 typedef CODEX_Server::ServerState::ShareSetType ShareSetType;
00580 typedef CODEX_Server::ServerState::ShareType ShareType;
00581 const CODEX_Ciphers::ElGamalPublicKey& serviceEGKey =
00582 serverState->publicEGKey();
00583 ShareSetType tempSS;
00584 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00585 {
00586 if ( vResponse.proof(i).verify( vResponse.blindCipher().c1().value(),
00587 serviceEGKey.g().value(),
00588 vResponse.partial(i).value(),
00589 vResponse.label().vc(i).value(),
00590 serviceEGKey.p().value(),
00591 serverState->hashFunc() ) )
00592 {
00593 tempSS.setShare(i,vResponse.partial(i));
00594 }
00595 else
00596 {
00597 #ifdef TIMING
00598 ActiveTimer.stop();
00599 #endif
00600 return true;
00601 }
00602 }
00603
00604
00605
00606 BIGNUM * bk = serverState->thresholdEG().thresholdDecrypt(
00607 tempSS,
00608 vResponse.blindCipher() );
00609 if ( 0 == bk )
00610 {
00611 #ifdef TIMING
00612 ActiveTimer.stop();
00613 #endif
00614 return true;
00615 }
00616 bool bkMismatch = ( 0 != BN_cmp( bk, response.blindedKey().value() ) );
00617 BN_clear_free( bk );
00618 if ( bkMismatch )
00619 {
00620 #ifdef TIMING
00621 ActiveTimer.stop();
00622 #endif
00623 return true;
00624 }
00625 #endif
00626
00627 bool retVal = process(
00628 digest, event.message().evidence(), qs->faultsTolerated()+1 );
00629
00630 BN_free( digest );
00631
00632 if ( retVal )
00633 {
00634 event.reRoute( m_destination );
00635 }
00636 else
00637 {
00638 sendEvent( 0, event.source(), true );
00639 }
00640 #ifdef TIMING
00641 ActiveTimer.stop();
00642 #endif
00643 return (!retVal);
00644 }
00645
00646 bool
00647 DelegateResponseVerifier::process(
00648 const BIGNUM* digest,
00649 const CODEX_ASN1::Array< CODEX_Server::ServerSignature >& evidence,
00650 unsigned int evidenceSize )
00651 {
00652 typedef CODEX_ASN1::Array< CODEX_Server::ServerSignature > ArrayType;
00653
00654
00655 if ( 0 == digest )
00656 {
00657 return false;
00658 }
00659
00660
00661 bool serverResponses[ CODEX_Server::ServerState::nServers ];
00662 for ( unsigned int i = 0 ; i < CODEX_Server::ServerState::nServers ; ++i )
00663 {
00664 serverResponses[i] = false;
00665 }
00666
00667
00668 CODEX_Server::ServerState* serverState =
00669 CODEX_Server::ServerState::instance();
00670 if ( 0 == serverState )
00671 {
00672 return false;
00673 }
00674
00675
00676 if ( evidence.size() < evidenceSize )
00677 {
00678 return false;
00679 }
00680
00681
00682
00683
00684
00685 unsigned int goodSigs = 0;
00686 ArrayType::ArrayItr itr = evidence.begin();
00687 ArrayType::ArrayItr end = evidence.end();
00688 for ( ; itr != end ; ++itr )
00689 {
00690 int serverNum = (*itr)->serverID().value();
00691 if ( serverResponses[ serverNum ] )
00692 {
00693
00694 continue;
00695 }
00696 serverResponses[ serverNum ] = true;
00697
00698
00699 const CODEX_Ciphers::RSAPublicKey& pubKey =
00700 serverState->publicKey( serverNum );
00701 if ( ! pubKey.initialized() )
00702 {
00703 break;
00704 }
00705
00706
00707 if ( ! pubKey.verifySignature( (*itr)->signature(), digest ) )
00708 {
00709 break;
00710 }
00711
00712
00713 ++goodSigs;
00714 }
00715
00716
00717 if ( goodSigs < evidenceSize )
00718 {
00719 return false;
00720 }
00721 return true;
00722 }