Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

Client.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: Client.cc,v 1.5 2004/05/19 15:56:48 mmarsh Exp $
00008 //
00009 // $Log: Client.cc,v $
00010 // Revision 1.5  2004/05/19 15:56:48  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.4  2003/11/06 16:58:39  mmarsh
00014 // Most of the inputs for CODEX operations were not being tested.  Now
00015 // all of them are.
00016 //
00017 // Revision 1.3  2003/11/04 22:09:57  mmarsh
00018 // The signed ElGamal public key for the service was moved into CODEX_Server.
00019 //
00020 //
00021 
00022 #include <fstream>
00023 
00024 #include "CODEX_Quorum/Message.h"
00025 #include "CODEX_Quorum/Socket.h"
00026 #include "CODEX_Exceptions/BignumExceptions.h"
00027 #include "CODEX_Exceptions/FileExceptions.h"
00028 #include "CODEX_ASN1/Integer.h"
00029 
00030 #include "Client.h"
00031 
00032 using namespace CODEX_Client;
00033 
00034 Client::Client() :
00035    m_server( 0 ),
00036    m_certificate( 0 ),
00037    m_privateKey( 0 ),
00038    m_serviceKey( 0 ),
00039    m_serviceEGKey( 0 ),
00040    m_serviceH( 0 ),
00041    m_publicEGKey( 0 ),
00042    m_privateEGKey( 0 )
00043 {
00044 }
00045 
00046 Client::~Client()
00047 {
00048    if ( 0 != m_server       ) delete m_server;
00049    if ( 0 != m_certificate  ) delete m_certificate;
00050    if ( 0 != m_privateKey   ) delete m_privateKey;
00051    if ( 0 != m_serviceKey   ) delete m_serviceKey;
00052    if ( 0 != m_serviceEGKey ) delete m_serviceEGKey;
00053    if ( 0 != m_serviceH     ) delete m_serviceH;
00054    if ( 0 != m_publicEGKey  ) delete m_publicEGKey;
00055    if ( 0 != m_privateEGKey ) delete m_privateEGKey;
00056 }
00057 
00058 void
00059 Client::setRemoteServer( const string& name, int port )
00060 {
00061    // We'll assume that the caller knows what he's doing and delete any
00062    // existing remote server.  This does NOT affect the service information
00063    // held.
00064    if ( 0 != m_server ) delete m_server;
00065    try
00066    {
00067       m_server = new
00068          CODEX_Quorum::AsynchronousRemoteServer( name, port, m_socketBuilder );
00069    }
00070    catch ( ... )
00071    {
00072       m_server = 0;
00073    }
00074 }
00075 
00076 void
00077 Client::setServiceKey( CODEX_Ciphers::RSAPublicKey* key )
00078 {
00079    m_serviceKey = key;
00080 }
00081 
00082 void
00083 Client::setKeyPair( CODEX_ASN1::Certificate* cert,
00084                     CODEX_Ciphers::RSAPrivateKey* key )
00085 {
00086    m_certificate = cert;
00087    m_privateKey = key;
00088 }
00089 
00091 CODEX_Ciphers::Policy*
00092 Client::createPolicy( const CODEX_Ciphers::RSAPublicKey& policyPubKey,
00093                       const CODEX_Ciphers::RSAPrivateKey& ownerPrivKey )
00094 {
00095    try
00096    {
00097 //      CODEX_Ciphers::Policy* p = new CODEX_Ciphers::Policy( policyPubKey,
00098 //                                                            ownerPrivKey,
00099 //                                                            m_hashFunc );
00100       CODEX_Ciphers::Policy* p = new CODEX_Ciphers::Policy;
00101       p->unmarshal(0,0,0); // trick the object into thinking it's initialized
00102       return p;
00103    }
00104    catch ( ... )
00105    {
00106       return 0;
00107    }
00108 }
00109 
00110 CODEX_Ciphers::Credentials*
00111 Client::issueCredentials( const CODEX_Ciphers::RSAPublicKey& clientPubKey,
00112                           const CODEX_Ciphers::RSAPrivateKey& policyPrivKey )
00113 {
00114    try
00115    {
00116       CODEX_Ciphers::Credentials* c =
00117          new CODEX_Ciphers::Credentials( clientPubKey );
00118       return c;
00119    }
00120    catch ( ... )
00121    {
00122       return 0;
00123    }
00124 }
00125 
00126 bool
00127 Client::createKey( const CODEX_ASN1::ustring& name,
00128                    const CODEX_ASN1::Certificate& owner_cert,
00129                    const CODEX_Ciphers::Policy& readPolicy,
00130                    const CODEX_Ciphers::Policy& writePolicy,
00131                    SignedBoundNameMsg& binding )
00132 {
00133    if ( 0 == m_server )
00134    {
00135       return false;
00136    }
00137    if ( 0 == m_privateKey )
00138    {
00139       return false;
00140    }
00141    if ( ! owner_cert.initialized() )
00142    {
00143       return false;
00144    }
00145    if ( ! readPolicy.initialized() )
00146    {
00147       return false;
00148    }
00149    if ( ! writePolicy.initialized() )
00150    {
00151       return false;
00152    }
00153    try
00154    {
00155       CreateKeyMsg ckMsg( name,
00156                           owner_cert,
00157                           readPolicy,
00158                           writePolicy );
00159       BIGNUM * digest = ckMsg.digest( m_hashFunc );
00160       CODEX_Ciphers::RSASignature* signature = m_privateKey->sign( digest );
00161       BN_free( digest );
00162       SignedCreateKeyMsg signedCKMsg( ckMsg, *signature );
00163 
00164       CODEX_Quorum::Message response;
00165       if ( ! contactServer( signedCKMsg,
00166                             kCreateKeyMsg | SignatureMask,
00167                             response ) )
00168       {
00169          throw 0;
00170       }
00171 
00172       // Check the response's message type.
00173       const unsigned char* data = response.buffer();
00174       int length = response.length();
00175       if ( (kBoundNameMsg|SignatureMask) != data[0] )
00176       {
00177          throw 1;
00178       }
00179 
00180       // Unmarshal the data.
00181       unsigned char* pBuff = (unsigned char*) data + 1;
00182       if ( 0 == binding.unmarshal( 0, &pBuff, length-1 ) )
00183       {
00184          throw 2;
00185       }
00186 
00187       // Check the key name of the response.
00188       if ( ckMsg.name().value() != binding.message().name().value() )
00189       {
00190          throw 3;
00191       }
00192 
00193       // Check the client signature in the response.
00194       if ( 0 != BN_cmp( binding.message().request().signature().value(),
00195                         signedCKMsg.signature().value() ) )
00196       {
00197          throw 4;
00198       }
00199 
00200       // Check the service's signature on the response.
00201       digest = binding.message().digest( m_hashFunc );
00202       if ( ! m_serviceKey->verifySignature( binding.signature(), digest ) )
00203       {
00204          throw 5;
00205       }
00206       BN_free(digest);
00207       digest = 0;
00208 
00209       return true;
00210    }
00211    catch ( ... )
00212    {
00213       return false;
00214    }
00215 }
00216 
00217 bool
00218 Client::writeKey( const CODEX_ASN1::ustring& name,
00219                   const BIGNUM* keyValue,
00220                   const CODEX_Ciphers::Credentials& credentials,
00221                   const CODEX_Ciphers::RSAPrivateKey& privKey,
00222                   const SignedBoundNameMsg& binding )
00223 {
00224    if ( 0 == m_server )
00225    {
00226       return false;
00227    }
00228    if ( 0 == keyValue )
00229    {
00230       return false;
00231    }
00232    if ( ! credentials.initialized() )
00233    {
00234       return false;
00235    }
00236    if ( ! privKey.initialized() )
00237    {
00238       return false;
00239    }
00240    if ( ! binding.initialized() )
00241    {
00242       return false;
00243    }
00244 
00245 #ifdef ELGAMAL
00246    if ( 0 == m_serviceEGKey )
00247    {
00248       if ( ! getServiceKey() )
00249       {
00250          return false;
00251       }
00252    }
00253 #endif
00254 
00255    if ( (0 == m_serviceKey ) )
00256    {
00257       return false;
00258    }
00259 
00260    // Now we're ready to actually compose the message.
00261    //CODEX_Ciphers::ElGamalCipherText* clientEnc = 0;
00262    //CODEX_Ciphers::ElGamalCipherText* serviceEnc = 0;
00263    //BIGNUM * k = 0;
00264    RequestCipherTextType* encryption = 0;
00265    BIGNUM * digest = 0;
00266    BIGNUM * r = 0;
00267    try
00268    {
00269 #ifndef ELGAMAL
00270       CODEX_Ciphers::VarRSAPublicKey encKey( *m_serviceKey );
00271       r = BN_new();
00272       if ( 0 == r )
00273       {
00274          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00275       }
00276       encryption = encKey.encrypt( keyValue, m_hashFunc, r );
00277 
00278       CODEX_Ciphers::RSAPlaintextPK proof( r,
00279                                            *m_serviceKey,
00280                                            credentials,
00281                                            m_hashFunc );
00282       r = 0;
00283 #else
00284       encryption =
00285          m_serviceEGKey->encryptS( keyValue, credentials, m_hashFunc );
00286 #endif
00287 
00288       WriteKeyMsg wkMsg( name,
00289                          *encryption,
00290 #ifndef ELGAMAL
00291                          proof,
00292 #endif
00293                          credentials,
00294                          binding );
00295 
00296       digest = wkMsg.digest( m_hashFunc );
00297       CODEX_Ciphers::RSASignature* signature = privKey.sign( digest );
00298       BN_free( digest );
00299       digest = 0;
00300       SignedWriteKeyMsg signedWKMsg( wkMsg, *signature );
00301       delete signature;
00302 
00303       CODEX_Quorum::Message response;
00304       if ( ! contactServer( signedWKMsg,
00305                             kWriteKeyMsg | SignatureMask,
00306                             response ) )
00307       {
00308          throw 0;
00309       }
00310 
00311       // Check the response's message type.
00312       const unsigned char* data = response.buffer();
00313       int length = response.length();
00314       if ( (kKeyStoredMsg|SignatureMask) != data[0] )
00315       {
00316          throw 1;
00317       }
00318 
00319       // Unmarshal the data.
00320       SignedKeyStoredMsg sksMsg;
00321       unsigned char* pBuff = (unsigned char*) data + 1;
00322       if ( 0 == sksMsg.unmarshal( 0, &pBuff, length-1 ) )
00323       {
00324          throw 2;
00325       }
00326 
00327       // Check the key name of the response.
00328       if ( wkMsg.name().value() != sksMsg.message().name().value() )
00329       {
00330          throw 3;
00331       }
00332 
00333       // Check the client signature in the response.
00334       if ( 0 != BN_cmp( sksMsg.message().requestSignature().value(),
00335                         signedWKMsg.signature().value() ) )
00336       {
00337          throw 4;
00338       }
00339 
00340       // Check the service's signature on the response.
00341       digest = sksMsg.message().digest( m_hashFunc );
00342       if ( ! m_serviceKey->verifySignature( sksMsg.signature(), digest ) )
00343       {
00344          throw 5;
00345       }
00346       BN_free(digest);
00347       digest = 0;
00348 
00349       //if ( 0 != clientEnc ) delete clientEnc;
00350       //if ( 0 != serviceEnc ) delete serviceEnc;
00351       //if ( 0 != k ) BN_clear_free(k);
00352       if ( 0 != encryption ) delete encryption;
00353       if ( 0 != digest ) BN_free(digest);
00354       return true;
00355    }
00356    catch ( ... )
00357    {
00358       //if ( 0 != clientEnc ) delete clientEnc;
00359       //if ( 0 != serviceEnc ) delete serviceEnc;
00360       //if ( 0 != k ) BN_clear_free(k);
00361       if ( 0 != encryption ) delete encryption;
00362       if ( 0 != digest ) BN_free(digest);
00363       if ( 0 != r ) BN_clear_free( r );
00364       return false;
00365    }
00366 }
00367 
00369 bool
00370 Client::readKey( const CODEX_ASN1::ustring& name,
00371                  const CODEX_Ciphers::Credentials& credentials,
00372                  const CODEX_Ciphers::RSAPrivateKey& privKey,
00373                  BIGNUM ** returnedKeyValue )
00374 {
00375    if ( ! credentials.initialized() )
00376    {
00377       return false;
00378    }
00379    if ( ! privKey.initialized() )
00380    {
00381       return false;
00382    }
00383    if ( 0 == returnedKeyValue )
00384    {
00385       return false;
00386    }
00387    *returnedKeyValue = 0;
00388 
00389    if ( 0 == m_server )
00390    {
00391       return false;
00392    }
00393 
00394 #ifdef ELGAMAL
00395    if ( 0 == m_serviceEGKey )
00396    {
00397       if ( ! getServiceKey() )
00398       {
00399          return false;
00400       }
00401    }
00402 #endif
00403 
00404    BIGNUM * digest = 0;
00405    BIGNUM * b = 0;
00406    BlindingCipherTextType* blindingFactor = 0;
00407    BN_CTX * ctx = 0;
00408    try
00409    {
00410       b = BN_new();
00411       if ( 0 == b )
00412       {
00413          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00414       }
00415 #ifndef ELGAMAL
00416       const CODEX_ASN1::BigNumber& nbn = m_serviceKey->n();
00417       const BIGNUM * n = m_serviceKey->n().value();
00418       BIGNUM * bMax = (BIGNUM*) n;
00419 #else
00420       const BIGNUM * n = m_serviceEGKey->p().value();
00421       BIGNUM * bMax = (BIGNUM*) m_serviceEGKey->q();
00422 #endif
00423       do
00424       {
00425          if ( ! BN_rand_range( b, bMax ) )
00426          {
00427             throw CODEX_Exceptions::BignumRandRangeException( __FILE__ ,
00428                                                               __LINE__ );
00429          }
00430       } while ( 0 >= BN_cmp( b, BN_value_one() ) );
00431 
00432 #ifndef ELGAMAL
00433       blindingFactor = m_serviceKey->encrypt( b );
00434 
00435       CODEX_Ciphers::RSAPlaintextPK proof( BN_dup(b),
00436                                            *m_serviceKey,
00437                                            credentials,
00438                                            m_hashFunc );
00439 #else
00440       blindingFactor =
00441          m_serviceEGKey->encryptS( b, credentials, m_hashFunc );
00442 #endif
00443 
00444       ReadKeyMsg rkMsg( name,
00445                         *blindingFactor,
00446 #ifndef ELGAMAL
00447                         proof,
00448 #endif
00449                         credentials );
00450 
00451       digest = rkMsg.digest( m_hashFunc );
00452       CODEX_Ciphers::RSASignature* signature = privKey.sign( digest );
00453       BN_free( digest );
00454       digest = 0;
00455       SignedReadKeyMsg signedRKMsg( rkMsg, *signature );
00456       delete signature;
00457 
00458       CODEX_Quorum::Message response;
00459       if ( ! contactServer( signedRKMsg,
00460                             kReadKeyMsg | SignatureMask,
00461                             response ) )
00462       {
00463          throw 0;
00464       }
00465 
00466       // Check the response's message type.
00467       const unsigned char* data = response.buffer();
00468       int length = response.length();
00469       if ( (kBlindKeyMsg|SignatureMask) != data[0] )
00470       {
00471          throw 1;
00472       }
00473 
00474       // Unmarshal the data.
00475       SignedBlindKeyMsg sbkMsg;
00476       unsigned char* pBuff = (unsigned char*) data + 1;
00477       if ( 0 == sbkMsg.unmarshal( 0, &pBuff, length-1 ) )
00478       {
00479          throw 2;
00480       }
00481 
00482       // Check the key name of the response.
00483       if ( rkMsg.name().value() != sbkMsg.message().name().value() )
00484       {
00485          throw 3;
00486       }
00487 
00488       // Check the client signature in the response.
00489       if ( 0 != BN_cmp( sbkMsg.message().requestSignature().value(),
00490                         signedRKMsg.signature().value() ) )
00491       {
00492          throw 4;
00493       }
00494 
00495       // Check the service's signature on the response.
00496       digest = sbkMsg.message().digest( m_hashFunc );
00497       if ( ! m_serviceKey->verifySignature( sbkMsg.signature(), digest ) )
00498       {
00499          throw 5;
00500       }
00501       BN_free(digest);
00502       digest = 0;
00503 
00504 #ifdef ELGAMAL
00505       *returnedKeyValue = BN_dup( sbkMsg.message().blindedKey().value() );
00506       if ( 0 == *returnedKeyValue )
00507       {
00508          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00509       }
00510       ctx = BN_CTX_new();
00511       if ( 0 == ctx )
00512       {
00513          throw CODEX_Exceptions::BignumContextException( __FILE__ , __LINE__ );
00514       }
00515       if ( ! BN_mod_inverse( b, b, n, ctx ) )
00516       {
00517          throw CODEX_Exceptions::BignumModInverseException( __FILE__ ,
00518                                                             __LINE__ );
00519       }
00520       if ( ! BN_mod_mul( *returnedKeyValue, *returnedKeyValue, b, n, ctx ) )
00521       {
00522          throw CODEX_Exceptions::BignumModMulException( __FILE__ , __LINE__ );
00523       }
00524       if ( BN_cmp( *returnedKeyValue, bMax ) >= 0 )
00525       {
00526          if ( ! BN_sub( *returnedKeyValue, n, *returnedKeyValue ) )
00527          {
00528             throw CODEX_Exceptions::BignumSubException( __FILE__ , __LINE__ );
00529          }
00530       }
00531 #else
00532       *returnedKeyValue =
00533          sbkMsg.message().blindedKey().unblind( b, nbn, m_hashFunc );
00534 #endif      
00535       BN_CTX_free(ctx);
00536       ctx = 0;
00537 
00538       BN_clear_free(b);
00539       delete blindingFactor;
00540       return true;
00541    }
00542    catch ( ... )
00543    {
00544       if ( 0 != digest ) BN_free(digest);
00545       if ( 0 != b ) BN_clear_free(b);
00546       if ( 0 != blindingFactor ) delete blindingFactor;
00547       if ( 0 != *returnedKeyValue ) BN_clear_free( *returnedKeyValue );
00548       *returnedKeyValue = 0;
00549       if ( 0 != ctx ) BN_CTX_free(ctx);
00550       return false;
00551    }
00552 }
00553 
00554 bool
00555 Client::getServiceKey()
00556 {
00557    if ( 0 == m_server )
00558    {
00559       return false;
00560    }
00561    if ( 0 == m_serviceKey )
00562    {
00563       return false;
00564    }
00565 
00566    BIGNUM * digest = 0;
00567    try
00568    {
00569       RequestKeyMsg rkMsg;
00570 
00571       CODEX_Quorum::Message response;
00572       if ( ! contactServer( rkMsg,
00573                             kRequestKeyMsg,
00574                             response ) )
00575       {
00576          return false;
00577       }
00578 
00579       int length = response.length();
00580       const unsigned char* data = response.buffer();
00581 
00582       // Does the response match the request?
00583       if ( (kPublicKeyMsg|SignatureMask) != data[0] )
00584       {
00585          return false;
00586       }
00587 
00588       SignedPublicKeyMsg spkMsg;
00589       unsigned char* p = (unsigned char*) data + 1;
00590       if ( 0 == spkMsg.unmarshal( 0, &p, length-1 ) )
00591       {
00592          return false;
00593       }
00594       digest = spkMsg.key().digest( m_hashFunc );
00595       // Is the service's signature valid?
00596       if ( ! m_serviceKey->verifySignature( spkMsg.signature(), digest ) )
00597       {
00598          BN_free(digest);
00599          return false;
00600       }
00601       BN_free(digest);
00602       digest = 0;
00603 
00604       m_serviceEGKey =
00605          new CODEX_Ciphers::ElGamalPublicKey( spkMsg.key().key() );
00606       m_serviceH = new CODEX_ASN1::BigNumber( spkMsg.key().h() );
00607 
00608       return true;
00609    }
00610    catch ( ... )
00611    {
00612       if ( 0 != digest ) BN_free(digest);
00613       return false;
00614    }
00615 }
00616 
00617 bool
00618 Client::contactServer( const Message& message,
00619                        unsigned char mtype,
00620                        CODEX_Quorum::Message& response )
00621 {
00622    int length = message.marshal(0) + 1;
00623    unsigned char* buff = new unsigned char[length];
00624    cout << "length of message: " << length << endl;
00625    buff[0] = mtype;
00626    unsigned char* pBuff = buff+1;
00627    message.marshal(&pBuff);
00628    CODEX_Quorum::Message msg( buff, length );
00629    delete [] buff;
00630 
00631    // Block waiting for the response.
00632    CODEX_Quorum::RemoteServerReturn sRet;
00633    try
00634    {
00635       m_server->sendTo( msg, sRet );
00636       m_server->flushSocket(); // blocking write
00637    }
00638    catch ( CODEX_Quorum::QSExceptionBase& e )
00639    {
00640       e.report();
00641       return false;
00642    }
00643    catch ( ... )
00644    {
00645       return false;
00646    }
00647    if ( CODEX_Quorum::RemoteServerReturn::kSuccess != sRet.returnCode() )
00648    {
00649       return false;
00650    }
00651    sRet.reset();
00652    try
00653    {
00654       length = 0;
00655       do
00656       {
00657          length = m_server->receiveFrom( response, sRet, length );
00658       } while ( length > 0 );
00659    }
00660    catch ( CODEX_Quorum::QSExceptionBase& e )
00661    {
00662       e.report();
00663       return false;
00664    }
00665    catch ( ... )
00666    {
00667       return false;
00668    }
00669 
00670    return true;
00671 }
00672 
00673 void
00674 Client::toFile( const char* fname ) const
00675 {
00676    CODEX_ASN1::Integer haveCert( ( 0 != m_certificate ) ? 1 : 0 );
00677    CODEX_ASN1::Integer havePrivKey( ( 0 != m_privateKey ) ? 1 : 0 );
00678    CODEX_ASN1::Integer haveServKey( ( 0 != m_serviceKey ) ? 1 : 0 );
00679    CODEX_ASN1::Integer haveServEGKey( ( 0 != m_serviceEGKey ) ? 1 : 0 );
00680    CODEX_ASN1::Integer haveServH( ( 0 != m_serviceH ) ? 1 : 0 );
00681    CODEX_ASN1::Integer havePubEGKey( ( 0 != m_publicEGKey ) ? 1 : 0 );
00682    CODEX_ASN1::Integer havePrivEGKey( ( 0 != m_privateEGKey ) ? 1 : 0 );
00683    int length = 0;
00684    length += haveCert.marshal(0);
00685    length += havePrivKey.marshal(0);
00686    length += haveServKey.marshal(0);
00687    length += haveServEGKey.marshal(0);
00688    length += haveServH.marshal(0);
00689    length += havePubEGKey.marshal(0);
00690    length += havePrivEGKey.marshal(0);
00691    if ( haveCert.value() )
00692    {
00693       length += m_certificate->marshal(0);
00694    }
00695    if ( havePrivKey.value() )
00696    {
00697       length += m_privateKey->marshal(0);
00698    }
00699    if ( haveServKey.value() )
00700    {
00701       length += m_serviceKey->marshal(0);
00702    }
00703    if ( haveServEGKey.value() )
00704    {
00705       length += m_serviceEGKey->marshal(0);
00706    }
00707    if ( haveServH.value() )
00708    {
00709       length += m_serviceH->marshal(0);
00710    }
00711    if ( havePubEGKey.value() )
00712    {
00713       length += m_publicEGKey->marshal(0);
00714    }
00715    if ( havePrivEGKey.value() )
00716    {
00717       length += m_privateEGKey->marshal(0);
00718    }
00719    unsigned char* buff = new unsigned char[length];
00720    unsigned char* p = buff;
00721    haveCert.marshal(&p);
00722    havePrivKey.marshal(&p);
00723    haveServKey.marshal(&p);
00724    haveServEGKey.marshal(&p);
00725    haveServH.marshal(&p);
00726    havePubEGKey.marshal(&p);
00727    havePrivEGKey.marshal(&p);
00728    if ( haveCert.value() )
00729    {
00730       m_certificate->marshal(&p);
00731    }
00732    if ( havePrivKey.value() )
00733    {
00734       m_privateKey->marshal(&p);
00735    }
00736    if ( haveServKey.value() )
00737    {
00738       m_serviceKey->marshal(&p);
00739    }
00740    if ( haveServEGKey.value() )
00741    {
00742       m_serviceEGKey->marshal(&p);
00743    }
00744    if ( haveServH.value() )
00745    {
00746       m_serviceH->marshal(&p);
00747    }
00748    if ( havePubEGKey.value() )
00749    {
00750       m_publicEGKey->marshal(&p);
00751    }
00752    if ( havePrivEGKey.value() )
00753    {
00754       m_privateEGKey->marshal(&p);
00755    }
00756 
00757    ofstream os(fname);
00758    if ( ! os.is_open() )
00759    {
00760       delete [] buff;
00761       throw CODEX_Exceptions::FileCannotCreateException( __FILE__ ,
00762                                                          __LINE__ ,
00763                                                          fname );
00764    }
00765    for ( int i = 0 ; i < length ; ++i )
00766    {
00767       os << buff[i];
00768    }
00769    os.close();
00770    delete [] buff;
00771 }
00772 
00773 void*
00774 Client::fromFile( const char* fname )
00775 {
00776    ifstream is(fname);
00777    if ( ! is.is_open() )
00778    {
00779       throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00780                                                        __LINE__ ,
00781                                                        fname );
00782    }
00783    string s;
00784    char ch;
00785    while ( is.get(ch) )
00786    {
00787       s.push_back(ch);
00788    }
00789    //basic_string<unsigned char> s;
00790    //is >> s;
00791    is.close();
00792    unsigned int length = s.length();
00793    unsigned char* p = new unsigned char[ length ];
00794    unsigned char* pOrig = p;
00795    //unsigned char* p = (unsigned char*)s.data();
00796    for ( unsigned int i = 0 ; i < length ; ++i )
00797    {
00798       p[i] = s.data()[i];
00799    }
00800    CODEX_ASN1::Integer haveCert;
00801    CODEX_ASN1::Integer havePrivKey;
00802    CODEX_ASN1::Integer haveServKey;
00803    CODEX_ASN1::Integer haveServEGKey;
00804    CODEX_ASN1::Integer haveServH;
00805    CODEX_ASN1::Integer havePubEGKey;
00806    CODEX_ASN1::Integer havePrivEGKey;
00807    haveCert.unmarshal(0,&p,length);
00808    havePrivKey.unmarshal(0,&p,length);
00809    haveServKey.unmarshal(0,&p,length);
00810    haveServEGKey.unmarshal(0,&p,length);
00811    haveServH.unmarshal(0,&p,length);
00812    havePubEGKey.unmarshal(0,&p,length);
00813    havePrivEGKey.unmarshal(0,&p,length);
00814    if ( haveCert.value() )
00815    {
00816       if ( 0 != m_certificate ) delete m_certificate;
00817       m_certificate = new CODEX_ASN1::Certificate;
00818       m_certificate->unmarshal(0,&p,length);
00819    }
00820    if ( havePrivKey.value() )
00821    {
00822       if ( 0 != m_privateKey ) delete m_privateKey;
00823       m_privateKey = new CODEX_Ciphers::RSAPrivateKey;
00824       m_privateKey->unmarshal(0,&p,length);
00825    }
00826    if ( haveServKey.value() )
00827    {
00828       if ( 0 != m_serviceKey ) delete m_serviceKey;
00829       m_serviceKey = new CODEX_Ciphers::RSAPublicKey;
00830       m_serviceKey->unmarshal(0,&p,length);
00831    }
00832    if ( haveServEGKey.value() )
00833    {
00834       if ( 0 != m_serviceEGKey ) delete m_serviceEGKey;
00835       m_serviceEGKey = new CODEX_Ciphers::ElGamalPublicKey;
00836       m_serviceEGKey->unmarshal(0,&p,length);
00837    }
00838    if ( haveServH.value() )
00839    {
00840       if ( 0 != m_serviceH ) delete m_serviceH;
00841       m_serviceH = new CODEX_ASN1::BigNumber;
00842       m_serviceH->unmarshal(0,&p,length);
00843    }
00844    if ( havePubEGKey.value() )
00845    {
00846       if ( 0 != m_publicEGKey ) delete m_publicEGKey;
00847       m_publicEGKey = new CODEX_Ciphers::ElGamalPublicKey;
00848       m_publicEGKey->unmarshal(0,&p,length);
00849    }
00850    if ( havePrivEGKey.value() )
00851    {
00852       if ( 0 != m_privateEGKey ) delete m_privateEGKey;
00853       m_privateEGKey = new CODEX_Ciphers::ElGamalPrivateKey;
00854       m_privateEGKey->unmarshal(0,&p,length);
00855    }
00856    delete [] pOrig;
00857    return this;
00858 }

Generated on Wed Jun 2 16:32:54 2004 for COrnell Data EXchange (CODEX) by doxygen1.2.18