00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "RecoverCallback.h"
00019 #include "Message.h"
00020 #include "Types.h"
00021 #include "StateInfo.h"
00022 #include "CODEX_Server/ServerState.h"
00023
00024 using namespace CODEX_APSS;
00025
00026 RecoverCallback::RecoverCallback( unsigned int version,
00027 const SublabelType& label ) :
00028 m_version( version ),
00029 m_label( label ),
00030 m_completed( false )
00031 {
00032 }
00033
00034 RecoverCallback::~RecoverCallback()
00035 {
00036
00037 StateInfo::instance()->markRecovered( m_label );
00038 }
00039
00040 bool
00041 RecoverCallback::operator()( unsigned int server, CODEX_Quorum::Message* msg )
00042 {
00043 if ( m_completed )
00044 {
00045 if ( 0 != msg ) delete msg;
00046 return true;
00047 }
00048
00049 if ( 0 == msg )
00050 {
00051 return false;
00052 }
00053
00054 CODEX_Server::ServerState* serverState =
00055 CODEX_Server::ServerState::instance();
00056 if ( 0 == serverState )
00057 {
00058 delete msg;
00059 return false;
00060 }
00061
00062 StateInfo* stateInfo = StateInfo::instance();
00063 if ( 0 == stateInfo )
00064 {
00065 delete msg;
00066 return false;
00067 }
00068
00069
00070 unsigned char* data = (unsigned char*)msg->buffer();
00071 int length = msg->length();
00072
00073 if ( length < 2 )
00074 {
00075 delete msg;
00076 return false;
00077 }
00078
00079 if ( stateInfo->domain() != data[0] )
00080 {
00081 delete msg;
00082 return false;
00083 }
00084 ++data;
00085 --length;
00086
00087 if ( ( kRecoveredMsg | SignatureMask ) != data[0] )
00088 {
00089 delete msg;
00090 return false;
00091 }
00092 ++data;
00093 --length;
00094
00095 SignedRecoveredMsg signedResponse;
00096 if ( 0 == signedResponse.unmarshal( 0, &data, length ) )
00097 {
00098 delete msg;
00099 return false;
00100 }
00101 delete msg;
00102
00103
00104 const RecoveredMsg& response = signedResponse.message();
00105 unsigned int srVersion = response.version().value();
00106 if ( srVersion != m_version )
00107 {
00108 return false;
00109 }
00110
00111 if ( response.requester().value() != serverState->hostNum() )
00112 {
00113 return false;
00114 }
00115
00116 if ( response.sublabel() != m_label )
00117 {
00118 return false;
00119 }
00120
00121
00122 BIGNUM * digest = 0;
00123 try
00124 {
00125 digest = response.digest( serverState->hashFunc() );
00126 if ( 0 == digest )
00127 {
00128 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00129 }
00130 if ( ! serverState->publicKey(server).verifySignature(
00131 signedResponse.signature(),
00132 digest ) )
00133 {
00134 throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00135 __LINE__ );
00136 }
00137 BN_free(digest);
00138 }
00139 catch ( ... )
00140 {
00141 if ( 0 != digest ) BN_free(digest);
00142 return false;
00143 }
00144
00145
00146 unsigned int num = m_label.label().num().value();
00147 OneWay oneWay( stateInfo->witness(num).args() );
00148 if ( ! m_label.check( response.shares(), oneWay ) )
00149 {
00150 return false;
00151 }
00152
00153
00154 stateInfo->addSubsharing( m_label, response.shares() );
00155
00156
00157 unsigned int self = serverState->hostNum();
00158 bool haveAll = true;
00159 const ShareSetType& subsharing =
00160 stateInfo->subsharing( m_label, self );
00161 for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00162 {
00163 if ( subsharing.shouldHave( i, self ) &&
00164 (!subsharing(i).initialized()) )
00165 {
00166 haveAll = false;
00167 break;
00168 }
00169 }
00170 if ( haveAll )
00171 {
00172
00173 stateInfo->markRecovered( m_label );
00174 m_completed = true;
00175 }
00176 return true;
00177 }