00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "SignWriteCallback.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 SignWriteCallback::SignWriteCallback(
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().digest(
00047 CODEX_Server::ServerState::instance()->hashFunc() );
00048 }
00049
00050 SignWriteCallback::~SignWriteCallback()
00051 {
00052 if ( NULL != 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 SignWriteCallback::operator()( unsigned int server,
00069 CODEX_Quorum::Message* msg )
00070 {
00071 if ( NULL == 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 ( NULL == 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 ( NULL == stateInfo )
00099 {
00100 delete msg;
00101 #ifdef TIMING
00102 ActiveTimer.stop();
00103 #endif
00104 return false;
00105 }
00106
00107
00108 if ( NULL == 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 ( NULL == 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 ( NULL == label.unmarshal( NULL, &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.evidence(),
00172 label );
00173 const unsigned char* newSeqNum = serverState->newSequenceNumber();
00174 stateInfo->registerSequenceNumber( newSeqNum, m_destination );
00175 SignWriteCallback* cb = new SignWriteCallback( m_deadPile,
00176 m_queue,
00177 m_destination,
00178 newReq,
00179 newSeqNum,
00180 m_reqHandler );
00181
00182 CODEX_Quorum::Message message;
00183 unsigned char self = serverState->hostNum();
00184 message.fill( self | CODEX_Server::ServerState::OutgoingMask );
00185 message.fill( newSeqNum, CODEX_Server::ServerState::nMID );
00186 message.fill( stateInfo->delegationDomain() );
00187 message.fill( ClientDelegation::kRequestSignature );
00188 message.fill( CODEX_Client::kKeyStoredMsg );
00189 int length = newReq.marshal(0);
00190 unsigned char* buffer = new unsigned char[length];
00191 unsigned char* pBuffer = buffer;
00192 newReq.marshal(&pBuffer);
00193 message.fill( buffer, length );
00194 delete [] buffer;
00195
00196
00197 CODEX_Server::SignRequestEvent* outEvent =
00198 new CODEX_Server::SignRequestEvent( this,
00199 m_reqHandler,
00200 message,
00201 cb );
00202 CODEX_Server::ShareLabelChallenge* slc =
00203 new CODEX_Server::ShareLabelChallenge( label, server, cb, outEvent );
00204 m_challenges.push_back( slc );
00205 if ( m_challenges.size() > qs->faultsTolerated() )
00206 {
00207
00208 ChallengeVector::iterator vItr = m_challenges.begin();
00209 ChallengeVector::iterator vEnd = m_challenges.end();
00210 for ( ; vItr != vEnd ; ++vItr )
00211 {
00212 serverState->addChallenge( seqNum() , *vItr );
00213 }
00214 m_challenges.clear();
00215
00216 m_complete = true;
00217 }
00218 delete msg;
00219 #ifdef TIMING
00220 ActiveTimer.stop();
00221 #endif
00222 return true;
00223 }
00224
00225 if ( ClientDelegation::kAcceptSignatureRequest != data[0] )
00226 {
00227 delete msg;
00228 #ifdef TIMING
00229 ActiveTimer.stop();
00230 #endif
00231 return false;
00232 }
00233 ++data;
00234 --length;
00235
00236
00237 typedef CODEX_Server::ServerState::ShareType ShareType;
00238 ShareType* signatures = new ShareType;
00239 if ( NULL == signatures->unmarshal( NULL, &data, length ) )
00240 {
00241 delete msg;
00242 #ifdef TIMING
00243 ActiveTimer.stop();
00244 #endif
00245 return false;
00246 }
00247 delete msg;
00248 m_signatures.push_back( signatures );
00249
00250
00251 typedef CODEX_Client::SignedKeyStoredMsg MsgType;
00252
00253 const CODEX_Server::ServerState::ThresholdRSAType& thresholdRSA =
00254 serverState->thresholdRSA();
00255
00256
00257 if ( m_signatures.size() > CODEX_Server::ServerState::nFaults )
00258 {
00259 CODEX_Server::ServerState::ShareSetType partials;
00260 SignatureArray::const_iterator itr = m_signatures.begin();
00261 SignatureArray::const_iterator end = m_signatures.end();
00262 for ( ; itr != end ; ++itr )
00263 {
00264 partials.addShare( **itr );
00265 }
00266
00267 BIGNUM * tsig = thresholdRSA.threshold( partials );
00268 if ( NULL != tsig )
00269 {
00270 try
00271 {
00272 CODEX_Ciphers::RSASignature sig(tsig);
00273 const CODEX_Ciphers::RSAPublicKey& serviceKey =
00274 serverState->serviceKey();
00275 if ( ! serviceKey.initialized() )
00276 {
00277 throw CODEX_Server::PublicKeyNotFoundException( __FILE__ ,
00278 __LINE__ );
00279 }
00280 if ( serviceKey.verifySignature( sig, m_digest ) )
00281 {
00282 ClientResponseEvent< MsgType >* event = new
00283 ClientResponseEvent< MsgType >(
00284 this,
00285 m_destination,
00286 MsgType(m_request.response(), sig) );
00287 sendEvent( event, 0 );
00288 serverState->removeChallenge( seqNum() );
00289 m_complete = true;
00290
00291 #ifdef TIMING
00292 ActiveTimer.stop();
00293 #endif
00294 return true;
00295 }
00296 }
00297 catch ( ... )
00298 {
00299 }
00300 }
00301 }
00302
00303
00304
00305 if ( m_signatures.size() >= qs->quorumSize() )
00306 {
00307 BIGNUM* tsig = serverState->thresholdOperation( m_signatures, m_digest );
00308 if ( NULL != tsig )
00309 {
00310 CODEX_Ciphers::RSASignature sig(tsig);
00311 ClientResponseEvent< MsgType >* event = new
00312 ClientResponseEvent< MsgType >(
00313 this,
00314 m_destination,
00315 MsgType(m_request.response(), sig) );
00316 sendEvent( event, 0 );
00317 serverState->removeChallenge( seqNum() );
00318 m_complete = true;
00319 }
00320 else
00321 {
00322
00323 sendEvent( new CODEX_Events::CloseEvent( this, m_destination ), 0 );
00324 }
00325 }
00326 #ifdef TIMING
00327 ActiveTimer.stop();
00328 #endif
00329 return true;
00330 }