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

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

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