00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "InternalVerifier.h"
00018 #include "CODEX_Quorum/Socket.h"
00019 #include "CODEX_ASN1/Integer.h"
00020 #include "ServerState.h"
00021
00022 #include "CODEX_Exceptions/BignumExceptions.h"
00023
00024 using namespace CODEX_Server;
00025
00026 InternalVerifier::InternalVerifier(
00027 int port,
00028 const CODEX_Quorum::SocketBuilder& socketBuilder,
00029 CODEX_Quorum::SocketBase* socket ) :
00030 CODEX_Quorum::LocalServer( port, socketBuilder ),
00031 m_toRead( 0 )
00032 {
00033 setSocket( socket );
00034 ServerState::instance()->addServer( this );
00035 }
00036
00037 InternalVerifier::~InternalVerifier()
00038 {
00039 ServerState* serverState = ServerState::instance();
00040 if ( NULL != serverState )
00041 {
00042
00043
00044 serverState->removeServer( this );
00045 }
00046 }
00047
00048 void
00049 InternalVerifier::disable()
00050 {
00051 CODEX_Quorum::LocalServer::disable();
00052 ServerState* serverState = ServerState::instance();
00053 if ( NULL == serverState ) return;
00054 serverState->cleanServer( this );
00055 }
00056
00057 void
00058 InternalVerifier::processRequest( CODEX_Quorum::SocketBase::StateType s )
00059 {
00060 using CODEX_Quorum::SocketBase;
00061 if ( ! m_nonce.initialized() )
00062 {
00063
00064 if ( SocketBase::kWrite != s )
00065 {
00066 return;
00067 }
00068
00069 BIGNUM * n = NULL;
00070 unsigned char* buffer = NULL;
00071 try
00072 {
00073 n = BN_new();
00074 if ( NULL == n )
00075 {
00076 throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00077 }
00078 if ( ! BN_rand( n, 1024, -1, 0 ) )
00079 {
00080 throw CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00081 __LINE__ );
00082 }
00083 m_nonce = CODEX_ASN1::SecureBigNumber( n );
00084 n = NULL;
00085
00086 int length = m_nonce.marshal(0);
00087 buffer = new unsigned char[length];
00088 unsigned char* pBuffer = buffer;
00089 m_nonce.marshal(&pBuffer);
00090 socket()->writeTo( CODEX_Quorum::Message( buffer, length ) );
00091 delete [] buffer;
00092 }
00093 catch ( ... )
00094 {
00095 if ( NULL != n ) BN_clear_free( n );
00096 if ( NULL != buffer ) delete [] buffer;
00097 throw;
00098 }
00099 }
00100 else
00101 {
00102
00103 if ( SocketBase::kRead != s )
00104 {
00105 return;
00106 }
00107 m_toRead = socket()->readAll( m_msg, m_toRead );
00108 if ( 0 != m_toRead )
00109 {
00110 return;
00111 }
00112
00113 int length = m_msg.length();
00114 unsigned char* data = (unsigned char*)m_msg.buffer();
00115 unsigned char* pData = data;
00116 CODEX_ASN1::Integer hostNum;
00117 if ( NULL == hostNum.unmarshal(NULL,&pData,length) )
00118 {
00119 disable();
00120 return;
00121 }
00122 if ( ( hostNum.value() < 0 ) ||
00123 ( hostNum.value() >= ServerState::nServers ) )
00124 {
00125 disable();
00126 return;
00127 }
00128 const CODEX_Ciphers::RSAPublicKey& hostKey =
00129 ServerState::instance()->publicKey( hostNum.value() );
00130
00131 length -= ( pData-data );
00132 CODEX_ASN1::BigNumber nonce;
00133 if ( NULL == nonce.unmarshal(NULL,&pData,length) )
00134 {
00135 disable();
00136 return;
00137 }
00138 int dataLength = pData - data;
00139 length = m_msg.length() - dataLength;
00140 CODEX_Ciphers::RSASignature signature;
00141 if ( NULL == signature.unmarshal(NULL,&pData,length) )
00142 {
00143 disable();
00144 return;
00145 }
00146 CODEX_ASN1::ustring* str=NULL;
00147 str = ServerState::instance()->hashFunc()(
00148 CODEX_ASN1::ustring(data, dataLength) );
00149 BIGNUM * digest = NULL;
00150 digest = BN_new();
00151 BN_bin2bn( str->data(), str->length(), digest );
00152 delete str;
00153 str = NULL;
00154 if ( ! hostKey.verifySignature(signature,digest) )
00155 {
00156 cout << "verify failed" << endl;
00157 BN_free(digest);
00158 disable();
00159 return;
00160 }
00161 BN_free(digest);
00162
00163
00164
00165 SocketBase* skt = socket();
00166 CODEX_Quorum::AsynchronousRemoteServer* rs =
00167 new CODEX_Quorum::AsynchronousRemoteServer(
00168 "",
00169 0,
00170 ServerState::instance()->serverOutSocketBuilder(),
00171 skt );
00172
00173
00174 if ( ! ServerState::instance()->addQuorumServer(hostNum.value(),rs) )
00175 {
00176 delete rs;
00177 }
00178 cout << "Accepted connection from server " << hostNum.value() << endl;
00179 setSocket(NULL);
00180 disable();
00181 }
00182 }