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