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

ClientMessageSigner.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: ClientMessageSigner.cc,v 1.4 2004/05/19 15:56:51 mmarsh Exp $
00008 //
00009 // $Log: ClientMessageSigner.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 "ClientMessageSigner.h"
00023 #include "CODEX_Server/ServerResponseEvent.h"
00024 #include "CODEX_Server/ServerState.h"
00025 #include "StateInfo.h"
00026 #include "ClientDelegation.h"
00027 #include "CODEX_Exceptions/BignumExceptions.h"
00028 
00029 #ifdef ELGAMAL
00030 #include "CODEX_ThresholdCrypto/DLProof.h"
00031 #endif
00032 
00033 #include "timing.h"
00034 
00035 using namespace CODEX_KeyService;
00036 
00037 ClientMessageSigner::ClientMessageSigner(
00038    CODEX_Events::DeadPileType& deadPile,
00039    CODEX_Events::QType& eventQueue,
00040    CODEX_Server::ServerResponseHandler* destination ):
00041    CODEX_Events::Activity( deadPile, eventQueue ),
00042    m_destination( destination )
00043 {
00044 }
00045 
00046 ClientMessageSigner::~ClientMessageSigner()
00047 {
00048 }
00049 
00050 bool
00051 ClientMessageSigner::handler( CODEX_Events::CloseEvent& event )
00052 {
00053    // just acknowledge
00054    sendEvent( 0, event.source() );
00055    return true;
00056 }
00057 
00058 bool
00059 ClientMessageSigner::handler( ClientMessageEvent< RequestKeyMsg >& event )
00060 {
00061    cerr <<
00062       "Error -- undecorated events should not be sent to ClientMessageSigner"
00063         << endl;
00064    ::exit(1);
00065    return true;
00066 }
00067 
00068 bool
00069 ClientMessageSigner::handler( ClientMessageEvent< SignedCreateKeyMsg >& event )
00070 {
00071    cerr <<
00072       "Error -- undecorated events should not be sent to ClientMessageSigner"
00073         << endl;
00074    ::exit(1);
00075    return true;
00076 }
00077 
00078 bool
00079 ClientMessageSigner::handler( ClientMessageEvent< SignedWriteKeyMsg >& event )
00080 {
00081    cerr <<
00082       "Error -- undecorated events should not be sent to ClientMessageSigner"
00083         << endl;
00084    ::exit(1);
00085    return true;
00086 }
00087 
00088 bool
00089 ClientMessageSigner::handler( ClientMessageEvent< SignedReadKeyMsg >& event )
00090 {
00091    cerr <<
00092       "Error -- undecorated events should not be sent to ClientMessageSigner"
00093         << endl;
00094    ::exit(1);
00095    return true;
00096 }
00097 
00098 bool
00099 ClientMessageSigner::handler(
00100    RoutedClientMessageEvent< SignedCreateKeyMsg >& event )
00101 {
00102    CODEX_Server::ServerState* serverState =
00103       CODEX_Server::ServerState::instance();
00104    if ( 0 == serverState )
00105    {
00106       return false;
00107    }
00108 
00109 #ifdef TIMING
00110    ActiveTimer.start();
00111 #endif
00112 
00113    CODEX_Quorum::Message msg;
00114    BIGNUM * digest = event.message().digest( serverState->hashFunc() );
00115    bool retVal =
00116       process( digest, event.source(), event, msg, event.failed() );
00117    BN_free(digest);
00118    int serverNum = msg.buffer()[0];
00119    sendEvent( new CODEX_Server::ServerResponseEvent(
00120       this, m_destination, msg, serverNum ), 0 );
00121 #ifdef TIMING
00122    ActiveTimer.stop();
00123 #endif
00124    return retVal;
00125 }
00126 
00127 bool
00128 ClientMessageSigner::handler(
00129    RoutedClientMessageEvent< SignedWriteKeyMsg >& event )
00130 {
00131    CODEX_Server::ServerState* serverState =
00132       CODEX_Server::ServerState::instance();
00133    if ( 0 == serverState )
00134    {
00135       return false;
00136    }
00137 
00138 #ifdef TIMING
00139    ActiveTimer.start();
00140 #endif
00141    CODEX_Quorum::Message msg;
00142    BIGNUM * digest = event.message().digest( serverState->hashFunc() );
00143    bool retVal =
00144       process( digest, event.source(), event, msg, event.failed() );
00145    BN_free(digest);
00146    int serverNum = msg.buffer()[0];
00147 
00148    if ( event.failed() )
00149    {
00150       sendEvent( new CODEX_Server::ServerResponseEvent(
00151          this, m_destination, msg, serverNum ), 0 );
00152 #ifdef TIMING
00153       ActiveTimer.stop();
00154 #endif
00155       return retVal;
00156    }
00157 
00158    sendEvent( new CODEX_Server::ServerResponseEvent(
00159       this, m_destination, msg, serverNum ), 0 );
00160 #ifdef TIMING
00161    ActiveTimer.stop();
00162 #endif
00163    return retVal;
00164 }
00165 
00166 bool
00167 ClientMessageSigner::handler(
00168    RoutedClientMessageEvent< LabeledReadKeyMsg >& event )
00169 {
00170    CODEX_Server::ServerState* serverState =
00171       CODEX_Server::ServerState::instance();
00172    if ( 0 == serverState )
00173    {
00174       return false;
00175    }
00176 
00177    StateInfo* stateInfo = StateInfo::instance();
00178    if ( 0 == stateInfo )
00179    {
00180       return false;
00181    }
00182 
00183 #ifdef TIMING
00184    ActiveTimer.start();
00185 #endif
00186 
00187    StateInfo::LSType keyShares;
00188    try
00189    {
00190       unsigned int server =
00191          event.server()[0] & ~(CODEX_Server::ServerState::OutgoingMask);
00192       keyShares = stateInfo->decryptionShares( event.message().label(),
00193                                                server );
00194    }
00195    catch ( CODEX_Server::InvalidLabelException& )
00196    {
00197       CODEX_Quorum::Message fmsg;
00198 
00199       unsigned char* server =
00200          new unsigned char[CODEX_Server::ServerState::nSID];
00201       if ( 0 == server )
00202       {
00203 #ifdef TIMING
00204          ActiveTimer.stop();
00205 #endif
00206          return false;
00207       }
00208       memcpy( server, event.server(), CODEX_Server::ServerState::nSID );
00209       // Make sure the "outgoing" mask isn't set.
00210       server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00211       fmsg.fill( server, CODEX_Server::ServerState::nSID );
00212 
00213       fmsg.fill( event.seqNum(), CODEX_Server::ServerState::nMID );
00214       fmsg.fill( stateInfo->delegationDomain() );
00215       fmsg.fill( ClientDelegation::kBadShareLabel );
00216       const StateInfo::LSType::LabelType& label =
00217          stateInfo->defaultDecryptionLabel();
00218       int length = label.marshal(0);
00219       unsigned char* buffer = new unsigned char[length];
00220       unsigned char* pBuffer = buffer;
00221       label.marshal(&pBuffer);
00222       fmsg.fill( buffer, length );
00223       delete [] buffer;
00224 
00225       sendEvent( new CODEX_Server::ServerResponseEvent(
00226          this, m_destination, fmsg, server[0] ), 0 );
00227       delete [] server;
00228 #ifdef TIMING
00229       ActiveTimer.stop();
00230 #endif
00231       return true;
00232    }
00233    catch ( CODEX_Server::KeySharesNotFoundException& )
00234    {
00235       sendEvent( 0, event.source(), true ); // NACK
00236 #ifdef TIMING
00237       ActiveTimer.stop();
00238 #endif
00239       return true;
00240    }      
00241 
00242    // Check if we have the (verified) key.
00243    const KeyInfo* kInfo =
00244       stateInfo->getKeyInfo( event.message().message().name().value() );
00245    if ( 0 == kInfo )
00246    {
00247       CODEX_Quorum::Message fmsg;
00248 
00249       unsigned char* server =
00250          new unsigned char[CODEX_Server::ServerState::nSID];
00251       if ( 0 == server )
00252       {
00253 #ifdef TIMING
00254          ActiveTimer.stop();
00255 #endif
00256          return false;
00257       }
00258       memcpy( server, event.server(), CODEX_Server::ServerState::nSID );
00259       // Make sure the "outgoing" mask isn't set.
00260       server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00261       fmsg.fill( server, CODEX_Server::ServerState::nSID );
00262 
00263       fmsg.fill( event.seqNum(), CODEX_Server::ServerState::nMID );
00264       fmsg.fill( stateInfo->delegationDomain() );
00265       fmsg.fill( ClientDelegation::kRejectClientRequest );
00266       sendEvent( new CODEX_Server::ServerResponseEvent(
00267          this, m_destination, fmsg, server[0] ), 0 );
00268       delete [] server;
00269 #ifdef TIMING
00270       ActiveTimer.stop();
00271 #endif
00272       return true;
00273    }
00274    const CODEX_Client::RequestCipherTextType& k = kInfo->keyValue();
00275    if ( ! ( k.initialized() && kInfo->verified() ) )
00276    {
00277       CODEX_Quorum::Message fmsg;
00278 
00279       unsigned char* server =
00280          new unsigned char[CODEX_Server::ServerState::nSID];
00281       if ( 0 == server )
00282       {
00283 #ifdef TIMING
00284          ActiveTimer.stop();
00285 #endif
00286          return false;
00287       }
00288       memcpy( server, event.server(), CODEX_Server::ServerState::nSID );
00289       // Make sure the "outgoing" mask isn't set.
00290       server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00291       fmsg.fill( server, CODEX_Server::ServerState::nSID );
00292 
00293       fmsg.fill( event.seqNum(), CODEX_Server::ServerState::nMID );
00294       fmsg.fill( stateInfo->delegationDomain() );
00295       fmsg.fill( ClientDelegation::kRejectClientRequest );
00296       sendEvent( new CODEX_Server::ServerResponseEvent(
00297          this, m_destination, fmsg, server[0] ), 0 );
00298       delete [] server;
00299 #ifdef TIMING
00300       ActiveTimer.stop();
00301 #endif
00302       return true;
00303    }
00304 
00305    // Now blind the ciphertext.
00306    const CODEX_ASN1::BigNumber& modulus =
00307 #ifndef ELGAMAL
00308       serverState->serviceKey().n()
00309 #else
00310       serverState->publicEGKey().p()
00311 #endif
00312       ;
00313 
00314    CODEX_Client::BlindCipherTextType* blindCipher =
00315       k.blind( event.message().message().blinding(), modulus );
00316 
00317    CODEX_Quorum::Message msg;
00318    BIGNUM * digest = 0;
00319    unsigned char* buff = 0;
00320    CODEX_ASN1::ustring* str = 0;
00321    try
00322    {
00323       int length = event.message().SignedReadKeyMsg::marshal(0);
00324       length += blindCipher->marshal(0);
00325       buff = new unsigned char[ length ];
00326       unsigned char* pBuff = buff;
00327       event.message().SignedReadKeyMsg::marshal(&pBuff);
00328       blindCipher->marshal(&pBuff);
00329       str = serverState->hashFunc()( CODEX_ASN1::ustring(buff,length) );
00330       delete [] buff;
00331       buff = 0;
00332       digest = BN_new();
00333       if ( 0 == digest )
00334       {
00335          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00336       }
00337       if ( 0 == BN_bin2bn( str->data(), str->length(), digest ) )
00338       {
00339          throw CODEX_Exceptions::BignumBin2BNException( __FILE__ , __LINE__ );
00340       }
00341 
00342       delete str;
00343    }
00344    catch ( ... )
00345    {
00346       if ( 0 != buff ) delete [] buff;
00347       if ( 0 != str ) delete str;
00348       if ( 0 != digest ) BN_free( digest );
00349       if ( 0 != blindCipher ) delete blindCipher;
00350 #ifdef TIMING
00351       ActiveTimer.stop();
00352 #endif
00353       throw;
00354    }
00355 
00356    bool retVal =
00357       process( digest, event.source(), event, msg, event.failed() );
00358    BN_free(digest);
00359    int serverNum = msg.buffer()[0];
00360 
00361    if ( event.failed() )
00362    {
00363       delete blindCipher;
00364       sendEvent( new CODEX_Server::ServerResponseEvent(
00365          this, m_destination, msg, serverNum ), 0 );
00366 #ifdef TIMING
00367       ActiveTimer.stop();
00368 #endif
00369       return retVal;
00370    }
00371 
00372    // Append the blinded ciphertext to the message.
00373    int length = blindCipher->marshal(0);
00374    unsigned char* buffer = new unsigned char[length];
00375    unsigned char* pBuffer = buffer;
00376    blindCipher->marshal(&pBuffer);
00377    msg.fill( buffer, length );
00378    delete [] buffer;
00379 
00380    // Now threshold decrypt the ciphertext.
00381    const StateInfo::ThresholdDecryptionType&
00382       thresholdDecryption = stateInfo->thresholdDecryption();
00383    StateInfo::ShareType decryptions;
00384    thresholdDecryption.decrypt( keyShares.share(), *blindCipher, decryptions );
00385    if ( ! decryptions.initialized() )
00386    {
00387       delete blindCipher;
00388 #ifdef TIMING
00389       ActiveTimer.stop();
00390 #endif
00391       return retVal;
00392    }
00393 
00394    // Append the partial decryptions to the message.
00395    length = decryptions.marshal(0);
00396    buffer = new unsigned char[length];
00397    pBuffer = buffer;
00398    decryptions.marshal(&pBuffer);
00399    msg.fill( buffer, length );
00400    delete [] buffer;
00401 
00402    // Calculate the discrete log proofs to demonstrate correctness
00403 #ifdef ELGAMAL
00404    CODEX_Server::ServerState::ShareSetType ss;
00405    ss.addShare( keyShares.share() );
00406    const unsigned int numShares = StateInfo::ShareType::NumShares;
00407    for ( unsigned int i = 0 ; i < numShares ; ++i )
00408    {
00409       // Record whether there's a proof entry for this index.
00410       CODEX_ASN1::Integer ai( ss(i).initialized() ? 1 : 0 );
00411       length = ai.marshal(0);
00412       buffer = new unsigned char[length];
00413       pBuffer = buffer;
00414       ai.marshal(&pBuffer);
00415       msg.fill( buffer, length );
00416       delete [] buffer;
00417 
00418       if ( ss(i).initialized() )
00419       {
00420          CODEX_ThresholdCrypto::DLProof proof(
00421             blindCipher->c1().value(),
00422             serverState->publicEGKey().g().value(),
00423             serverState->publicEGKey().p().value(),
00424             serverState->publicEGKey().p1(),
00425             ss(i).value(),
00426             serverState->hashFunc() );
00427 
00428          length = proof.marshal(0);
00429          buffer = new unsigned char[length];
00430          pBuffer = buffer;
00431          proof.marshal(&pBuffer);
00432          msg.fill( buffer, length );
00433          delete [] buffer;
00434       }
00435    }
00436 #endif
00437 
00438    delete blindCipher;
00439 
00440    // Send the resulting event.
00441    sendEvent( new CODEX_Server::ServerResponseEvent(
00442       this, m_destination, msg, serverNum ), 0 );
00443 #ifdef TIMING
00444    ActiveTimer.stop();
00445 #endif
00446    return retVal;
00447 }
00448 
00449 bool
00450 ClientMessageSigner::process( const BIGNUM* digest,
00451                               CODEX_Events::Activity* source,
00452                               const CODEX_Server::RoutingInfo& routingInfo,
00453                               CODEX_Quorum::Message& m,
00454                               bool failed )
00455 {
00456    unsigned char* server = new unsigned char[CODEX_Server::ServerState::nSID];
00457    if ( 0 == server )
00458    {
00459       return false;
00460    }
00461    memcpy( server, routingInfo.server(), CODEX_Server::ServerState::nSID );
00462    // Make sure the "outgoing" mask isn't set.
00463    server[0] &= ~(CODEX_Server::ServerState::OutgoingMask);
00464 
00465    StateInfo* stateInfo = StateInfo::instance();
00466    if ( 0 == stateInfo )
00467    {
00468       sendEvent( 0, source, true ); // NACK
00469       return true;
00470    }
00471 
00472    // Fill message headers.
00473    m.fill( server, CODEX_Server::ServerState::nSID );
00474    delete [] server;
00475    m.fill( routingInfo.seqNum(), CODEX_Server::ServerState::nMID );
00476    m.fill( stateInfo->delegationDomain() );
00477    if ( failed )
00478    {
00479       m.fill( ClientDelegation::kRejectClientRequest );
00480       return true;
00481    }
00482    m.fill( ClientDelegation::kApproveClientRequest );
00483 
00484    // Sign the request.
00485    CODEX_Server::ServerState* serverState =
00486       CODEX_Server::ServerState::instance();
00487    if ( 0 == serverState )
00488    {
00489       sendEvent( 0, source, true ); // NACK
00490       return true;
00491    }
00492    const CODEX_Ciphers::RSAPrivateKey& key = serverState->privateKey();
00493    CODEX_Ciphers::RSASignature* signature = key.sign( digest );
00494    if ( 0 == signature )
00495    {
00496       sendEvent( 0, source, true ); // NACK
00497       return true;
00498    }
00499    int length = signature->marshal(0);
00500    unsigned char* buffer = new unsigned char[length];
00501    unsigned char* pBuffer = buffer;
00502    signature->marshal(&pBuffer);
00503    m.fill( buffer, length );
00504    delete [] buffer;
00505    delete signature;
00506 
00507    sendEvent( 0, source );
00508    return true;
00509 }

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