00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "ClientReadCallback.h"
00019 #include "CODEX_Events/Event.h"
00020 #include "CODEX_Server/ServerExceptions.h"
00021 #include "CODEX_Client/Message.h"
00022 #include "SupportedClientResponse.h"
00023 #include "CODEX_Server/SignRequestEvent.h"
00024 #include "ClientDelegation.h"
00025 #include "SignReadCallback.h"
00026 #include "CODEX_Server/ShareLabelChallenge.h"
00027 #include "CODEX_Server/BroadcastRequestEvent.h"
00028 #include "VerifiableBlindKeyMsg.h"
00029
00030 #include "timing.h"
00031
00032 using namespace CODEX_KeyService;
00033
00034 ClientReadCallback::ClientReadCallback(
00035 CODEX_Events::DeadPileType& deadPile,
00036 CODEX_Events::QType& eventQueue,
00037 CODEX_Server::SignRequestHandler* destination,
00038 ClientResponseHandler* clientAct,
00039 const LabeledReadKeyMsg& req,
00040 const unsigned char* seqNum,
00041 CODEX_Server::BroadcastRequestHandler* reqHandler ) :
00042 ResponseCallback( seqNum ),
00043 CODEX_Events::Activity( deadPile, eventQueue ),
00044 m_destination( destination ),
00045 m_clientAct( clientAct ),
00046 m_request( req ),
00047 m_complete( false ),
00048 m_reqHandler( reqHandler )
00049 {
00050 }
00051
00052 ClientReadCallback::~ClientReadCallback()
00053 {
00054 DigestMap::iterator dItr = m_digests.begin();
00055 DigestMap::iterator dEnd = m_digests.end();
00056 for ( ; dItr != dEnd ; ++dItr )
00057 {
00058 if ( 0 != dItr->second ) BN_free( dItr->second );
00059 }
00060 #ifndef ELGAMAL
00061 PartialMap::iterator pItr = m_partials.begin();
00062 PartialMap::iterator pEnd = m_partials.end();
00063 for ( ; pItr != pEnd ; ++pItr )
00064 {
00065 while ( pItr->second.size() )
00066 {
00067 delete pItr->second.back();
00068 pItr->second.pop_back();
00069 }
00070 }
00071 #endif
00072 ChallengeVector::iterator vItr = m_challenges.begin();
00073 ChallengeVector::iterator vEnd = m_challenges.end();
00074 for ( ; vItr != vEnd ; ++vItr )
00075 {
00076 delete *vItr;
00077 }
00078 }
00079
00081 bool
00082 ClientReadCallback::operator()( unsigned int server,
00083 CODEX_Quorum::Message* msg )
00084 {
00085 if ( 0 == msg )
00086 {
00087 return false;
00088 }
00089
00090 if ( m_complete )
00091 {
00092 delete msg;
00093 return true;
00094 }
00095
00096 #ifdef TIMING
00097 ActiveTimer.start();
00098 #endif
00099
00100 CODEX_Server::ServerState* serverState =
00101 CODEX_Server::ServerState::instance();
00102 if ( 0 == serverState )
00103 {
00104 delete msg;
00105 #ifdef TIMING
00106 ActiveTimer.stop();
00107 #endif
00108 return false;
00109 }
00110
00111 StateInfo* stateInfo = StateInfo::instance();
00112 if ( 0 == stateInfo )
00113 {
00114 delete msg;
00115 #ifdef TIMING
00116 ActiveTimer.stop();
00117 #endif
00118 return false;
00119 }
00120
00121
00122 if ( 0 == stateInfo->getActFromSeqNum( seqNum() ) )
00123 {
00124 delete msg;
00125 #ifdef TIMING
00126 ActiveTimer.stop();
00127 #endif
00128 return false;
00129 }
00130
00131 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00132 if ( 0 == qs )
00133 {
00134 delete msg;
00135 #ifdef TIMING
00136 ActiveTimer.stop();
00137 #endif
00138 throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00139 }
00140
00141 unsigned char* data = (unsigned char*)msg->buffer();
00142 int length = msg->length();
00143
00144 if ( length < 2 )
00145 {
00146 delete msg;
00147 #ifdef TIMING
00148 ActiveTimer.stop();
00149 #endif
00150 return false;
00151 }
00152
00153
00154 if ( stateInfo->delegationDomain() != data[0] )
00155 {
00156 delete msg;
00157 #ifdef TIMING
00158 ActiveTimer.stop();
00159 #endif
00160 return false;
00161 }
00162 ++data;
00163 --length;
00164
00165
00166 if ( ClientDelegation::kBadShareLabel == data[0] )
00167 {
00168 cerr << __FILE__ << ", line " << __LINE__ << ":\n"
00169 << " kBadShareLabel returned" << endl;
00170 ++data;
00171 --length;
00172
00173
00174 CODEX_Server::ServerState::LSType::LabelType label;
00175 if ( 0 == label.unmarshal( 0, &data, length ) )
00176 {
00177
00178 delete msg;
00179 #ifdef TIMING
00180 ActiveTimer.stop();
00181 #endif
00182 return false;
00183 }
00184 LabeledReadKeyMsg newReq( m_request, label );
00185 const unsigned char* newSeqNum = serverState->newSequenceNumber();
00186 stateInfo->registerSequenceNumber( newSeqNum, m_clientAct );
00187 ClientReadCallback* cb = new ClientReadCallback( m_deadPile,
00188 m_queue,
00189 m_destination,
00190 m_clientAct,
00191 newReq,
00192 newSeqNum,
00193 m_reqHandler );
00194
00195 CODEX_Quorum::Message message;
00196
00197 unsigned char self = serverState->hostNum();
00198 message.fill( self | CODEX_Server::ServerState::OutgoingMask );
00199 message.fill( newSeqNum, CODEX_Server::ServerState::nMID );
00200 message.fill( stateInfo->messageDomain() );
00201 message.fill( CODEX_Client::kReadKeyMsg | CODEX_Client::SignatureMask );
00202 int length = newReq.marshal(0);
00203 unsigned char* buffer = new unsigned char[length];
00204 unsigned char* pBuffer = buffer;
00205 newReq.marshal(&pBuffer);
00206 message.fill( buffer, length );
00207 delete [] buffer;
00208
00209
00210 CODEX_Server::BroadcastRequestEvent* outEvent =
00211 new CODEX_Server::BroadcastRequestEvent( 0,
00212 m_reqHandler,
00213 message,
00214 cb );
00215 CODEX_Server::ShareLabelChallenge* slc =
00216 new CODEX_Server::ShareLabelChallenge( label, server, cb, outEvent );
00217 m_challenges.push_back( slc );
00218 if ( m_challenges.size() > qs->faultsTolerated() )
00219 {
00220
00221 ChallengeVector::iterator vItr = m_challenges.begin();
00222 ChallengeVector::iterator vEnd = m_challenges.end();
00223 for ( ; vItr != vEnd ; ++vItr )
00224 {
00225 serverState->addChallenge( seqNum() , *vItr );
00226 }
00227 m_challenges.clear();
00228
00229 m_complete = true;
00230 }
00231 delete msg;
00232 #ifdef TIMING
00233 ActiveTimer.stop();
00234 #endif
00235 return true;
00236 }
00237
00238 if ( ClientDelegation::kApproveClientRequest != data[0] )
00239 {
00240 delete msg;
00241 #ifdef TIMING
00242 ActiveTimer.stop();
00243 #endif
00244 return false;
00245 }
00246 ++data;
00247 --length;
00248
00249
00250 typedef CODEX_Ciphers::RSASignature SigType;
00251 typedef ShareType TDType;
00252 typedef BlindPlainTextType BKType;
00253 unsigned char* oData = data;
00254
00255 SigType signature;
00256 if ( 0 == signature.unmarshal( 0, &data, length ) )
00257 {
00258 delete msg;
00259 #ifdef TIMING
00260 ActiveTimer.stop();
00261 #endif
00262 return false;
00263 }
00264 length -= (data-oData);
00265 oData = data;
00266
00267 BlindCipherTextType bct;
00268 if ( 0 == bct.unmarshal( 0, &data, length ) )
00269 {
00270 delete msg;
00271 #ifdef TIMING
00272 ActiveTimer.stop();
00273 #endif
00274 return false;
00275 }
00276 length -= (data-oData);
00277 oData = data;
00278
00279 TDType* partialResults = new TDType;
00280 if ( 0 == partialResults->unmarshal( 0, &data, length ) )
00281 {
00282 delete msg;
00283 delete partialResults;
00284 #ifdef TIMING
00285 ActiveTimer.stop();
00286 #endif
00287 return false;
00288 }
00289 length -= (data-oData);
00290 oData = data;
00291
00292 #ifdef ELGAMAL
00293 const CODEX_Ciphers::ElGamalPublicKey& serviceEGKey =
00294 serverState->publicEGKey();
00295 if ( ! serviceEGKey.initialized() )
00296 {
00297 delete msg;
00298 delete partialResults;
00299 #ifdef TIMING
00300 ActiveTimer.stop();
00301 #endif
00302 throw CODEX_Server::PublicKeyNotFoundException( __FILE__ ,
00303 __LINE__ );
00304 }
00305 CODEX_ThresholdCrypto::DLProof proofs[TDType::NumShares];
00306 for ( unsigned int i = 0 ; i < TDType::NumShares ; ++i )
00307 {
00308 CODEX_ASN1::Integer ai;
00309 if ( 0 == ai.unmarshal( 0, &data, length ) )
00310 {
00311 delete msg;
00312 delete partialResults;
00313 #ifdef TIMING
00314 ActiveTimer.stop();
00315 #endif
00316 return false;
00317 }
00318 length -= (data-oData);
00319 oData = data;
00320
00321 if ( 0 != ai.value() )
00322 {
00323 if ( 0 == proofs[i].unmarshal( 0, &data, length ) )
00324 {
00325 delete msg;
00326 delete partialResults;
00327 #ifdef TIMING
00328 ActiveTimer.stop();
00329 #endif
00330 return false;
00331 }
00332 length -= (data-oData);
00333 oData = data;
00334 }
00335 }
00336 #endif
00337
00338 delete msg;
00339
00340 CODEX_Server::ServerSignature* servSig = 0;
00341 try
00342 {
00343 DigestMap::iterator dItr = m_digests.find( bct );
00344 if ( dItr == m_digests.end() )
00345 {
00346 m_digests.insert( DigestMap::value_type( bct, 0 ) );
00347 dItr = m_digests.find( bct );
00348 }
00349 if ( 0 == dItr->second )
00350 {
00351 unsigned char* buff = 0;
00352 CODEX_ASN1::ustring* str = 0;
00353 try
00354 {
00355 int length = m_request.SignedReadKeyMsg::marshal(0);
00356 length += bct.marshal(0);
00357 buff = new unsigned char[ length ];
00358 unsigned char* pBuff = buff;
00359 m_request.SignedReadKeyMsg::marshal(&pBuff);
00360 bct.marshal(&pBuff);
00361 str = serverState->hashFunc()( CODEX_ASN1::ustring(buff,length) );
00362 delete [] buff;
00363 buff = 0;
00364 dItr->second = BN_new();
00365 if ( 0 == dItr->second )
00366 {
00367 throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00368 __LINE__ );
00369 }
00370 if ( 0 == BN_bin2bn( str->data(),
00371 str->length(),
00372 dItr->second ) )
00373 {
00374 throw CODEX_Exceptions::BignumBin2BNException( __FILE__ ,
00375 __LINE__ );
00376 }
00377
00378 delete str;
00379 }
00380 catch ( ... )
00381 {
00382 if ( 0 != buff ) delete [] buff;
00383 if ( 0 != str ) delete str;
00384 if ( 0 != dItr->second ) BN_free( dItr->second );
00385 throw;
00386 }
00387 }
00388
00389 if ( ! serverState->publicKey(server).verifySignature(
00390 signature, dItr->second ) )
00391 {
00392 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00393 __LINE__ );
00394 }
00395
00396
00397 servSig = new CODEX_Server::ServerSignature( server, signature );
00398
00399
00400 m_evidence[ bct ].append( servSig );
00401 servSig = 0;
00402
00403 #ifndef ELGAMAL
00404 m_partials[ bct ].push_back( partialResults );
00405 partialResults = 0;
00406 #else
00407
00408
00409
00410
00411
00412
00413 ShareSetType tempSS;
00414 tempSS.addShare( *partialResults );
00415
00416 const CODEX_Server::ServerState::LSType::LabelType& reqLabel =
00417 m_request.label();
00418
00419 bool goodShares = true;
00420 for ( unsigned int i = 0 ;
00421 goodShares && ( i < ShareType::NumShares ) ;
00422 ++i )
00423 {
00424 if ( tempSS(i).initialized() )
00425 {
00426 if ( ! proofs[i].verify( bct.c1().value(),
00427 serviceEGKey.g().value(),
00428 tempSS(i).value(),
00429 reqLabel.vc(i).value(),
00430 serviceEGKey.p().value(),
00431 serverState->hashFunc() ) )
00432 {
00433 goodShares = false;
00434 }
00435 }
00436 }
00437 if ( goodShares )
00438 {
00439 m_partials[ bct ].addShare( *partialResults );
00440 delete partialResults;
00441 partialResults = 0;
00442 ++m_nResp[ bct ];
00443 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00444 {
00445 if ( proofs[i].initialized() )
00446 {
00447 if ( m_proofs[ bct ].size() != ShareType::NumShares )
00448 {
00449 m_proofs[ bct ].resize( ShareType::NumShares );
00450 }
00451 if ( ! m_proofs[ bct ][i].initialized() )
00452 {
00453 m_proofs[ bct ][i] = proofs[i];
00454 }
00455 }
00456 }
00457 }
00458 else
00459 {
00460 delete partialResults;
00461 partialResults = 0;
00462 }
00463 #endif
00464
00465
00466
00467 typedef VerifiableBlindKeyMsg RespType;
00468 typedef CODEX_Client::SignedReadKeyMsg ReqType;
00469
00470 BKType blindedKey;
00471 PartialMap::key_type pKey;
00472 PartialMap::data_type pVal;
00473
00474 unsigned int numResp = 0;
00475 PartialMap::const_iterator itr = m_partials.begin();
00476 PartialMap::const_iterator end = m_partials.end();
00477 for ( ; ( itr != end ) && ( ! blindedKey.initialized() ) ; ++itr )
00478 {
00479 #ifndef ELGAMAL
00480 numResp += itr->second.size();
00481 #else
00482 numResp += m_nResp[ itr->first ];
00483 #endif
00484 constructBlindedKey( blindedKey, itr->first, itr->second );
00485 if ( blindedKey.initialized() )
00486 {
00487 pKey = itr->first;
00488 pVal = itr->second;
00489 }
00490 }
00491
00492 if ( blindedKey.initialized() )
00493 {
00494 RespType bkMsg( m_request.message().name(),
00495 blindedKey,
00496 m_request.signature(),
00497 #ifdef ELGAMAL
00498 reqLabel,
00499 pVal,
00500 m_proofs[pKey],
00501 #endif
00502 pKey );
00503 const CODEX_Server::ServerState::LSType::LabelType& label =
00504 serverState->defaultSignatureLabel();
00505
00506 SupportedClientResponse< RespType, ReqType > resp( bkMsg,
00507 m_request,
00508 m_evidence[bct],
00509 label );
00510 unsigned char* seqNum = serverState->newSequenceNumber();
00511 stateInfo->registerSequenceNumber( seqNum, m_clientAct );
00512 SignReadCallback* cb = new SignReadCallback( m_deadPile,
00513 m_queue,
00514 m_clientAct,
00515 resp,
00516 seqNum,
00517 m_destination );
00518
00519 CODEX_Quorum::Message request;
00520 unsigned char self = serverState->hostNum();
00521 request.fill( self | CODEX_Server::ServerState::OutgoingMask );
00522 request.fill( seqNum, CODEX_Server::ServerState::nMID );
00523 request.fill( stateInfo->delegationDomain() );
00524 request.fill( ClientDelegation::kRequestSignature );
00525 request.fill( CODEX_Client::kBlindKeyMsg );
00526 int reqLen = resp.marshal(0);
00527 unsigned char* reqBuff = new unsigned char[reqLen];
00528 unsigned char* pReqBuff = reqBuff;
00529 resp.marshal(&pReqBuff);
00530 request.fill( reqBuff, reqLen );
00531 delete [] reqBuff;
00532
00533 CODEX_Server::SignRequestEvent* event =
00534 new CODEX_Server::SignRequestEvent(this,
00535 m_destination,
00536 request,
00537 cb);
00538 sendEvent( event, 0 );
00539 serverState->removeChallenge( this->seqNum() );
00540 m_complete = true;
00541 }
00542 else if ( numResp >= qs->quorumSize() )
00543 {
00544
00545
00546 sendEvent( new CODEX_Events::CloseEvent(0, m_clientAct), 0 );
00547 #ifdef TIMING
00548 ActiveTimer.stop();
00549 #endif
00550 return false;
00551 }
00552 #ifdef TIMING
00553 ActiveTimer.stop();
00554 #endif
00555 return true;
00556 }
00557 catch ( CODEX_Exceptions::ExceptionBase& e )
00558 {
00559 e.report();
00560 if ( 0 != servSig ) delete servSig;
00561 if ( 0 != partialResults ) delete partialResults;
00562 #ifdef TIMING
00563 ActiveTimer.stop();
00564 #endif
00565 return false;
00566 }
00567 catch ( ... )
00568 {
00569 if ( 0 != servSig ) delete servSig;
00570 if ( 0 != partialResults ) delete partialResults;
00571 #ifdef TIMING
00572 ActiveTimer.stop();
00573 #endif
00574 return false;
00575 }
00576
00577 #ifdef TIMING
00578 ActiveTimer.stop();
00579 #endif
00580 return false;
00581 }
00582
00583 void
00584 ClientReadCallback::constructBlindedKey( BlindPlainTextType& blindedKey,
00585 const BlindCipherTextType& blinding,
00586 const PartialArray& partials )
00587 {
00588 typedef ShareType TDType;
00589
00590 CODEX_Server::ServerState* serverState =
00591 CODEX_Server::ServerState::instance();
00592 if ( 0 == serverState )
00593 {
00594 return;
00595 }
00596
00597 #ifndef ELGAMAL
00598 if ( partials.size() > CODEX_Server::ServerState::nFaults )
00599 {
00600
00601 ShareSetType allPartials;
00602 PartialArray::const_iterator itr = partials.begin();
00603 PartialArray::const_iterator end = partials.end();
00604 for ( ; itr != end ; ++itr )
00605 {
00606 allPartials.addShare( **itr );
00607 }
00608
00609 const CODEX_Server::ServerState::ThresholdRSAType& thresholdRSA =
00610 serverState->thresholdRSA();
00611 BIGNUM* bk = thresholdRSA.threshold( allPartials );
00612 if ( 0 != bk )
00613 {
00614 try
00615 {
00616 const CODEX_Ciphers::RSAPublicKey& serviceKey =
00617 serverState->serviceKey();
00618 if ( ! serviceKey.initialized() )
00619 {
00620 throw CODEX_Server::PublicKeyNotFoundException( __FILE__ ,
00621 __LINE__ );
00622 }
00623
00624
00625 CODEX_Ciphers::RSACipherText* ct = serviceKey.encrypt( bk );
00626 if ( 0 == BN_cmp( ct->value(), blinding.c1().value() ) )
00627 {
00628 blindedKey = BlindPlainTextType( bk, blinding.c2() );
00629 bk = 0;
00630 }
00631 delete ct;
00632 }
00633 catch ( ... )
00634 {
00635 }
00636 if ( 0 != bk ) BN_free( bk );
00637 }
00638
00639 if ( ! blindedKey.initialized() )
00640 {
00641 bk = serverState->thresholdOperation( partials,
00642 blinding.c1().value() );
00643 if ( 0 != bk )
00644 {
00645 blindedKey = BlindPlainTextType( bk, blinding.c2() );
00646 bk = 0;
00647 }
00648 if ( 0 != bk ) BN_free( bk );
00649 }
00650 }
00651 #else
00652
00653
00654
00655 BIGNUM * bk = serverState->thresholdEG().thresholdDecrypt( partials,
00656 blinding );
00657 if ( 0 == bk )
00658 {
00659 return;
00660 }
00661 blindedKey = CODEX_ASN1::BigNumber( bk );
00662 #endif
00663 }