Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

InternalVerifier.cc

00001 /*
00002  * Copyright 2003 Michael A. Marsh, Cornell University. All rights reserved.
00003  * This software is released under the modified BSD license.
00004  * See the file LICENSE in the top-level directory for details.
00005  */
00006 //
00007 // $Id: InternalVerifier.cc,v 1.3 2004/05/19 15:56:58 mmarsh Exp $
00008 //
00009 // $Log: InternalVerifier.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:58  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.2  2003/11/04 22:31:50  mmarsh
00014 // *** empty log message ***
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       // Don't remove until now, because it screws up iterating through the
00043       // list otherwise.
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       // We're in the first step of the protocol.
00064       if ( SocketBase::kWrite != s )
00065       {
00066          return;
00067       }
00068       // Select a nonce
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          // send the nonce...
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       // We're in the second step of the protocol.
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       // We have the full message.
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       // The host is who it claims to be.  Set up a long-term connection.
00163       // Make sure the socket isn't going to be closed when this server
00164       // goes away.
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       // add rs to the quorum system
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 }

Generated on Fri May 6 17:39:58 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1