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

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

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