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

SignReadCallback.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: SignReadCallback.cc,v 1.3 2004/05/19 15:56:52 mmarsh Exp $
00008 //
00009 // $Log: SignReadCallback.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:52  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.2  2003/11/04 22:31:49  mmarsh
00014 // *** empty log message ***
00015 //
00016 //
00017 
00018 #include "SignReadCallback.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 "CODEX_Server/SignRequestEvent.h"
00025 #include "ClientDelegation.h"
00026 #include "CODEX_Server/ShareLabelChallenge.h"
00027 
00028 #include "timing.h"
00029 
00030 using namespace CODEX_KeyService;
00031 
00032 SignReadCallback::SignReadCallback(
00033    CODEX_Events::DeadPileType& deadPile,
00034    CODEX_Events::QType& eventQueue,
00035    ClientResponseHandler* destination,
00036    const RequestType& request,
00037    const unsigned char* seqNum,
00038    CODEX_Server::SignRequestHandler* reqHandler ) :
00039    ResponseCallback( seqNum ),
00040    CODEX_Events::Activity( deadPile, eventQueue ),
00041    m_destination( destination ),
00042    m_request( request ),
00043    m_complete( false ),
00044    m_reqHandler( reqHandler )
00045 {
00046    m_digest = m_request.response().upcast().digest(
00047       CODEX_Server::ServerState::instance()->hashFunc() );
00048 }
00049 
00050 SignReadCallback::~SignReadCallback()
00051 {
00052    if ( 0 != m_digest ) BN_free( m_digest );
00053    while ( m_signatures.size() )
00054    {
00055       delete m_signatures.back();
00056       m_signatures.pop_back();
00057    }
00058    ChallengeVector::iterator vItr = m_challenges.begin();
00059    ChallengeVector::iterator vEnd = m_challenges.end();
00060    for ( ; vItr != vEnd ; ++vItr )
00061    {
00062       delete *vItr;
00063    }
00064 }
00065 
00067 bool
00068 SignReadCallback::operator()( unsigned int server,
00069                               CODEX_Quorum::Message* msg )
00070 {
00071    if ( 0 == msg )
00072    {
00073       return false;
00074    }
00075 
00076    if ( m_complete )
00077    {
00078       delete msg;
00079       return true;
00080    }
00081 
00082 #ifdef TIMING
00083    ActiveTimer.start();
00084 #endif
00085 
00086    CODEX_Server::ServerState* serverState =
00087       CODEX_Server::ServerState::instance();
00088    if ( 0 == serverState )
00089    {
00090       delete msg;
00091 #ifdef TIMING
00092       ActiveTimer.stop();
00093 #endif
00094       return false;
00095    }
00096 
00097    StateInfo* stateInfo = StateInfo::instance();
00098    if ( 0 == stateInfo )
00099    {
00100       delete msg;
00101 #ifdef TIMING
00102       ActiveTimer.stop();
00103 #endif
00104       return false;
00105    }
00106 
00107    // Sanity check -- is our destination still valid?
00108    if ( 0 == stateInfo->getActFromSeqNum( seqNum() ) )
00109    {
00110       delete msg;
00111 #ifdef TIMING
00112       ActiveTimer.stop();
00113 #endif
00114       return false;
00115    }
00116 
00117    CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00118    if ( 0 == qs )
00119    {
00120       delete msg;
00121 #ifdef TIMING
00122       ActiveTimer.stop();
00123 #endif
00124       throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00125    }
00126 
00127    unsigned char* data = (unsigned char*)msg->buffer();
00128    int length = msg->length();
00129 
00130    if ( length < 2 )
00131    {
00132       delete msg;
00133 #ifdef TIMING
00134       ActiveTimer.stop();
00135 #endif
00136       return false;
00137    }
00138 
00139    // Check the message type.
00140    if ( stateInfo->delegationDomain() != data[0] )
00141    {
00142       delete msg;
00143 #ifdef TIMING
00144       ActiveTimer.stop();
00145 #endif
00146       return false;
00147    }
00148    ++data;
00149    --length;
00150 
00151    // Test a special condition
00152    if ( ClientDelegation::kBadShareLabel == data[0] )
00153    {
00154       cerr << __FILE__ << ", line " << __LINE__ << ":\n"
00155            << "   kBadShareLabel returned" << endl;
00156       ++data;
00157       --length;
00158       // We need to re-send the request with the new label, but only if
00159       // the label returned is actually valid.
00160       CODEX_Server::ServerState::LSType::LabelType label;
00161       if ( 0 == label.unmarshal( 0, &data, length ) )
00162       {
00163          // The response is no good.
00164          delete msg;
00165 #ifdef TIMING
00166          ActiveTimer.stop();
00167 #endif
00168          return false;
00169       }
00170       RequestType newReq( m_request.response(),
00171                           m_request.request(),
00172                           m_request.evidence(),
00173                           label );
00174       const unsigned char* newSeqNum = serverState->newSequenceNumber();
00175       stateInfo->registerSequenceNumber( newSeqNum, m_destination );
00176       SignReadCallback* cb = new SignReadCallback( m_deadPile,
00177                                                    m_queue,
00178                                                    m_destination,
00179                                                    newReq,
00180                                                    newSeqNum,
00181                                                    m_reqHandler );
00182 
00183       CODEX_Quorum::Message message;
00184       unsigned char self = serverState->hostNum();
00185       message.fill( self | CODEX_Server::ServerState::OutgoingMask );
00186       message.fill( newSeqNum, CODEX_Server::ServerState::nMID );
00187       message.fill( stateInfo->delegationDomain() );
00188       message.fill( ClientDelegation::kRequestSignature );
00189       message.fill( CODEX_Client::kBlindKeyMsg );
00190       int length = newReq.marshal(0);
00191       unsigned char* buffer = new unsigned char[length];
00192       unsigned char* pBuffer = buffer;
00193       newReq.marshal(&pBuffer);
00194       message.fill( buffer, length );
00195       delete [] buffer;
00196 
00197       // Create the outgoing event.
00198       CODEX_Server::SignRequestEvent* outEvent =
00199          new CODEX_Server::SignRequestEvent( this,
00200                                              m_reqHandler,
00201                                              message,
00202                                              cb );
00203       CODEX_Server::ShareLabelChallenge* slc =
00204          new CODEX_Server::ShareLabelChallenge( label, server, cb, outEvent );
00205       m_challenges.push_back( slc );
00206       if ( m_challenges.size() > qs->faultsTolerated() )
00207       {
00208          // register challenges
00209          ChallengeVector::iterator vItr = m_challenges.begin();
00210          ChallengeVector::iterator vEnd = m_challenges.end();
00211          for ( ; vItr != vEnd ; ++vItr )
00212          {
00213             serverState->addChallenge( seqNum() , *vItr );
00214          }
00215          m_challenges.clear();
00216          // No progress will be made on this request.
00217          m_complete = true;
00218       }
00219       delete msg;
00220 #ifdef TIMING
00221       ActiveTimer.stop();
00222 #endif
00223       return true;
00224    }
00225 
00226    if ( ClientDelegation::kAcceptSignatureRequest != data[0] )
00227    {
00228       delete msg;
00229 #ifdef TIMING
00230       ActiveTimer.stop();
00231 #endif
00232       return false;
00233    }
00234    ++data;
00235    --length;
00236 
00237    // Check that it unmarshalls.
00238    typedef CODEX_Server::ServerState::ShareType ShareType;
00239    ShareType* signatures = new ShareType;
00240    if ( 0 == signatures->unmarshal( 0, &data, length ) )
00241    {
00242       delete msg;
00243 #ifdef TIMING
00244       ActiveTimer.stop();
00245 #endif
00246       return false;
00247    }
00248    delete msg;
00249    m_signatures.push_back( signatures );
00250 
00251    // See if we have enough responses to create the threshold signature.
00252    typedef CODEX_Client::SignedBlindKeyMsg MsgType;
00253 
00254    const CODEX_Server::ServerState::ThresholdRSAType& thresholdRSA =
00255       serverState->thresholdRSA();
00256 
00257    // optimistic case
00258    if ( m_signatures.size() > CODEX_Server::ServerState::nFaults )
00259    {
00260       CODEX_Server::ServerState::ShareSetType partials;
00261       SignatureArray::const_iterator itr = m_signatures.begin();
00262       SignatureArray::const_iterator end = m_signatures.end();
00263       for ( ; itr != end ; ++itr )
00264       {
00265          partials.addShare( **itr );
00266       }
00267       // Get the threshold signature, verify it, and if OK respond.
00268       BIGNUM * tsig = thresholdRSA.threshold( partials );
00269       if ( 0 != tsig )
00270       {
00271          try
00272          {
00273             CODEX_Ciphers::RSASignature sig(tsig);
00274             const CODEX_Ciphers::RSAPublicKey& serviceKey =
00275                serverState->serviceKey();
00276             if ( ! serviceKey.initialized() )
00277             {
00278                throw CODEX_Server::PublicKeyNotFoundException( __FILE__ ,
00279                                                                __LINE__ );
00280             }
00281             if ( serviceKey.verifySignature( sig, m_digest ) )
00282             {
00283                ClientResponseEvent< MsgType >* event = new
00284                   ClientResponseEvent< MsgType >(
00285                      this,
00286                      m_destination,
00287                      MsgType(m_request.response(), sig) );
00288                sendEvent( event, 0 ); // no need to acknowledge
00289                serverState->removeChallenge( seqNum() );
00290                m_complete = true;
00291                // We're done.
00292 #ifdef TIMING
00293                ActiveTimer.stop();
00294 #endif
00295                return true;
00296             }
00297          }
00298          catch ( ... )
00299          {
00300          }
00301       }
00302    }
00303 
00304    // Wait for a full quorum and try all possible combinations until one
00305    // works.
00306    if ( m_signatures.size() >= qs->quorumSize() )
00307    {
00308       BIGNUM* tsig = serverState->thresholdOperation( m_signatures, m_digest );
00309       if ( 0 != tsig )
00310       {
00311          CODEX_Ciphers::RSASignature sig(tsig);
00312          ClientResponseEvent< MsgType >* event = new
00313             ClientResponseEvent< MsgType >(
00314                this,
00315                m_destination,
00316                MsgType(m_request.response(), sig) );
00317          sendEvent( event, 0 ); // no need to acknowledge
00318          serverState->removeChallenge( seqNum() );
00319          m_complete = true;
00320       }
00321       else
00322       {
00323          // There was a problem
00324          sendEvent( new CODEX_Events::CloseEvent( this, m_destination ), 0 );
00325       }
00326    }
00327 #ifdef TIMING
00328    ActiveTimer.stop();
00329 #endif
00330    return true;
00331 }

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