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