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

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

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