Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

VerifyWriteCallback.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: VerifyWriteCallback.cc,v 1.4 2004/05/19 15:56:54 mmarsh Exp $
00008 //
00009 // $Log: VerifyWriteCallback.cc,v $
00010 // Revision 1.4  2004/05/19 15:56:54  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.3  2003/11/04 22:31:49  mmarsh
00014 // *** empty log message ***
00015 //
00016 //
00017 
00018 #include "VerifyWriteCallback.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 "SupportedKeyStoredMsg.h"
00025 #include "CODEX_Server/SignRequestEvent.h"
00026 #include "ClientDelegation.h"
00027 #include "SignWriteCallback.h"
00028 
00029 #include "timing.h"
00030 
00031 using namespace CODEX_KeyService;
00032 
00033 VerifyWriteCallback::VerifyWriteCallback(
00034    CODEX_Events::DeadPileType& deadPile,
00035    CODEX_Events::QType& eventQueue,
00036    CODEX_Server::SignRequestHandler* destination,
00037    ClientResponseHandler* clientAct,
00038    const CODEX_Client::KeyStoredMsg& resp,
00039    const unsigned char* seqNum ) :
00040    ResponseCallback( seqNum ),
00041    CODEX_Events::Activity( deadPile, eventQueue ),
00042    m_destination( destination ),
00043    m_clientAct( clientAct ),
00044    m_response( resp ),
00045    m_complete( false )
00046 {
00047    m_digest =
00048       m_response.digest( CODEX_Server::ServerState::instance()->hashFunc() );
00049 }
00050 
00051 VerifyWriteCallback::~VerifyWriteCallback()
00052 {
00053    if ( NULL != m_digest ) BN_free( m_digest );
00054 }
00055 
00059 bool
00060 VerifyWriteCallback::operator()( unsigned int server,
00061                                  CODEX_Quorum::Message* msg )
00062 {
00063    if ( NULL == msg )
00064    {
00065       return false;
00066    }
00067 
00068    if ( m_complete )
00069    {
00070       delete msg;
00071       return true;
00072    }
00073 
00074 #ifdef TIMING
00075    ActiveTimer.start();
00076 #endif
00077 
00078    CODEX_Server::ServerState* serverState =
00079       CODEX_Server::ServerState::instance();
00080    if ( NULL == serverState )
00081    {
00082       delete msg;
00083 #ifdef TIMING
00084       ActiveTimer.stop();
00085 #endif
00086       return false;
00087    }
00088 
00089    StateInfo* stateInfo = StateInfo::instance();
00090    if ( NULL == stateInfo )
00091    {
00092       delete msg;
00093 #ifdef TIMING
00094       ActiveTimer.stop();
00095 #endif
00096       return false;
00097    }
00098 
00099    // Sanity check -- is the client still connected?
00100    if ( NULL == stateInfo->getActFromSeqNum( seqNum() ) )
00101    {
00102       delete msg;
00103 #ifdef TIMING
00104       ActiveTimer.stop();
00105 #endif
00106       return false;
00107    }
00108 
00109    unsigned char* data = (unsigned char*)msg->buffer();
00110    int length = msg->length();
00111 
00112    if ( length < 2 )
00113    {
00114       delete msg;
00115 #ifdef TIMING
00116       ActiveTimer.stop();
00117 #endif
00118       return false;
00119    }
00120 
00121    // Check the message type.
00122    if ( stateInfo->delegationDomain() != data[0] )
00123    {
00124       delete msg;
00125 #ifdef TIMING
00126       ActiveTimer.stop();
00127 #endif
00128       return false;
00129    }
00130    ++data;
00131    --length;
00132 
00133    if ( ClientDelegation::kAcceptKeyVerification != data[0] )
00134    {
00135       delete msg;
00136 #ifdef TIMING
00137       ActiveTimer.stop();
00138 #endif
00139       return false;
00140    }
00141    ++data;
00142    --length;
00143 
00144    // Check that it unmarshalls.
00145    CODEX_Ciphers::RSASignature signature;
00146    if ( NULL == signature.unmarshal( NULL, &data, length ) )
00147    {
00148       delete msg;
00149 #ifdef TIMING
00150       ActiveTimer.stop();
00151 #endif
00152       return false;
00153    }
00154    delete msg;
00155 
00156    CODEX_Server::ServerSignature* servSig = NULL;
00157    try
00158    {
00159       // Verify the signature.
00160       if ( ! serverState->publicKey(server).verifySignature(
00161          signature, m_digest ) )
00162       {
00163          throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00164                                                                    __LINE__ );
00165       }
00166 
00167       // Create a new ServerSignature.
00168       servSig = new CODEX_Server::ServerSignature( server, signature );
00169 
00170       // Add to the evidence set.
00171       m_evidence.append( servSig );
00172 
00173       // See if we have enough responses to create the threshold signature
00174       // request.
00175       CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00176       if ( NULL == qs )
00177       {
00178          throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00179       }
00180       if ( m_evidence.size() >= qs->quorumSize() )
00181       {
00182          const CODEX_Server::ServerState::LSType::LabelType& label =
00183             serverState->defaultSignatureLabel();
00184 
00185          SupportedKeyStoredMsg resp( m_response, m_evidence, label );
00186          unsigned char* seqNum = serverState->newSequenceNumber();
00187          stateInfo->registerSequenceNumber( seqNum, m_clientAct );
00188          SignWriteCallback* cb = new SignWriteCallback( m_deadPile,
00189                                                         m_queue,
00190                                                         m_clientAct,
00191                                                         resp,
00192                                                         seqNum,
00193                                                         m_destination );
00194 
00195          CODEX_Quorum::Message request;
00196          unsigned char self = serverState->hostNum();
00197          request.fill( self | CODEX_Server::ServerState::OutgoingMask );
00198          request.fill( seqNum, CODEX_Server::ServerState::nMID );
00199          request.fill( stateInfo->delegationDomain() );
00200          request.fill( ClientDelegation::kRequestSignature );
00201          request.fill( ClientDelegation::kSupportedKeyStoredMsg );
00202          int reqLen = resp.marshal(0);
00203          unsigned char* reqBuff = new unsigned char[reqLen];
00204          unsigned char* pReqBuff = reqBuff;
00205          resp.marshal(&pReqBuff);
00206          request.fill( reqBuff, reqLen );
00207          delete [] reqBuff;
00208 
00209          CODEX_Server::SignRequestEvent* event =
00210             new CODEX_Server::SignRequestEvent(this,
00211                                                m_destination,
00212                                                request,
00213                                                cb);
00214          sendEvent( event, 0 ); // no need to acknowledge
00215          m_complete = true;
00216       }
00217 #ifdef TIMING
00218       ActiveTimer.stop();
00219 #endif
00220       return true;
00221    }
00222    // This is a particularly bad error
00223    catch ( CODEX_Server::NoQuorumSystemException& e )
00224    {
00225       if ( NULL != servSig ) delete servSig;
00226       // We'll never be able to make progress, so re-throw.
00227 #ifdef TIMING
00228       ActiveTimer.stop();
00229 #endif
00230       throw;
00231    }
00232    catch ( ... )
00233    {
00234       if ( NULL != servSig ) delete servSig;
00235 #ifdef TIMING
00236       ActiveTimer.stop();
00237 #endif
00238       return false;
00239    }
00240 }

Generated on Wed Jun 2 16:32:57 2004 for COrnell Data EXchange (CODEX) by doxygen1.2.18