reSIProcate/stack  9694
TlsConnection.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #if defined(USE_SSL)
00006 
00007 #include "resip/stack/ssl/TlsConnection.hxx"
00008 #include "resip/stack/ssl/TlsTransport.hxx"
00009 #include "resip/stack/ssl/Security.hxx"
00010 #include "rutil/Logger.hxx"
00011 #include "resip/stack/Uri.hxx"
00012 #include "rutil/Socket.hxx"
00013 
00014 #include <openssl/e_os2.h>
00015 #include <openssl/evp.h>
00016 #include <openssl/crypto.h>
00017 #include <openssl/err.h>
00018 #include <openssl/pem.h>
00019 #include <openssl/pkcs7.h>
00020 #include <openssl/x509v3.h>
00021 #include <openssl/ssl.h>
00022 #endif
00023 
00024 using namespace resip;
00025 
00026 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
00027 
00028 TlsConnection::TlsConnection( Transport* transport, const Tuple& tuple, 
00029                               Socket fd, Security* security, 
00030                               bool server, Data domain,  SecurityTypes::SSLType sslType ,
00031                               Compression &compression) :
00032    Connection(transport,tuple, fd, compression),
00033    mServer(server),
00034    mSecurity(security),
00035    mSslType( sslType ),
00036    mDomain(domain)
00037 {
00038 #if defined(USE_SSL)
00039    InfoLog (<< "Creating TLS connection for domain " 
00040             << mDomain 
00041             << " " << tuple 
00042             << " on " << fd);
00043 
00044    mSsl = NULL;
00045    mBio= NULL;
00046   
00047    if (mServer)
00048    {
00049       DebugLog( << "Trying to form TLS connection - acting as server" );
00050       if ( mDomain.empty() )
00051       {
00052          ErrLog(<< "Tranport was not created with a server domain so can not act as server" ); 
00053          throw Security::Exception("Trying to act as server but no domain specified",
00054                                    __FILE__,__LINE__);
00055       }
00056    }
00057    else
00058    {
00059       DebugLog( << "Trying to form TLS connection - acting as client" );
00060    }
00061    assert( mSecurity );
00062 
00063    TlsTransport *t = dynamic_cast<TlsTransport*>(transport);
00064    assert(t);
00065 
00066    SSL_CTX* ctx=t->getCtx();
00067    assert(ctx);
00068    
00069    mSsl = SSL_new(ctx);
00070    assert(mSsl);
00071 
00072    assert( mSecurity );
00073 
00074    if(mServer)
00075    {
00076       // clear SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE set in SSL_CTX if we are a server
00077       int verify_mode;
00078       switch(t->getClientVerificationMode())
00079       {
00080       case SecurityTypes::None:
00081          verify_mode = SSL_VERIFY_NONE;
00082          DebugLog(<< "Not expecting client certificate" );
00083          break;
00084       case SecurityTypes::Optional:
00085          verify_mode = SSL_VERIFY_PEER;
00086          DebugLog(<< "Optional client certificate mode" );
00087          break;
00088       case SecurityTypes::Mandatory:
00089          verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00090          DebugLog(<< "Mandatory client certificate mode" );
00091          break;
00092       default:
00093          assert( 0 );
00094       }
00095       SSL_set_verify(mSsl, verify_mode, 0);
00096    }
00097 
00098    mBio = BIO_new_socket((int)fd,0/*close flag*/);
00099    assert( mBio );
00100    
00101    SSL_set_bio( mSsl, mBio, mBio );
00102 
00103    mTlsState = Initial;
00104    mHandShakeWantsRead = false;
00105 
00106 #endif // USE_SSL   
00107 }
00108 
00109 TlsConnection::~TlsConnection()
00110 {
00111 #if defined(USE_SSL)
00112    SSL_shutdown(mSsl);
00113    SSL_free(mSsl);
00114 #endif // USE_SSL   
00115 }
00116 
00117 
00118 const char*
00119 TlsConnection::fromState(TlsConnection::TlsState s)
00120 {
00121    switch(s)
00122    {
00123       case Initial: return "Initial"; break;
00124       case Handshaking: return "Handshaking"; break;
00125       case Broken: return "Broken"; break;
00126       case Up: return "Up"; break;
00127    }
00128    return "????";
00129 }
00130 
00131 TlsConnection::TlsState
00132 TlsConnection::checkState()
00133 {
00134 #if defined(USE_SSL)
00135    //DebugLog(<<"state is " << fromTlsState(mTlsState));
00136 
00137    if (mTlsState == Up || mTlsState == Broken)
00138    {
00139       return mTlsState;
00140    }
00141    
00142    int ok=0;
00143    
00144    ERR_clear_error();
00145    
00146    if (mTlsState != Handshaking)
00147    {
00148       if (mServer)
00149       {
00150          InfoLog( << "TLS handshake starting (Server mode)" );
00151          SSL_set_accept_state(mSsl);
00152          mTlsState = Handshaking;
00153       }
00154       else
00155       {
00156          InfoLog( << "TLS handshake starting (client mode)" );
00157          SSL_set_connect_state(mSsl);
00158          mTlsState = Handshaking;
00159       }
00160 
00161       InfoLog( << "TLS connected" ); 
00162       mTlsState = Handshaking;
00163    }
00164 
00165    mHandShakeWantsRead = false;
00166    ok = SSL_do_handshake(mSsl);
00167       
00168    if ( ok <= 0 )
00169    {
00170       int err = SSL_get_error(mSsl,ok);
00171          
00172       switch (err)
00173       {
00174          case SSL_ERROR_WANT_READ:
00175             StackLog( << "TLS handshake want read" );
00176             mHandShakeWantsRead = true;
00177 
00178             return mTlsState;
00179          case SSL_ERROR_WANT_WRITE:
00180             StackLog( << "TLS handshake want write" );
00181             ensureWritable();
00182             return mTlsState;
00183 
00184          case SSL_ERROR_ZERO_RETURN:
00185             StackLog( << "TLS connection closed cleanly");
00186             return mTlsState;
00187 
00188          case SSL_ERROR_WANT_CONNECT:
00189             StackLog( << "BIO not connected, try later");
00190             return mTlsState;
00191 
00192 #if  ( OPENSSL_VERSION_NUMBER >= 0x0090702fL )
00193          case SSL_ERROR_WANT_ACCEPT:
00194             StackLog( << "TLS connection want accept" );
00195             return mTlsState;
00196 #endif
00197 
00198          case SSL_ERROR_WANT_X509_LOOKUP:
00199             StackLog( << "Try later");
00200             return mTlsState;
00201          default:
00202             if(err == SSL_ERROR_SYSCALL)
00203             {
00204                int e = getErrno();
00205                switch(e)
00206                {
00207                   case EINTR:
00208                   case EAGAIN:
00209                      StackLog( << "try later");
00210                      return mTlsState;
00211                }
00212                ErrLog( << "socket error " << e);
00213                Transport::error(e);
00214             }
00215             else if (err == SSL_ERROR_SSL)
00216             {
00217                mFailureReason = TransportFailure::CertValidationFailure;
00218             }
00219             ErrLog( << "TLS handshake failed ");
00220             while (true)
00221             {
00222                const char* file;
00223                int line;
00224 
00225                unsigned long code = ERR_get_error_line(&file,&line);
00226                if ( code == 0 )
00227                {
00228                   break;
00229                }
00230 
00231                char buf[256];
00232                ERR_error_string_n(code,buf,sizeof(buf));
00233                ErrLog( << buf  );
00234                ErrLog( << "Error code = "
00235                         << code << " file=" << file << " line=" << line );
00236             }
00237             mBio = NULL;
00238             mTlsState = Broken;
00239             return mTlsState;
00240       }
00241    }
00242    else // ok > 1
00243    {
00244       InfoLog( << "TLS connected" );
00245    }
00246 
00247    // force peer name to get checked and perhaps cert loaded
00248    computePeerName();
00249 
00250    //post-connection verification: check that certificate name matches domain name
00251    if (!mServer)
00252    {
00253       bool matches = false;
00254       for(std::list<BaseSecurity::PeerName>::iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)
00255       {
00256          if(BaseSecurity::matchHostName(it->mName, who().getTargetDomain()))
00257          {
00258              matches=true;
00259              break;
00260          }
00261       }
00262       if(!matches)
00263       {
00264          mTlsState = Broken;
00265          mBio = NULL;
00266          ErrLog (<< "Certificate name mismatch: trying to connect to <" 
00267                  << who().getTargetDomain()
00268                  << "> remote cert domain(s) are <" 
00269                  << getPeerNamesData() << ">" );
00270          mFailureReason = TransportFailure::CertNameMismatch;         
00271          return mTlsState;
00272       }
00273    }
00274 
00275    InfoLog( << "TLS handshake done for peer " << getPeerNamesData()); 
00276    mTlsState = Up;
00277    if (!mOutstandingSends.empty())
00278    {
00279       ensureWritable();
00280    }
00281 #endif // USE_SSL   
00282    return mTlsState;
00283 }
00284 
00285       
00286 int 
00287 TlsConnection::read(char* buf, int count )
00288 {
00289 #if defined(USE_SSL)
00290    assert( mSsl ); 
00291    assert( buf );
00292 
00293    switch(checkState())
00294    {
00295       case Broken:
00296          return -1;
00297          break;
00298       case Up:
00299          break;
00300       default:
00301          return 0;
00302          break;
00303    }
00304 
00305    if (!mBio)
00306    {
00307       DebugLog( << "Got TLS read bad bio  " );
00308       return 0;
00309    }
00310       
00311    if ( !isGood() )
00312    {
00313       return -1;
00314    }
00315 
00316    int bytesRead = SSL_read(mSsl,buf,count);
00317    StackLog(<< "SSL_read returned " << bytesRead << " bytes [" << Data(Data::Borrow, buf, (bytesRead > 0)?(bytesRead):(0)) << "]");
00318 
00319    int bytesPending = SSL_pending(mSsl);
00320 
00321    if ((bytesRead > 0) && (bytesPending > 0))
00322    {
00323       char* buffer = getWriteBufferForExtraBytes(bytesPending);
00324       if (buffer)
00325       {
00326          StackLog(<< "reading remaining buffered bytes");
00327          bytesPending = SSL_read(mSsl, buffer, bytesPending);
00328          StackLog(<< "SSL_read returned  " << bytesPending << " bytes [" << Data(Data::Borrow, buffer, (bytesPending > 0)?(bytesPending):(0)) << "]");
00329          
00330          if (bytesPending > 0)
00331          {
00332             bytesRead += bytesPending;
00333          }
00334          else
00335          {
00336             bytesRead = bytesPending;
00337          }
00338       }
00339       else
00340       {
00341          assert(0);
00342       }
00343    }
00344 
00345    if (bytesRead <= 0)
00346    {
00347       int err = SSL_get_error(mSsl,bytesRead);
00348       switch (err)
00349       {
00350          case SSL_ERROR_WANT_READ:
00351          case SSL_ERROR_WANT_WRITE:
00352          case SSL_ERROR_NONE:
00353          {
00354             StackLog( << "Got TLS read got condition of " << err  );
00355             return 0;
00356          }
00357          break;
00358          default:
00359          {
00360             char buf[256];
00361             ERR_error_string_n(err,buf,sizeof(buf));
00362             ErrLog( << "Got TLS read ret=" << bytesRead << " error=" << err  << " " << buf  );
00363             return -1;
00364          }
00365          break;
00366       }
00367       assert(0);
00368    }
00369    StackLog(<<"SSL bytesRead="<<bytesRead);
00370    return bytesRead;
00371 #endif // USE_SSL
00372    return -1;
00373 }
00374 
00375 bool
00376 TlsConnection::transportWrite()
00377 {
00378    switch(mTlsState)
00379    {
00380       case Handshaking:
00381       case Initial:
00382          checkState();
00383          if (mTlsState == Handshaking)
00384          {
00385             DebugLog(<< "Transportwrite--Handshaking--remove from write: " << mHandShakeWantsRead);
00386             return mHandShakeWantsRead;
00387          }
00388          else
00389          {
00390             DebugLog(<< "Transportwrite--Handshake complete, in " << fromState(mTlsState) << " calling write");
00391             return false;
00392          }
00393       case Up:
00394       case Broken:
00395          DebugLog(<< "Transportwrite--" << fromState(mTlsState) << " fall through to write");
00396          return false;
00397    }
00398    assert(0);
00399    return false;
00400 }
00401 
00402 int 
00403 TlsConnection::write( const char* buf, int count )
00404 {
00405 #if defined(USE_SSL)
00406    assert( mSsl );
00407    assert( buf );
00408    int ret;
00409  
00410    switch(checkState())
00411    {
00412       case Broken:
00413          return -1;
00414          break;
00415       case Up:
00416          break;
00417       default:
00418          DebugLog( << "Tried to Tls write - but connection is not Up"  );
00419          return 0;
00420          break;
00421    }
00422 
00423    if (!mBio)
00424    {
00425       DebugLog( << "Got TLS write bad bio "  );
00426       return 0;
00427    }
00428         
00429    ret = SSL_write(mSsl,(const char*)buf,count);
00430    if (ret < 0 )
00431    {
00432       int err = SSL_get_error(mSsl,ret);
00433       switch (err)
00434       {
00435          case SSL_ERROR_WANT_READ:
00436          case SSL_ERROR_WANT_WRITE:
00437          case SSL_ERROR_NONE:
00438          {
00439             StackLog( << "Got TLS write got condition of " << err  );
00440             return 0;
00441          }
00442          break;
00443          default:
00444          {
00445             while (true)
00446             {
00447                const char* file;
00448                int line;
00449                
00450                unsigned long code = ERR_get_error_line(&file,&line);
00451                if ( code == 0 )
00452                {
00453                   break;
00454                }
00455                
00456                char buf[256];
00457                ERR_error_string_n(code,buf,sizeof(buf));
00458                ErrLog( << buf  );
00459                DebugLog( << "Error code = " << code << " file=" << file << " line=" << line );
00460             }
00461             ErrLog( << "Got TLS write error=" << err << " ret=" << ret  );
00462             return -1;
00463          }
00464          break;
00465       }
00466    }
00467 
00468    Data monkey(Data::Borrow, buf, count);
00469 
00470    StackLog( << "Did TLS write " << ret << " " << count << " " << "[[" << monkey << "]]" );
00471 
00472    return ret;
00473 #endif // USE_SSL
00474    return -1;
00475 }
00476 
00477 
00478 bool 
00479 TlsConnection::hasDataToRead() // has data that can be read 
00480 {
00481 #if defined(USE_SSL)
00482    //hack (for now)
00483    if(mTlsState == Initial)
00484       return false;
00485 
00486    if (checkState() != Up)
00487    {
00488       return false;
00489    }
00490 
00491    int p = SSL_pending(mSsl);
00492    //DebugLog(<<"hasDataToRead(): " <<p);
00493    return (p>0);
00494 #else // USE_SSL
00495    return false;
00496 #endif 
00497 }
00498 
00499 
00500 bool 
00501 TlsConnection::isGood() // has data that can be read 
00502 {
00503 #if defined(USE_SSL)
00504    if ( mBio == 0 )
00505    {
00506       return false;
00507    }
00508 
00509    int mode = SSL_get_shutdown(mSsl);
00510    if ( mode != 0 ) 
00511    {
00512       return false;
00513    }
00514 
00515 #endif       
00516    return true;
00517 }
00518 
00519 bool 
00520 TlsConnection::isWritable() 
00521 {
00522 #if defined(USE_SSL)
00523    switch(mTlsState)
00524    {
00525       case Handshaking:
00526          return mHandShakeWantsRead ? false : true;
00527       case Initial:
00528       case Up:
00529          return isGood();
00530       default:
00531          return false;
00532    }
00533    //dragos -- to remove
00534    DebugLog( << "Current state: " << fromState(mTlsState));
00535    //end dragos
00536 #endif 
00537    return false;
00538 }
00539 
00540 void TlsConnection::getPeerNames(std::list<Data> &peerNames) const
00541 {
00542    for(std::list<BaseSecurity::PeerName>::const_iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)
00543 {
00544       peerNames.push_back(it->mName);
00545    }
00546 }
00547 
00548 Data
00549 TlsConnection::getPeerNamesData() const
00550 {
00551    Data peerNamesString;
00552    for(std::list<BaseSecurity::PeerName>::const_iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)
00553    {
00554       if(it == mPeerNames.begin())
00555       {
00556          peerNamesString += it->mName;
00557       }
00558       else
00559       {
00560          peerNamesString += ", " + it->mName;
00561       }
00562    }
00563    return peerNamesString;
00564 }
00565 
00566 
00567 void
00568 TlsConnection::computePeerName()
00569 {
00570 #if defined(USE_SSL)
00571    Data commonName;
00572 
00573    assert(mSsl);
00574 
00575    if (!mBio)
00576    {
00577       ErrLog( << "bad bio" );
00578       return;
00579    }
00580 
00581    // print session infor       
00582    const SSL_CIPHER *ciph;
00583    ciph=SSL_get_current_cipher(mSsl);
00584    InfoLog( << "TLS sessions set up with " 
00585             <<  SSL_get_version(mSsl) << " "
00586             <<  SSL_CIPHER_get_version(ciph) << " "
00587             <<  SSL_CIPHER_get_name(ciph) << " " );
00588 
00589    // get the certificate if other side has one 
00590    X509* cert = SSL_get_peer_certificate(mSsl);
00591    if ( !cert )
00592    {
00593       DebugLog(<< "No peer certificate in TLS connection" );
00594       return;
00595    }
00596 
00597    // check that this certificate is valid 
00598    if (X509_V_OK != SSL_get_verify_result(mSsl))
00599    {
00600       DebugLog(<< "Peer certificate in TLS connection is not valid" );
00601       X509_free(cert); cert=NULL;
00602       return;
00603    }
00604 
00605    TlsTransport *t = dynamic_cast<TlsTransport*>(mTransport);
00606    assert(t);
00607 
00608    mPeerNames.clear();
00609    BaseSecurity::getCertNames(cert, mPeerNames,
00610       t->isUseEmailAsSIP());
00611    if(mPeerNames.empty())
00612    {
00613       ErrLog(<< "Invalid certificate: no subjectAltName/CommonName found");
00614       return;
00615    }
00616 
00617    if(!mServer)
00618    {
00619       // add the certificate to the Security store
00620       unsigned char* buf = NULL;
00621       int len = i2d_X509( cert, &buf );
00622       Data derCert( buf, len );
00623       for(std::list<BaseSecurity::PeerName>::iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)
00624       {
00625          if ( !mSecurity->hasDomainCert( it->mName ) )
00626          {
00627             mSecurity->addDomainCertDER(it->mName,derCert);
00628          }
00629       }
00630       OPENSSL_free(buf); buf=NULL;
00631    }
00632 
00633    X509_free(cert); cert=NULL;
00634 #endif // USE_SSL
00635 }
00636 
00637 /* ====================================================================
00638  * The Vovida Software License, Version 1.0 
00639  * 
00640  * Copyright (c) 2000-2005 Vovida Networks, Inc.  All rights reserved.
00641  * 
00642  * Redistribution and use in source and binary forms, with or without
00643  * modification, are permitted provided that the following conditions
00644  * are met:
00645  * 
00646  * 1. Redistributions of source code must retain the above copyright
00647  *    notice, this list of conditions and the following disclaimer.
00648  * 
00649  * 2. Redistributions in binary form must reproduce the above copyright
00650  *    notice, this list of conditions and the following disclaimer in
00651  *    the documentation and/or other materials provided with the
00652  *    distribution.
00653  * 
00654  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00655  *    and "Vovida Open Communication Application Library (VOCAL)" must
00656  *    not be used to endorse or promote products derived from this
00657  *    software without prior written permission. For written
00658  *    permission, please contact vocal@vovida.org.
00659  *
00660  * 4. Products derived from this software may not be called "VOCAL", nor
00661  *    may "VOCAL" appear in their name, without prior written
00662  *    permission of Vovida Networks, Inc.
00663  * 
00664  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00665  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00666  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00667  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00668  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00669  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00670  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00671  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00672  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00673  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00674  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00675  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00676  * DAMAGE.
00677  * 
00678  * ====================================================================
00679  * 
00680  * This software consists of voluntary contributions made by Vovida
00681  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00682  * Inc.  For more information on Vovida Networks, Inc., please see
00683  * <http://www.vovida.org/>.
00684  *
00685  */