00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "SignCreateCallback.h"
00019 #include "CODEX_Events/Event.h"
00020 #include "StateInfo.h"
00021 #include "CODEX_Client/Message.h"
00022 #include "CODEX_Server/SignRequestEvent.h"
00023 #include "ClientDelegation.h"
00024 #include "CODEX_Server/ShareLabelChallenge.h"
00025
00026 #include "CODEX_Server/ServerExceptions.h"
00027 #include "Exceptions.h"
00028
00029 #include "timing.h"
00030
00031 using namespace CODEX_KeyService;
00032
00033 SignCreateCallback::SignCreateCallback(
00034 CODEX_Events::DeadPileType& deadPile,
00035 CODEX_Events::QType& eventQueue,
00036 ClientResponseHandler* destination,
00037 const RequestType& request,
00038 const unsigned char* seqNum,
00039 CODEX_Server::SignRequestHandler* reqHandler ) :
00040 ResponseCallback( seqNum ),
00041 CODEX_Events::Activity( deadPile, eventQueue ),
00042 m_destination( destination ),
00043 m_request( request ),
00044 m_complete( false ),
00045 m_reqHandler( reqHandler )
00046 {
00047 m_digest = m_request.response().digest(
00048 CODEX_Server::ServerState::instance()->hashFunc() );
00049 ChallengeVector::iterator vItr = m_challenges.begin();
00050 ChallengeVector::iterator vEnd = m_challenges.end();
00051 for ( ; vItr != vEnd ; ++vItr )
00052 {
00053 delete *vItr;
00054 }
00055 }
00056
00057 SignCreateCallback::~SignCreateCallback()
00058 {
00059 if ( NULL != m_digest ) BN_free( m_digest );
00060 while ( m_signatures.size() )
00061 {
00062 delete m_signatures.back();
00063 m_signatures.pop_back();
00064 }
00065 }
00066
00068 bool
00069 SignCreateCallback::operator()( unsigned int server,
00070 CODEX_Quorum::Message* msg )
00071 {
00072 if ( NULL == msg )
00073 {
00074 return false;
00075 }
00076
00077 if ( m_complete )
00078 {
00079 delete msg;
00080 return true;
00081 }
00082
00083 #ifdef TIMING
00084 ActiveTimer.start();
00085 #endif
00086
00087 CODEX_Server::ServerState* serverState =
00088 CODEX_Server::ServerState::instance();
00089 if ( NULL == serverState )
00090 {
00091 delete msg;
00092 #ifdef TIMING
00093 ActiveTimer.stop();
00094 #endif
00095 return false;
00096 }
00097
00098 StateInfo* stateInfo = StateInfo::instance();
00099 if ( NULL == stateInfo )
00100 {
00101 delete msg;
00102 #ifdef TIMING
00103 ActiveTimer.stop();
00104 #endif
00105 return false;
00106 }
00107
00108
00109 if ( NULL == stateInfo->getActFromSeqNum( seqNum() ) )
00110 {
00111 delete msg;
00112 #ifdef TIMING
00113 ActiveTimer.stop();
00114 #endif
00115 return false;
00116 }
00117
00118 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00119 if ( NULL == qs )
00120 {
00121 delete msg;
00122 #ifdef TIMING
00123 ActiveTimer.stop();
00124 #endif
00125 throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00126 }
00127
00128 unsigned char* data = (unsigned char*)msg->buffer();
00129 int length = msg->length();
00130
00131 if ( length < 2 )
00132 {
00133 delete msg;
00134 #ifdef TIMING
00135 ActiveTimer.stop();
00136 #endif
00137 return false;
00138 }
00139
00140
00141 if ( stateInfo->delegationDomain() != data[0] )
00142 {
00143 delete msg;
00144 #ifdef TIMING
00145 ActiveTimer.stop();
00146 #endif
00147 return false;
00148 }
00149 ++data;
00150 --length;
00151
00152
00153 if ( ClientDelegation::kBadShareLabel == data[0] )
00154 {
00155 cerr << __FILE__ << ", line " << __LINE__ << ":\n"
00156 << " kBadShareLabel returned" << endl;
00157 ++data;
00158 --length;
00159
00160
00161 CODEX_Server::ServerState::LSType::LabelType label;
00162 if ( NULL == label.unmarshal( NULL, &data, length ) )
00163 {
00164
00165 delete msg;
00166 #ifdef TIMING
00167 ActiveTimer.stop();
00168 #endif
00169 return false;
00170 }
00171 RequestType newReq( m_request.response(),
00172 m_request.request(),
00173 m_request.evidence(),
00174 label );
00175 const unsigned char* newSeqNum = serverState->newSequenceNumber();
00176 stateInfo->registerSequenceNumber( newSeqNum, m_destination );
00177 SignCreateCallback* cb = new SignCreateCallback( m_deadPile,
00178 m_queue,
00179 m_destination,
00180 newReq,
00181 newSeqNum,
00182 m_reqHandler );
00183
00184 CODEX_Quorum::Message message;
00185 unsigned char self = serverState->hostNum();
00186 message.fill( self | CODEX_Server::ServerState::OutgoingMask );
00187 message.fill( newSeqNum, CODEX_Server::ServerState::nMID );
00188 message.fill( stateInfo->delegationDomain() );
00189 message.fill( ClientDelegation::kRequestSignature );
00190 message.fill( CODEX_Client::kBoundNameMsg );
00191 int length = newReq.marshal(0);
00192 unsigned char* buffer = new unsigned char[length];
00193 unsigned char* pBuffer = buffer;
00194 newReq.marshal(&pBuffer);
00195 message.fill( buffer, length );
00196 delete [] buffer;
00197
00198
00199 CODEX_Server::SignRequestEvent* outEvent =
00200 new CODEX_Server::SignRequestEvent( this,
00201 m_reqHandler,
00202 message,
00203 cb );
00204 CODEX_Server::ShareLabelChallenge* slc =
00205 new CODEX_Server::ShareLabelChallenge( label, server, cb, outEvent );
00206 m_challenges.push_back( slc );
00207 if ( m_challenges.size() > qs->faultsTolerated() )
00208 {
00209
00210 ChallengeVector::iterator vItr = m_challenges.begin();
00211 ChallengeVector::iterator vEnd = m_challenges.end();
00212 for ( ; vItr != vEnd ; ++vItr )
00213 {
00214 serverState->addChallenge( seqNum() , *vItr );
00215 }
00216 m_challenges.clear();
00217
00218 m_complete = true;
00219 }
00220 delete msg;
00221 #ifdef TIMING
00222 ActiveTimer.stop();
00223 #endif
00224 return true;
00225 }
00226
00227 if ( ClientDelegation::kAcceptSignatureRequest != data[0] )
00228 {
00229 delete msg;
00230 #ifdef TIMING
00231 ActiveTimer.stop();
00232 #endif
00233 return false;
00234 }
00235 ++data;
00236 --length;
00237
00238
00239 typedef CODEX_Server::ServerState::ShareType ShareType;
00240 ShareType* signatures = new ShareType;
00241 if ( NULL == signatures->unmarshal( NULL, &data, length ) )
00242 {
00243 delete msg;
00244 #ifdef TIMING
00245 ActiveTimer.stop();
00246 #endif
00247 return false;
00248 }
00249 delete msg;
00250 m_signatures.push_back( signatures );
00251
00252
00253 typedef CODEX_Client::SignedBoundNameMsg MsgType;
00254
00255 const CODEX_Server::ServerState::ThresholdRSAType& thresholdRSA =
00256 serverState->thresholdRSA();
00257
00258
00259 if ( m_signatures.size() > CODEX_Server::ServerState::nFaults )
00260 {
00261 CODEX_Server::ServerState::ShareSetType partials;
00262 SignatureArray::const_iterator itr = m_signatures.begin();
00263 SignatureArray::const_iterator end = m_signatures.end();
00264 for ( ; itr != end ; ++itr )
00265 {
00266 partials.addShare( **itr );
00267 }
00268
00269 BIGNUM * tsig = thresholdRSA.threshold( partials );
00270 if ( NULL != tsig )
00271 {
00272 ClientResponseEvent< MsgType >* event = NULL;
00273 try
00274 {
00275 CODEX_Ciphers::RSASignature sig( tsig );
00276 const CODEX_Ciphers::RSAPublicKey& serviceKey =
00277 serverState->serviceKey();
00278 if ( ! serviceKey.initialized() )
00279 {
00280 throw CODEX_Server::PublicKeyNotFoundException( __FILE__ ,
00281 __LINE__ );
00282 }
00283 if ( serviceKey.verifySignature( sig, m_digest ) )
00284 {
00285 event = new ClientResponseEvent< MsgType >(
00286 this,
00287 m_destination,
00288 MsgType(m_request.response(), sig) );
00289 if ( ! stateInfo->addKeySignature(
00290 m_request.response().name().value(), sig ) )
00291 {
00292 throw KeyNotFoundException( __FILE__ , __LINE__ );
00293 }
00294 sendEvent( event, 0 );
00295 serverState->removeChallenge( seqNum() );
00296 m_complete = true;
00297
00298 #ifdef TIMING
00299 ActiveTimer.stop();
00300 #endif
00301 return true;
00302 }
00303 }
00304 catch ( ... )
00305 {
00306 if ( NULL == event ) delete event;
00307 #ifdef TIMING
00308 ActiveTimer.stop();
00309 #endif
00310 throw;
00311 }
00312 }
00313 }
00314
00315
00316
00317 if ( m_signatures.size() >= qs->quorumSize() )
00318 {
00319 BIGNUM* tsig = serverState->thresholdOperation( m_signatures, m_digest );
00320 if ( NULL != tsig )
00321 {
00322 ClientResponseEvent< MsgType >* event = NULL;
00323 try
00324 {
00325 CODEX_Ciphers::RSASignature sig(tsig);
00326 event = new ClientResponseEvent< MsgType >(
00327 this,
00328 m_destination,
00329 MsgType(m_request.response(), sig) );
00330 if ( ! stateInfo->addKeySignature(
00331 m_request.response().name().value(),sig ) )
00332 {
00333 throw KeyNotFoundException( __FILE__ , __LINE__ );
00334 }
00335 sendEvent( event, 0 );
00336 serverState->removeChallenge( seqNum() );
00337 m_complete = true;
00338 }
00339 catch ( ... )
00340 {
00341 if ( NULL != event ) delete event;
00342 #ifdef TIMING
00343 ActiveTimer.stop();
00344 #endif
00345 throw;
00346 }
00347 }
00348 else
00349 {
00350
00351 sendEvent( new CODEX_Events::CloseEvent( this, m_destination ), 0 );
00352 }
00353 }
00354 #ifdef TIMING
00355 ActiveTimer.stop();
00356 #endif
00357 return true;
00358 }