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

ServerState.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: ServerState.cc,v 1.4 2004/05/19 15:56:59 mmarsh Exp $
00008 //
00009 // $Log: ServerState.cc,v $
00010 // Revision 1.4  2004/05/19 15:56:59  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.3  2003/11/04 22:19:55  mmarsh
00014 // The ElGamal public key is handled here, not in CODEX_Client.  All
00015 // black magic relating to switching between cryptosystems used for
00016 // key service decryption has been moved to CODEX_KeyService, where
00017 // it belongs.  This package is no longer dependent on CODEX_Client.
00018 //
00019 //
00020 
00021 #include <fstream>
00022 #include <sstream>
00023 #include <openssl/conf.h>
00024 
00025 #include "ServerState.h"
00026 #include "CODEX_ASN1/Integer.h"
00027 #include "CODEX_Exceptions/FileExceptions.h"
00028 #include "ServerExceptions.h"
00029 #include "ConfigurationExceptions.h"
00030 #include "ShareLabelChallenge.h"
00031 
00032 using namespace CODEX_Server;
00033 
00034 ServerState* ServerState::m_instance = 0;
00035 
00036 
00037 //=============================================================
00038 // Constructors and destructors
00039 //=============================================================
00040 
00041 ServerState*
00042 ServerState::instance()
00043 {
00044    if ( 0 == m_instance )
00045    {
00046       m_instance = new ServerState;
00047    }
00048    return m_instance;
00049 }
00050 
00051 void
00052 ServerState::destroy()
00053 {
00054    if ( 0 != m_instance )
00055    {
00056       delete m_instance;
00057    }
00058    m_instance = 0;
00059 }
00060 
00061 ServerState::ServerState() :
00062    m_quorumSystem( 0 ),
00063    m_serverOutSocketBuilder( 0 ),
00064    m_serverInSocketBuilder( 0 ),
00065    m_rsa( 0 ),
00066    m_thresholdRSA( CODEX_ASN1::BigNumber() ),
00067    m_thresholdVarRSA( CODEX_ASN1::BigNumber() ),
00068    m_defaultRSAShareCB( 0 ),
00069    m_rsaShareCallback( 0 ),
00070    m_rsaDefaultLabel( 0 ),
00071    m_thresholdEG( CODEX_ASN1::BigNumber() ),
00072    m_defaultEGShareCB( 0 ),
00073    m_egShareCallback( 0 ),
00074    m_egDefaultLabel( 0 ),
00075    m_caKey( 0 )
00076 {
00077    for ( unsigned int i = 0 ; i < nMID ; ++i )
00078    {
00079       m_seqNum[i] = 0U;
00080    }
00081 }
00082 
00083 ServerState::~ServerState()
00084 {
00085    if ( 0 != m_caKey ) EVP_PKEY_free( m_caKey );
00086    if ( 0 != m_rsa ) RSA_free( m_rsa );
00087    if ( 0 != m_serverOutSocketBuilder ) delete m_serverOutSocketBuilder;
00088    if ( 0 != m_serverInSocketBuilder ) delete m_serverInSocketBuilder;
00089    if ( 0 != m_quorumSystem ) delete m_quorumSystem;
00090    if ( 0 != m_defaultRSAShareCB ) delete m_defaultRSAShareCB;
00091    if ( 0 != m_defaultEGShareCB ) delete m_defaultEGShareCB;
00092 //   while ( ! m_serverList.empty() )
00093 //   {
00094 //      delete m_serverList.back();
00095 //      m_serverList.pop_back();
00096 //   }
00097    while ( ! m_deadServerList.empty() )
00098    {
00099       delete m_serverList.back();
00100       m_serverList.pop_back();
00101    }
00102 }
00103 
00104 
00105 //=============================================================
00106 // Configuration
00107 //=============================================================
00108 
00109 void
00110 ServerState::configure( const CONF* conf,
00111                         const char* sec,
00112                         const string& fname )
00113 {
00114    // The number of servers is fixed at compile time, so this is just
00115    // a consistency check.  Later versions may have run-time-configured
00116    // systems, in which case nhosts will be a more meaningful field.
00117    long dummy;
00118    if ( ! NCONF_get_number_e(conf,sec,"nhosts",&dummy) )
00119    {
00120       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00121                                             fname, "nhosts" );
00122    }
00123    unsigned long uDummy = dummy;
00124    if ( nServers > uDummy )
00125    {
00126       throw BCBadValueException( __FILE__ , __LINE__ , fname, "nhosts" );
00127    }
00128 
00129    if ( ! NCONF_get_number_e(conf,sec,"hostnum",&m_hostNum) )
00130    {
00131       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00132                                             fname, "hostnum" );
00133    }
00134    if ( (m_hostNum < 0) || (m_hostNum >= nServers) )
00135    {
00136       throw BCBadValueException( __FILE__ , __LINE__ , fname, "hostnum" );
00137    }
00138 
00139    const char* ciphers = NCONF_get_string(conf,sec,"ciphers");
00140    if ( 0 == ciphers )
00141    {
00142       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00143                                             fname, "ciphers" );
00144    }
00145 
00146    // Default server-to-server port.
00147    long serverPort;
00148    if ( ! NCONF_get_number_e(conf,sec,"server_port",&serverPort) )
00149    {
00150       serverPort = 0;
00151    }
00152 
00153    const char* file = 0;
00154 
00155    // CA's certificate
00156    const char* caCertFile = NCONF_get_string(conf,sec,"ca_cert_file");
00157    if ( 0 == caCertFile )
00158    {
00159       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00160                                             fname, "ca_cert_file" );
00161    }
00162    readCACert( caCertFile );
00163 
00164    // Service certificate
00165    file = NCONF_get_string(conf,sec,"service_cert_file");
00166    if ( 0 == file )
00167    {
00168       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00169                                             fname, "service_cert_file" );
00170    }
00171    readServiceCert( file );
00172 
00173    // Service ElGamal public key
00174    file = NCONF_get_string(conf,sec,"service_eg_public_file");
00175    if ( 0 == file )
00176    {
00177       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00178                                             fname, "service_eg_public_file" );
00179    }
00180    readPublicEGKey( file );
00181    // Verify the signature
00182    bool okKey = m_signedEGKey.verify( serviceKey(), m_hashFunc );
00183 //   BIGNUM * digest = m_signedEGKey.key().digest( m_hashFunc );
00184 //   bool okKey = serviceKey().verifySignature( m_signedEGKey.signature(),
00185 //                                              digest );
00186 //   BN_free( digest );
00187    if ( ! okKey )
00188    {
00189       throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00190    }
00191 
00192    // Server private key
00193    file = NCONF_get_string(conf,sec,"server_private_file");
00194    if ( 0 == file )
00195    {
00196       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00197                                             fname, "server_private_file" );
00198    }
00199    readPrivateKey( file, NCONF_get_string(conf,sec,"private_key_passwd") );
00200 
00201    // Shares of the service RSA private key
00202    file = NCONF_get_string(conf,sec,"rsa_shares_file");
00203    if ( 0 == file )
00204    {
00205       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00206                                             fname, "rsa_shares_file" );
00207    }
00208    readRSAShares( file );
00209    m_thresholdRSA = ThresholdRSAType( m_serviceKey.n() );
00210    m_thresholdVarRSA = ThresholdVarRSAType( m_serviceKey.n() );
00211    m_defaultRSAShareCB =
00212       new DefaultShareCallback< ShareType , OneWay >( &m_rsaShares );
00213    m_rsaShareCallback = m_defaultRSAShareCB;
00214    m_rsaInitialLabel = m_rsaShares.label();
00215    m_rsaDefaultLabel = &m_rsaInitialLabel;
00216 
00217    // Witness for the RSA private key
00218    file = NCONF_get_string(conf,sec,"rsa_witness_file");
00219    if ( 0 == file )
00220    {
00221       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00222                                             fname, "rsa_witness_file" );
00223    }
00224    if ( 0 == m_rsaWitness.fromFile( file ) )
00225    {
00226       throw CODEX_Exceptions::FileCannotOpenException( __FILE__ , __LINE__ ,
00227                                                        file );
00228    }
00229 
00230    // Shares of the service ElGamal private key
00231    file = NCONF_get_string(conf,sec,"elgamal_shares_file");
00232    if ( 0 == file )
00233    {
00234       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00235                                             fname, "elgamal_shares_file" );
00236    }
00237    readElGamalShares( file );
00238    m_thresholdEG = ThresholdElGamalType( m_signedEGKey.key().key().p() );
00239    m_defaultEGShareCB =
00240       new DefaultShareCallback< ShareType , OneWay >( &m_elgamalShares );
00241    m_egShareCallback = m_defaultEGShareCB;
00242    m_egInitialLabel = m_elgamalShares.label();
00243    m_egDefaultLabel = &m_egInitialLabel;
00244 
00245    // Witness for the ElGamal private key
00246    file = NCONF_get_string(conf,sec,"elgamal_witness_file");
00247    if ( 0 == file )
00248    {
00249       throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00250                                             fname, "elgamal_witness_file" );
00251    }
00252    if ( 0 == m_egWitness.fromFile( file ) )
00253    {
00254       throw CODEX_Exceptions::FileCannotOpenException( __FILE__ , __LINE__ ,
00255                                                        file );
00256    }
00257 
00258    const char* hostCertFile = 0;
00259 
00260    // Public information regarding each server in the quorum system
00261    for ( int i=0 ; i < nServers ; ++i )
00262    {
00263       ostringstream nstr;
00264       nstr << "host" << i;
00265       const char* ncstr = nstr.str().c_str();
00266       const char* hostname = NCONF_get_string(conf,sec,ncstr);
00267       if ( 0 == hostname )
00268       {
00269          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00270                                                fname, nstr.str() );
00271       }
00272       m_hostnames[i] = hostname;
00273 
00274       ostringstream pstr;
00275       pstr << "server_port" << i;
00276       const char* pcstr = pstr.str().c_str();
00277       long port;
00278       if ( NCONF_get_number_e(conf,sec,pcstr,&port) &&
00279            ( port > 0 ) )
00280       {
00281          m_serverPorts[i] = port;
00282       }
00283       else if ( serverPort > 0 )
00284       {
00285          m_serverPorts[i] = serverPort;
00286       }
00287       else
00288       {
00289          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00290                                                fname, pstr.str() );
00291       }
00292 
00293       ostringstream cstr;
00294       cstr << "server" << i << "_cert_file";
00295       const char* ccstr = cstr.str().c_str();
00296       const char* certFile = NCONF_get_string(conf,sec,ccstr);
00297       if ( 0 == certFile )
00298       {
00299          throw BCParameterNotDefinedException( __FILE__ , __LINE__ ,
00300                                                fname, cstr.str() );
00301       }
00302       m_serverCerts[i].fromPEMFile( certFile );
00303       if ( i == m_hostNum )
00304       {
00305          hostCertFile = certFile;
00306       }
00307    }
00308 
00309    // Create the SSL socket builders
00310    SSL_METHOD * cmeth = TLSv1_client_method();
00311    SSL_METHOD * smeth = TLSv1_server_method();
00312    m_serverOutSocketBuilder =
00313       new CODEX_SSL::SSLSocketBuilder( cmeth,
00314                                        m_serverCerts[ m_hostNum ].value(),
00315                                        m_rsa,
00316                                        ciphers,
00317                                        caCertFile,
00318                                        hostCertFile,
00319                                        SSL_VERIFY_PEER
00320                                        // The rest of the args can default
00321          );
00322    m_serverInSocketBuilder =
00323       new CODEX_SSL::SSLSocketBuilder( smeth,
00324                                        m_serverCerts[ m_hostNum ].value(),
00325                                        m_rsa,
00326                                        ciphers,
00327                                        caCertFile,
00328                                        hostCertFile,
00329                                        ( SSL_VERIFY_PEER |
00330                                          SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
00331                                          SSL_VERIFY_CLIENT_ONCE )
00332                                        // The rest of the args can default
00333          );
00334 
00335    // Create the quorum system
00336    unsigned char* self = new unsigned char[nSID];
00337    self[0] = m_hostNum;
00338    m_quorumSystem = new QSType(
00339       new CODEX_Quorum::ConcreteResponseTracker< nSID , nMID >( self ) );
00340    // Connect to ourself
00341    addQuorumServer( m_hostNum,
00342                     new CODEX_Quorum::AsynchronousRemoteServer(
00343                        m_hostnames[ m_hostNum ],
00344                        m_serverPorts[ m_hostNum ],
00345                        m_loopbackSocketBuilder ) );
00346 }
00347 
00348 void
00349 ServerState::readPrivateKey( const char* fname, const char* passwd )
00350 {
00351    FILE* fp = 0;
00352 
00353    try
00354    {
00355       fp = fopen( fname, "r" );
00356       if ( 0 == fp )
00357       {
00358          throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00359                                                           __LINE__ , fname );
00360       }
00361       if ( ! PEM_read_RSAPrivateKey( fp, &m_rsa, 0, (void*)passwd ) )
00362       {
00363          throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00364                                                           __LINE__ , fname );
00365       }
00366       fclose( fp );
00367       fp = 0;
00368       m_privateKey = CODEX_Ciphers::RSAPrivateKey( BN_dup( m_rsa->p ),
00369                                                    BN_dup( m_rsa->q ),
00370                                                    BN_dup( m_rsa->d ),
00371                                                    BN_dup( m_rsa->n ) );
00372    }
00373    catch ( ... )
00374    {
00375       if ( 0 != fp ) fclose(fp);
00376       throw;
00377    }
00378 }
00379 
00380 const CODEX_ASN1::Certificate&
00381 ServerState::serverCert( unsigned int i ) const
00382 {
00383    if ( i >= nServers )
00384    {
00385       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00386    }
00387    return m_serverCerts[i];
00388 }
00389 
00390 const CODEX_Ciphers::RSAPublicKey&
00391 ServerState::publicKey()
00392 {
00393    if ( ! m_publicKeys[m_hostNum].initialized() )
00394    {
00395       if ( m_serverCerts[m_hostNum].initialized() )
00396       {
00397          m_publicKeys[m_hostNum] =
00398             CODEX_Ciphers::RSAPublicKey( m_serverCerts[m_hostNum].value() );
00399       }
00400    }
00401    return m_publicKeys[m_hostNum];
00402 }
00403 
00404 const CODEX_Ciphers::RSAPublicKey&
00405 ServerState::publicKey( unsigned int i )
00406 {
00407    if ( i >= nServers )
00408    {
00409       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00410    }
00411 
00412    if ( ! m_publicKeys[i].initialized() )
00413    {
00414       if ( m_serverCerts[i].initialized() )
00415       {
00416          m_publicKeys[i] =
00417             CODEX_Ciphers::RSAPublicKey( m_serverCerts[i].value() );
00418       }
00419    }
00420    return m_publicKeys[i];
00421 }
00422 
00423 void
00424 ServerState::readCACert( const char* fname )
00425 {
00426    if ( ! m_caCert.fromPEMFile( fname ) )
00427    {
00428       throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00429                                                        __LINE__ ,
00430                                                        fname );
00431    }
00432 }
00433 
00435 const EVP_PKEY*
00436 ServerState::caKey()
00437 {
00438    if ( 0 == m_caKey )
00439    {
00440       if ( ! m_caCert.initialized() )
00441       {
00442          return 0;
00443       }
00444       m_caKey = X509_get_pubkey( (X509*) m_caCert.value() );
00445    }
00446    return m_caKey;
00447 }
00448 
00449 void
00450 ServerState::readServiceCert( const char* fname )
00451 {
00452    m_serviceCert.fromPEMFile( fname );
00453 }
00454 
00455 const CODEX_Ciphers::RSAPublicKey&
00456 ServerState::serviceKey()
00457 {
00458    if ( ! m_serviceKey.initialized() )
00459    {
00460       if ( m_serviceCert.initialized() )
00461       {
00462          m_serviceKey = CODEX_Ciphers::RSAPublicKey( m_serviceCert.value() );
00463       }
00464    }
00465    return m_serviceKey;
00466 }
00467 
00469 void
00470 ServerState::readPublicEGKey( const char* fname )
00471 {
00472    ifstream is(fname);
00473    if ( ! is.is_open() )
00474    {
00475       throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00476                                                        __LINE__ ,
00477                                                        fname );
00478    }
00479    string s;
00480    char ch;
00481    while ( is.get(ch) )
00482    {
00483       s.push_back(ch);
00484    }
00485    //basic_string<unsigned char> s;
00486    //is >> s;
00487    unsigned int length = s.length();
00488    unsigned char* p = new unsigned char[length];
00489    unsigned char* pOrig = p;
00490    for ( unsigned int i = 0 ; i < length ; ++i )
00491    {
00492       p[i] = s.data()[i];
00493    }
00494    //unsigned char* p = (unsigned char*)s.data();
00495    if ( 0 == m_signedEGKey.unmarshal(0,&p,length) )
00496    {
00497       delete [] pOrig;
00498       throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00499    }
00500    delete [] pOrig;
00501 }
00502 
00503 void
00504 ServerState::readRSAShares( const char* fname )
00505 {
00506    if ( ! serviceKey().initialized() )
00507    {
00508       throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00509    }
00510    if ( 0 == m_rsaShares.fromFile( fname ) )
00511    {
00512       throw KeySharesNotFoundException( __FILE__ , __LINE__ );
00513    }
00514 }
00515 
00516 void
00517 ServerState::readElGamalShares( const char* fname )
00518 {
00519    if ( ! m_signedEGKey.initialized() )
00520    {
00521       throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00522    }
00523    if ( 0 == m_elgamalShares.fromFile( fname ) )
00524    {
00525       throw KeySharesNotFoundException( __FILE__ , __LINE__ );
00526    }
00527 }
00528 
00529 
00530 //=============================================================
00531 // Server management
00532 //=============================================================
00533 
00534 void
00535 ServerState::addServer( CODEX_Quorum::LocalServer* server )
00536 {
00537    m_serverList.push_back( server );
00538 }
00539 
00540 void
00541 ServerState::removeServer( CODEX_Quorum::LocalServer* server )
00542 {
00543    m_serverList.remove( server );
00544 }
00545 
00546 void
00547 ServerState::cleanServer( CODEX_Quorum::LocalServer* server )
00548 {
00549    m_deadServerList.push_back( server );
00550 }
00551 
00552 void
00553 ServerState::garbageCollectServers()
00554 {
00555    while ( m_deadServerList.size() )
00556    {
00557       CODEX_Quorum::LocalServer* ls = m_deadServerList.front();
00558       m_deadServerList.pop_front();
00559       delete ls;
00560    }
00561 }
00562 
00563 
00564 //=============================================================
00565 // Secret sharing utilities
00566 //=============================================================
00567 const ServerState::LSType&
00568 ServerState::rsaShares( const LSType::LabelType& label,
00569                         unsigned int server ) const
00570 {
00571    if ( 0 == m_rsaShareCallback )
00572    {
00573       throw KeySharesNotFoundException( __FILE__ , __LINE__ );
00574    }
00575    return (*m_rsaShareCallback)( label, server );
00576 }
00577 
00578 const ServerState::LSType::LabelType&
00579 ServerState::defaultRSALabel() const
00580 {
00581    if ( 0 == m_rsaDefaultLabel )
00582    {
00583       throw KeySharesNotFoundException( __FILE__ , __LINE__ );
00584    }
00585    return (*m_rsaDefaultLabel);
00586 }
00587 
00588 const ServerState::LSType&
00589 ServerState::elgamalShares( const LSType::LabelType& label,
00590                         unsigned int server ) const
00591 {
00592    if ( 0 == m_egShareCallback )
00593    {
00594       throw KeySharesNotFoundException( __FILE__ , __LINE__ );
00595    }
00596    return (*m_egShareCallback)( label, server );
00597 }
00598 
00599 const ServerState::LSType::LabelType&
00600 ServerState::defaultEGLabel() const
00601 {
00602    if ( 0 == m_egDefaultLabel )
00603    {
00604       throw KeySharesNotFoundException( __FILE__ , __LINE__ );
00605    }
00606    return (*m_egDefaultLabel);
00607 }
00608 
00609 const ServerState::ThresholdSignatureType&
00610 ServerState::thresholdSignature() const
00611 {
00612    return thresholdRSA();
00613 //   return thresholdTemplate< ThresholdSignatureType >();
00614 }
00615 
00616 const ServerState::LSType::LabelType&
00617 ServerState::defaultLabel( unsigned int num ) const
00618 {
00619    if ( RSAKeyNum == num )
00620    {
00621       return defaultRSALabel();
00622    }
00623    if ( EGKeyNum == num )
00624    {
00625       return defaultEGLabel();
00626    }
00627    throw UnknownSecretNumberException( __FILE__ , __LINE__ , num );
00628 }
00629 
00630 void
00631 ServerState::setShareCallback( unsigned int num, const ShareCallback* cb )
00632 {
00633    if ( RSAKeyNum == num )
00634    {
00635       setRSAShareCallback( cb );
00636       return;
00637    }
00638    if ( EGKeyNum == num )
00639    {
00640       setEGShareCallback( cb );
00641       return;
00642    }
00643    // otherwise ignore
00644 }
00645 
00646 void
00647 ServerState::setDefaultLabel( const LSType::LabelType* label )
00648 {
00649    if ( 0 == label )
00650    {
00651       return;
00652    }
00653    unsigned int num = label->num().value();
00654    if ( RSAKeyNum == num )
00655    {
00656       setRSADefaultLabel( label );
00657       return;
00658    }
00659    if ( EGKeyNum == num )
00660    {
00661       setEGDefaultLabel( label );
00662    }
00663    // otherwise ignore
00664 }
00665 
00666 void
00667 ServerState::rationalizeSharings(
00668    const vector< ShareType* >& sharings,
00669    ShareSetType& result ) const
00670 {
00671    typedef vector< ShareType > VSSVec;
00672    const unsigned int nShares = ShareType::NumShares;
00673    unsigned int bestGuess[nShares];
00674    unsigned int guessCount[nShares];
00675    unsigned int veclen = sharings.size();
00676    for ( unsigned int i = 0 ; i < nShares ; ++i )
00677    {
00678       guessCount[i] = 0;
00679       bestGuess[i] = veclen;
00680       for ( unsigned int j = 0 ; j < veclen ; ++j )
00681       {
00682          if ( sharings[j]->initialized() &&
00683               sharings[j]->share(i).initialized() )
00684          {
00685             bestGuess[i] = j;
00686             guessCount[i] = 1;
00687             break;
00688          }
00689       }
00690    }
00691    for ( unsigned int i = 0 ; i < nShares ; ++i )
00692    {
00693       while ( ( ! result(i).initialized() ) &&
00694               ( bestGuess[i] < veclen ) )
00695       {
00696          for ( unsigned int j = bestGuess[i] + 1 ; j < veclen ; ++j )
00697          {
00698             if ( sharings[j]->initialized() &&
00699                  sharings[j]->share(i).initialized() &&
00700                  ( 0 == BN_cmp( sharings[j]->share(i).value(),
00701                                 sharings[bestGuess[i]]->share(i).value() ) ) )
00702             {
00703                ++guessCount[i];
00704             }
00705          }
00706          if ( guessCount[i] > ServerState::nFaults )
00707          {
00708             result.setShare(i,sharings[bestGuess[i]]->share(i));
00709          }
00710          else
00711          {
00712             guessCount[i] = 0;
00713             bestGuess[i] = veclen;
00714             for ( unsigned int j = bestGuess[i] + 1 ; j < veclen ; ++j )
00715             {
00716                if ( sharings[j]->initialized() &&
00717                     sharings[j]->share(i).initialized() )
00718                {
00719                   bestGuess[i] = j;
00720                   guessCount[i] = 1;
00721                   break;
00722                }
00723             }
00724          }
00725       }
00726    }
00727 }
00728 
00729 BIGNUM*
00730 ServerState::thresholdOperation(
00731    const vector< ShareType* >& sharings,
00732    const BIGNUM * operand ) const
00733 {
00734    ShareSetType consistent;
00735    rationalizeSharings( sharings, consistent );
00736    // "consistent" is now a trustable set of shares
00737    ShareSetType temp = consistent;
00738 
00739    // do the combinatorics
00740    const unsigned int nShares = ShareType::NumShares;
00741    unsigned int veclen = sharings.size();
00742    unsigned int firstGuess[nShares];
00743    unsigned int lastGuess[nShares];
00744    for ( unsigned int i = 0 ; i < nShares ; ++i )
00745    {
00746       if ( consistent(i).initialized() ) continue;
00747       firstGuess[i] = veclen;
00748       lastGuess[i] = veclen;
00749       for ( unsigned int j = 0 ; j < veclen ; ++j )
00750       {
00751          if ( sharings[j]->initialized() &&
00752               sharings[j]->share(i).initialized() )
00753          {
00754             firstGuess[i] = j;
00755             lastGuess[i] = j;
00756             temp.setShare(i,sharings[j]->share(i));
00757             break;
00758          }
00759       }
00760    }
00761    // This loop _will_ terminate.
00762    bool changed = true;
00763    while( changed )
00764    {
00765       changed = false;
00766       BIGNUM* tres = m_thresholdRSA.threshold( temp );
00767       CODEX_Ciphers::RSACipherText* ct = 0;
00768       if ( 0 != tres )
00769       {
00770          try
00771          {
00772             // Encryption is slightly more generic than signature verification.
00773             ct = m_serviceKey.encrypt( tres );
00774             if ( 0 == BN_cmp( ct->value(), operand ) )
00775             {
00776                return tres;
00777             }
00778          }
00779          catch ( ... )
00780          {
00781          }
00782       }
00783       if ( 0 != ct ) delete ct;
00784       if ( 0 != tres ) delete tres;
00785       for ( unsigned int i = 0 ; i < nShares ; ++i )
00786       {
00787          if ( consistent(i).initialized() ) continue;
00788 
00789          unsigned int j = lastGuess[i] + 1;
00790          lastGuess[i] = veclen;
00791          for ( ; j < veclen ; ++j )
00792          {
00793             if ( sharings[j]->initialized() &&
00794                  sharings[j]->share(i).initialized() )
00795             {
00796                lastGuess[i] = j;
00797                break;
00798             }
00799          }
00800          if ( lastGuess[i] < veclen )
00801          {
00802             temp.setShare(i,sharings[lastGuess[i]]->share(i));
00803             changed = true;
00804             break;
00805          }
00806          else
00807          {
00808             // Try moving the next unconfirmed share.
00809             // If this is the last one, then changed will not be set
00810             // true, and the loop will terminate.
00811             lastGuess[i] = firstGuess[i];
00812          }
00813       }
00814    }
00815    return 0;
00816 }
00817 
00818 
00819 
00820 unsigned char*
00821 ServerState::newSequenceNumber()
00822 {
00823    for ( unsigned int i = 0 ; i < nMID ; ++i )
00824    {
00825       if ( m_seqNum[i] < 255U )
00826       {
00827          ++m_seqNum[i];
00828          break;
00829       }
00830       m_seqNum[i] = 0U;
00831    }
00832    return m_seqNum;
00833 }
00834 
00835 void
00836 ServerState::addChallenge( const unsigned char* request,
00837                            ShareLabelChallenge* challenge )
00838 {
00839    ChallengeMap::iterator itr = m_challengeMap.find( request );
00840    if ( m_challengeMap.end() == itr )
00841    {
00842       unsigned char* s = new unsigned char[ ServerState::nMID ];
00843       memcpy( s, request, CODEX_Server::ServerState::nMID );
00844       m_challengeMap.insert( ChallengeMap::value_type( s,
00845                                                        ChallengeVector() ) );
00846    }
00847    m_challengeMap[request].push_back( challenge );
00848 }
00849 
00850 void
00851 ServerState::removeChallenge( const unsigned char* request )
00852 {
00853    ChallengeMap::iterator itr = m_challengeMap.find( request );
00854    if ( itr != m_challengeMap.end() )
00855    {
00856       delete [] itr->first;
00857       ChallengeVector::iterator vItr = itr->second.begin();
00858       ChallengeVector::iterator vEnd = itr->second.end();
00859       for ( ; vItr != vEnd ; ++vItr )
00860       {
00861          delete *vItr;
00862       }
00863       m_challengeMap.erase( itr );
00864    }
00865 }
00866 
00867 
00868 //=============================================================
00869 // Quorum system management
00870 //=============================================================
00871 
00872 bool
00873 ServerState::addQuorumServer( int host,
00874                               CODEX_Quorum::AsynchronousRemoteServer* server )
00875 {
00876    if ( (host < 0) || (host >= nServers) )
00877    {
00878       return false;
00879    }
00880    if ( 0 == server )
00881    {
00882       return false;
00883    }
00884    if ( 0 == m_quorumSystem )
00885    {
00886       return false;
00887    }
00888    if ( 0 != m_quorumSystem->server(host) )
00889    {
00890       return false;
00891    }
00892    m_quorumSystem->setServer(host,server);
00893    return true;
00894 }
00895 
00896 const CODEX_Quorum::RemoteServer*
00897 ServerState::getQuorumServer( int host )
00898 {
00899    if ( 0 == m_quorumSystem )
00900    {
00901       return 0;
00902    }
00903    return m_quorumSystem->server(host);
00904 }
00905 
00906 bool
00907 ServerState::haveQuorumServer( int host ) const
00908 {
00909    if ( 0 == m_quorumSystem )
00910    {
00911       return false;
00912    }
00913    return ( 0 != m_quorumSystem->server(host) );
00914 }
00915 
00916 const string&
00917 ServerState::hostName( long i )
00918 {
00919    if ( (i < 0) || (i >= nServers) )
00920    {
00921       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00922    }
00923    return m_hostnames[i];
00924 }
00925          
00926 long
00927 ServerState::serverPort( long i )
00928 {
00929    if ( (i < 0) || (i >= nServers) )
00930    {
00931       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00932    }
00933    return m_serverPorts[i];
00934 }

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