00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "EstablishCallback.h"
00019 #include "CODEX_Server/ServerState.h"
00020 #include "StateInfo.h"
00021 #include "Message.h"
00022
00023 #include "CODEX_Exceptions/BignumExceptions.h"
00024 #include "CODEX_Server/ServerExceptions.h"
00025
00026 #include "timing.h"
00027
00028 using namespace CODEX_APSS;
00029
00030 EstablishCallback::EstablishCallback( InitActivity* initAct,
00031 unsigned int version,
00032 const SublabelType& label ) :
00033 m_initAct( initAct ),
00034 m_version( version ),
00035 m_label( label ),
00036 m_completed( false ),
00037 m_evidence( new EvidenceVector )
00038 {
00039 }
00040
00041 EstablishCallback::~EstablishCallback()
00042 {
00043 if ( 0 != m_evidence ) delete m_evidence;
00044 }
00045
00046 bool
00047 EstablishCallback::operator()( unsigned int server,
00048 CODEX_Quorum::Message* msg )
00049 {
00050 if ( m_completed )
00051 {
00052 if ( 0 != msg ) delete msg;
00053 return true;
00054 }
00055
00056 if ( 0 == msg )
00057 {
00058 return false;
00059 }
00060
00061 if ( 0 == m_evidence )
00062 {
00063
00064 m_completed = true;
00065 delete msg;
00066 return false;
00067 }
00068
00069 #ifdef TIMING
00070 ActiveTimer.start();
00071 #endif
00072 CODEX_Server::ServerState* serverState =
00073 CODEX_Server::ServerState::instance();
00074 if ( 0 == serverState )
00075 {
00076 delete msg;
00077 #ifdef TIMING
00078 ActiveTimer.stop();
00079 #endif
00080 return false;
00081 }
00082
00083 StateInfo* stateInfo = StateInfo::instance();
00084 if ( 0 == stateInfo )
00085 {
00086 delete msg;
00087 #ifdef TIMING
00088 ActiveTimer.stop();
00089 #endif
00090 return false;
00091 }
00092
00093
00094 unsigned char* data = (unsigned char*)msg->buffer();
00095 int length = msg->length();
00096
00097 if ( length < 2 )
00098 {
00099 delete msg;
00100 #ifdef TIMING
00101 ActiveTimer.stop();
00102 #endif
00103 return false;
00104 }
00105
00106 if ( stateInfo->domain() != data[0] )
00107 {
00108 delete msg;
00109 #ifdef TIMING
00110 ActiveTimer.stop();
00111 #endif
00112 return false;
00113 }
00114 ++data;
00115 --length;
00116
00117 if ( ( kEstablishedMsg | SignatureMask ) != data[0] )
00118 {
00119 delete msg;
00120 #ifdef TIMING
00121 ActiveTimer.stop();
00122 #endif
00123 return false;
00124 }
00125 ++data;
00126 --length;
00127
00128 SignedEstablishedMsg signedResponse;
00129 if ( 0 == signedResponse.unmarshal( 0, &data, length ) )
00130 {
00131 delete msg;
00132 #ifdef TIMING
00133 ActiveTimer.stop();
00134 #endif
00135 return false;
00136 }
00137 delete msg;
00138
00139
00140 const EstablishedMsg& response = signedResponse.message();
00141 unsigned int srVersion = response.version().value();
00142 if ( srVersion != m_version )
00143 {
00144 #ifdef TIMING
00145 ActiveTimer.stop();
00146 #endif
00147 return false;
00148 }
00149
00150 unsigned int srRecipient = response.recipient().value();
00151 if ( srRecipient != server )
00152 {
00153 #ifdef TIMING
00154 ActiveTimer.stop();
00155 #endif
00156 return false;
00157 }
00158
00159 if ( response.establisher().value() != serverState->hostNum() )
00160 {
00161 #ifdef TIMING
00162 ActiveTimer.stop();
00163 #endif
00164 return false;
00165 }
00166
00167 if ( response.sublabel() != m_label )
00168 {
00169 #ifdef TIMING
00170 ActiveTimer.stop();
00171 #endif
00172 return false;
00173 }
00174
00175
00176 BIGNUM * digest = 0;
00177 try
00178 {
00179 digest = response.digest( serverState->hashFunc() );
00180 if ( 0 == digest )
00181 {
00182 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00183 }
00184 if ( ! serverState->publicKey(server).verifySignature(
00185 signedResponse.signature(),
00186 digest ) )
00187 {
00188 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00189 __LINE__ );
00190 }
00191 BN_free(digest);
00192 }
00193 catch ( ... )
00194 {
00195 if ( 0 != digest ) BN_free(digest);
00196 }
00197
00198
00199 m_evidence->push_back( signedResponse );
00200
00201
00202 CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00203 if ( 0 == qs )
00204 {
00205 #ifdef TIMING
00206 ActiveTimer.stop();
00207 #endif
00208 throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00209 }
00210 if ( m_evidence->size() >= qs->quorumSize() )
00211 {
00212 m_initAct->addEvidence( m_label, m_evidence );
00213 m_evidence = 0;
00214 m_completed = true;
00215 }
00216
00217 #ifdef TIMING
00218 ActiveTimer.stop();
00219 #endif
00220 return true;
00221 }
00222
00223 void
00224 EstablishCallback::fail()
00225 {
00226 if ( 0 != m_initAct )
00227 {
00228 m_initAct->addFailure();
00229 }
00230 }