PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/qwaqvm/platforms/Cross/third-party/resiprocate-src-1.6/resip/stack/ssl/DtlsTransport.cxx

http://openqwaq.googlecode.com/
C++ | 701 lines | 467 code | 116 blank | 118 comment | 49 complexity | 190394a69c0d0b58fce3b6bba67b034b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0, BSD-3-Clause
  1. #ifdef USE_SSL
  2. #ifdef USE_DTLS
  3. #if defined(HAVE_CONFIG_H)
  4. #include "resip/stack/config.hxx"
  5. #endif
  6. #include <memory>
  7. #ifndef RESIP_COMPAT_HXX
  8. #include "rutil/compat.hxx"
  9. #endif
  10. #ifndef RESIP_DATA_HXX
  11. #include "rutil/Data.hxx"
  12. #endif
  13. #ifndef RESIP_DNSUTIL_HXX
  14. #include "rutil/DnsUtil.hxx"
  15. #endif
  16. #ifndef RESIP_SOCKET_HXX
  17. #include "rutil/Socket.hxx"
  18. #endif
  19. #ifndef RESIP_LOGGER_HXX
  20. #include "rutil/Logger.hxx"
  21. #endif
  22. #ifndef RESIP_SIPMESSAGE_HXX
  23. #include "resip/stack/SipMessage.hxx"
  24. #endif
  25. #ifndef RESIP_HELPER_HXX
  26. #include "resip/stack/Helper.hxx"
  27. #endif
  28. #ifndef RESIP_SECURITY_HXX
  29. #include "resip/stack/ssl/Security.hxx"
  30. #endif
  31. #ifndef RESIP_DTLSMESSAGE_HXX
  32. #include "resip/stack/DtlsMessage.hxx"
  33. #endif
  34. #ifndef RESIP_DTLSTRANSPORT_HXX
  35. #include "resip/stack/ssl/DtlsTransport.hxx"
  36. #endif
  37. #include "rutil/WinLeakCheck.hxx"
  38. #include <openssl/e_os2.h>
  39. #include <openssl/evp.h>
  40. #include <openssl/crypto.h>
  41. #include <openssl/err.h>
  42. #include <openssl/pem.h>
  43. #include <openssl/pkcs7.h>
  44. #include <openssl/x509v3.h>
  45. #include <openssl/ssl.h>
  46. #ifdef USE_SIGCOMP
  47. #include <osc/Stack.h>
  48. #include <osc/StateChanges.h>
  49. #include <osc/SigcompMessage.h>
  50. #endif
  51. #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
  52. using namespace std;
  53. using namespace resip;
  54. DtlsTransport::DtlsTransport(Fifo<TransactionMessage>& fifo,
  55. int portNum,
  56. IpVersion version,
  57. const Data& interfaceObj,
  58. Security& security,
  59. const Data& sipDomain,
  60. AfterSocketCreationFuncPtr socketFunc,
  61. Compression& compression)
  62. : UdpTransport( fifo, portNum, version,
  63. StunDisabled, interfaceObj, socketFunc, compression ),
  64. mTimer( mHandshakePending ),
  65. mSecurity( &security ),
  66. mDomain(sipDomain)
  67. {
  68. setTlsDomain(sipDomain);
  69. InfoLog ( << "Creating DTLS transport host=" << interfaceObj
  70. << " port=" << mTuple.getPort()
  71. << " ipv4=" << version ) ;
  72. mTuple.setType( transport() );
  73. mClientCtx = SSL_CTX_new( DTLSv1_client_method() ) ;
  74. mServerCtx = SSL_CTX_new( DTLSv1_server_method() ) ;
  75. assert( mClientCtx ) ;
  76. assert( mServerCtx ) ;
  77. mDummyBio = BIO_new( BIO_s_mem() ) ;
  78. assert( mDummyBio ) ;
  79. mSendData = NULL ;
  80. /* trying to read from this BIO always returns retry */
  81. BIO_set_mem_eof_return( mDummyBio, -1 ) ;
  82. }
  83. DtlsTransport::~DtlsTransport()
  84. {
  85. DebugLog (<< "Shutting down " << mTuple);
  86. while(mDtlsConnections.begin() != mDtlsConnections.end())
  87. {
  88. _cleanupConnectionState(mDtlsConnections.begin()->second, mDtlsConnections.begin()->first);
  89. }
  90. SSL_CTX_free(mClientCtx);mClientCtx=0;
  91. SSL_CTX_free(mServerCtx);mServerCtx=0;
  92. BIO_free( mDummyBio) ;
  93. }
  94. void
  95. DtlsTransport::_read( FdSet& fdset )
  96. {
  97. //should this buffer be allocated on the stack and then copied out, as it
  98. //needs to be deleted every time EWOULDBLOCK is encountered
  99. // .dlb. can we determine the size of the buffer before we allocate?
  100. // something about MSG_PEEK|MSG_TRUNC in Stevens..
  101. // .dlb. RFC3261 18.1.1 MUST accept 65K datagrams. would have to attempt to
  102. // adjust the UDP buffer as well...
  103. unsigned int bufferLen = UdpTransport::MaxBufferSize + 5 ;
  104. char* buffer = new char[ bufferLen ] ;
  105. unsigned char *pt = new unsigned char[ bufferLen ] ;
  106. SSL *ssl ;
  107. BIO *rbio ;
  108. BIO *wbio ;
  109. // !jf! how do we tell if it discarded bytes
  110. // !ah! we use the len-1 trick :-(
  111. Tuple tuple(mTuple) ;
  112. socklen_t slen = tuple.length() ;
  113. int len = recvfrom( mFd,
  114. buffer,
  115. UdpTransport::MaxBufferSize,
  116. 0 /*flags */,
  117. &tuple.getMutableSockaddr(),
  118. &slen ) ;
  119. if ( len == SOCKET_ERROR )
  120. {
  121. int err = getErrno() ;
  122. if ( err != EWOULDBLOCK )
  123. {
  124. error( err ) ;
  125. }
  126. }
  127. if (len == 0 || len == SOCKET_ERROR)
  128. {
  129. delete [] buffer ;
  130. buffer = 0 ;
  131. return ;
  132. }
  133. if ( len + 1 >= UdpTransport::MaxBufferSize )
  134. {
  135. InfoLog (<<"Datagram exceeded max length "<<UdpTransport::MaxBufferSize ) ;
  136. delete [] buffer ; buffer = 0 ;
  137. return ;
  138. }
  139. //DebugLog ( << "UDP Rcv : " << len << " b" );
  140. //DebugLog ( << Data(buffer, len).escaped().c_str());
  141. /* begin SSL stuff */
  142. struct sockaddr peer = tuple.getMutableSockaddr() ;
  143. ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ;
  144. /*
  145. * If we don't have a binding for this peer,
  146. * then we're a server.
  147. */
  148. if ( ssl == NULL )
  149. {
  150. ssl = SSL_new( mServerCtx ) ;
  151. assert( ssl ) ;
  152. SSL_set_accept_state( ssl ) ;
  153. X509 *cert = mSecurity->getDomainCert( mDomain ) ;
  154. EVP_PKEY *pkey = mSecurity->getDomainKey( mDomain ) ;
  155. if( !cert )
  156. {
  157. Data error = Data("Could not load certifiacte for domain: ")
  158. + mDomain;
  159. throw Security::Exception( error,__FILE__, __LINE__ ) ;
  160. }
  161. if( !pkey )
  162. {
  163. Data error = Data("Could not load private key for domain: ")
  164. + mDomain;
  165. throw Security::Exception( error,__FILE__, __LINE__ ) ;
  166. }
  167. assert( cert ) ;
  168. assert( pkey ) ;
  169. if( ! SSL_use_certificate( ssl, cert ) )
  170. {
  171. throw Security::Exception( "SSL_use_certificate failed",
  172. __FILE__, __LINE__ ) ;
  173. }
  174. if ( ! SSL_use_PrivateKey( ssl, pkey ) )
  175. throw Security::Exception( "SSL_use_PrivateKey failed.",
  176. __FILE__, __LINE__ ) ;
  177. wbio = BIO_new_dgram( mFd, BIO_NOCLOSE ) ;
  178. assert( wbio ) ;
  179. BIO_dgram_set_peer( wbio, &peer ) ;
  180. SSL_set_bio( ssl, NULL, wbio ) ;
  181. /* remember this connection */
  182. mDtlsConnections[ *((struct sockaddr_in *)&peer) ] = ssl ;
  183. }
  184. rbio = BIO_new_mem_buf( buffer, len ) ;
  185. BIO_set_mem_eof_return( rbio, -1 ) ;
  186. ssl->rbio = rbio ;
  187. len = SSL_read( ssl, pt, UdpTransport::MaxBufferSize ) ;
  188. int err = SSL_get_error( ssl, len ) ;
  189. /* done with the rbio */
  190. BIO_free( ssl->rbio ) ;
  191. ssl->rbio = mDummyBio ;
  192. delete [] buffer ;
  193. buffer = 0 ;
  194. if ( len <= 0 )
  195. {
  196. switch( err )
  197. {
  198. case SSL_ERROR_NONE:
  199. break ;
  200. case SSL_ERROR_SSL:
  201. break ;
  202. case SSL_ERROR_WANT_READ:
  203. break ;
  204. case SSL_ERROR_WANT_WRITE:
  205. break ;
  206. case SSL_ERROR_SYSCALL:
  207. break ;
  208. /* connection closed */
  209. case SSL_ERROR_ZERO_RETURN:
  210. _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ;
  211. break ;
  212. case SSL_ERROR_WANT_CONNECT:
  213. break ;
  214. case SSL_ERROR_WANT_ACCEPT:
  215. break ;
  216. default:
  217. break ;
  218. }
  219. }
  220. if ( len <= 0 )
  221. return ;
  222. if ( SSL_in_init( ssl ) )
  223. mTimer.add( ssl, DtlsReceiveTimeout ) ;
  224. #ifdef USE_SIGCOMP
  225. osc::StateChanges *sc = 0;
  226. #endif
  227. if ((pt[0] & 0xf8) == 0xf8)
  228. {
  229. if(!mCompression.isEnabled())
  230. {
  231. InfoLog(<< "Discarding unexpected SigComp message");
  232. delete [] pt;
  233. return;
  234. }
  235. #ifdef USE_SIGCOMP
  236. unsigned char *newPt = new unsigned char[ bufferLen ] ;
  237. size_t uncompressedLength =
  238. mSigcompStack->uncompressMessage(pt, len,
  239. newPt, UdpTransport::MaxBufferSize,
  240. sc);
  241. DebugLog (<< "Unompressed message from "
  242. << len << " bytes to "
  243. << uncompressedLength << " bytes");
  244. osc::SigcompMessage *nack = mSigcompStack->getNack();
  245. if (nack)
  246. {
  247. mTxFifo.add(new SendData(tuple,
  248. Data(nack->getDatagramMessage(),
  249. nack->getDatagramLength()),
  250. Data::Empty,
  251. Data::Empty,
  252. true)
  253. );
  254. delete nack;
  255. }
  256. delete[] buffer;
  257. buffer = newBuffer;
  258. len = uncompressedLength;
  259. #endif
  260. }
  261. SipMessage* message = new SipMessage(this);
  262. // set the received from information into the received= parameter in the
  263. // via
  264. // It is presumed that UDP Datagrams are arriving atomically and that
  265. // each one is a unique SIP message
  266. // Save all the info where this message came from
  267. tuple.transport = this ;
  268. message->setSource( tuple ) ;
  269. //DebugLog (<< "Received from: " << tuple);
  270. // Tell the SipMessage about this datagram buffer.
  271. message->addBuffer( (char *)pt ) ;
  272. mMsgHeaderScanner.prepareForMessage( message ) ;
  273. char *unprocessedCharPtr ;
  274. if (mMsgHeaderScanner.scanChunk( (char *)pt,
  275. len,
  276. &unprocessedCharPtr ) !=
  277. MsgHeaderScanner::scrEnd)
  278. {
  279. DebugLog( << "Scanner rejecting datagram as unparsable / fragmented from "
  280. << tuple ) ;
  281. DebugLog( << Data( pt, len ) ) ;
  282. delete message ;
  283. message = 0 ;
  284. return ;
  285. }
  286. // no pp error
  287. int used = unprocessedCharPtr - (char *)pt ;
  288. if ( used < len )
  289. {
  290. // body is present .. add it up.
  291. // NB. The Sip Message uses an overlay (again)
  292. // for the body. It ALSO expects that the body
  293. // will be contiguous (of course).
  294. // it doesn't need a new buffer in UDP b/c there
  295. // will only be one datagram per buffer. (1:1 strict)
  296. message->setBody( (char *)pt + used, len - used ) ;
  297. //DebugLog(<<"added " << len-used << " byte body");
  298. }
  299. if ( ! basicCheck( *message ) )
  300. {
  301. delete message ; // cannot use it, so, punt on it...
  302. // basicCheck queued any response required
  303. message = 0 ;
  304. return ;
  305. }
  306. stampReceived( message) ;
  307. #ifdef USE_SIGCOMP
  308. if (mCompression.isEnabled() && sc)
  309. {
  310. const Via &via = message->header(h_Vias).front();
  311. if (message->isRequest())
  312. {
  313. // For requests, the compartment ID is read out of the
  314. // top via header field; if not present, we use the
  315. // TCP connection for identification purposes.
  316. if (via.exists(p_sigcompId))
  317. {
  318. Data compId = via.param(p_sigcompId);
  319. mSigcompStack->provideCompartmentId(
  320. sc, compId.data(), compId.size());
  321. }
  322. else
  323. {
  324. mSigcompStack->provideCompartmentId(sc, this, sizeof(this));
  325. }
  326. }
  327. else
  328. {
  329. // For responses, the compartment ID is supposed to be
  330. // the same as the compartment ID of the request. We
  331. // *could* dig down into the transaction layer to try to
  332. // figure this out, but that's a royal pain, and a rather
  333. // severe layer violation. In practice, we're going to ferret
  334. // the ID out of the the Via header field, which is where we
  335. // squirreled it away when we sent this request in the first place.
  336. Data compId = via.param(p_branch).getSigcompCompartment();
  337. mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size());
  338. }
  339. }
  340. #endif
  341. mStateMachineFifo.add( message ) ;
  342. }
  343. void DtlsTransport::_write( FdSet& fdset )
  344. {
  345. SSL *ssl ;
  346. BIO *wBio ;
  347. int retry = 0 ;
  348. SendData *sendData ;
  349. if ( mSendData != NULL )
  350. sendData = mSendData ;
  351. else
  352. sendData = mTxFifo.getNext() ;
  353. //DebugLog (<< "Sent: " << sendData->data);
  354. //DebugLog (<< "Sending message on udp.");
  355. assert( &(*sendData) );
  356. assert( sendData->destination.getPort() != 0 );
  357. sockaddr peer = sendData->destination.getSockaddr();
  358. ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ;
  359. /* If we don't have a binding, then we're a client */
  360. if ( ssl == NULL )
  361. {
  362. ssl = SSL_new( mClientCtx ) ;
  363. assert( ssl ) ;
  364. SSL_set_connect_state( ssl ) ;
  365. wBio = BIO_new_dgram( mFd, BIO_NOCLOSE ) ;
  366. assert( wBio ) ;
  367. BIO_dgram_set_peer( wBio, &peer) ;
  368. /* the real rbio will be set by _read */
  369. SSL_set_bio( ssl, mDummyBio, wBio ) ;
  370. /* we should be ready to take this out if the
  371. * connection fails later */
  372. mDtlsConnections [ *((struct sockaddr_in *)&peer) ] = ssl ;
  373. }
  374. int expected;
  375. int count;
  376. #ifdef USE_SIGCOMP
  377. // If message needs to be compressed, compress it here.
  378. if (mSigcompStack &&
  379. sendData->sigcompId.size() > 0 &&
  380. !sendData->isAlreadyCompressed )
  381. {
  382. osc::SigcompMessage *sm = mSigcompStack->compressMessage
  383. (sendData->data.data(), sendData->data.size(),
  384. sendData->sigcompId.data(), sendData->sigcompId.size(),
  385. isReliable());
  386. DebugLog (<< "Compressed message from "
  387. << sendData->data.size() << " bytes to "
  388. << sm->getDatagramLength() << " bytes");
  389. expected = sm->getDatagramLength();
  390. count = SSL_Write(ssl,
  391. sm->getDatagramMessage(),
  392. sm->getDatagramLength());
  393. delete sm;
  394. }
  395. else
  396. #endif
  397. {
  398. expected = sendData->data.size();
  399. count = SSL_write(ssl, sendData->data.data(),
  400. sendData->data.size());
  401. }
  402. /*
  403. * all reads go through _read, so the most likely result during a handshake
  404. * will be SSL_ERROR_WANT_READ
  405. */
  406. if ( count <= 0 )
  407. {
  408. /* cache unqueued data */
  409. mSendData = sendData ;
  410. int err = SSL_get_error( ssl, count ) ;
  411. switch( err )
  412. {
  413. case SSL_ERROR_NONE:
  414. break;
  415. case SSL_ERROR_SSL:
  416. break;
  417. case SSL_ERROR_WANT_READ:
  418. retry = 1 ;
  419. break;
  420. case SSL_ERROR_WANT_WRITE:
  421. retry = 1 ;
  422. fdset.setWrite(mFd);
  423. break;
  424. case SSL_ERROR_SYSCALL:
  425. {
  426. int e = getErrno();
  427. error(e);
  428. InfoLog (<< "Failed (" << e << ") sending to "
  429. << sendData->destination);
  430. fail(sendData->transactionId);
  431. break;
  432. }
  433. case SSL_ERROR_ZERO_RETURN:
  434. _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ;
  435. break ;
  436. case SSL_ERROR_WANT_CONNECT:
  437. break;
  438. case SSL_ERROR_WANT_ACCEPT:
  439. break;
  440. default:
  441. break ;
  442. }
  443. }
  444. else
  445. {
  446. mSendData = NULL ;
  447. }
  448. /*
  449. * ngm: is sendData deleted by a higher layer? Seems to be the case after
  450. * checking with UdpTransport
  451. */
  452. if ( ! retry && count != int(sendData->data.size()) )
  453. {
  454. ErrLog (<< "UDPTransport - send buffer full" );
  455. fail(sendData->transactionId);
  456. }
  457. }
  458. void
  459. DtlsTransport::_doHandshake( void )
  460. {
  461. DtlsMessage *msg = mHandshakePending.getNext() ;
  462. SSL *ssl = msg->getSsl() ;
  463. delete msg ;
  464. int ret = SSL_do_handshake( ssl ) ;
  465. switch( ret )
  466. {
  467. case SSL_ERROR_NONE:
  468. break;
  469. case SSL_ERROR_SSL:
  470. break;
  471. case SSL_ERROR_WANT_READ:
  472. break;
  473. case SSL_ERROR_WANT_WRITE:
  474. break;
  475. case SSL_ERROR_SYSCALL:
  476. break;
  477. case SSL_ERROR_ZERO_RETURN:
  478. break;
  479. case SSL_ERROR_WANT_CONNECT:
  480. break;
  481. case SSL_ERROR_WANT_ACCEPT:
  482. break;
  483. default:
  484. break ;
  485. }
  486. }
  487. void
  488. DtlsTransport::process(FdSet& fdset)
  489. {
  490. // pull buffers to send out of TxFifo
  491. // receive datagrams from fd
  492. // preparse and stuff into RxFifo
  493. mTimer.process() ;
  494. while ( mHandshakePending.messageAvailable() )
  495. _doHandshake() ;
  496. if ( ( mSendData != NULL || mTxFifo.messageAvailable() )
  497. && fdset.readyToWrite( mFd ) )
  498. _write( fdset ) ;
  499. // !jf! this may have to change - when we read a message that is too big
  500. if ( fdset.readyToRead(mFd) )
  501. _read( fdset ) ;
  502. }
  503. void
  504. DtlsTransport::buildFdSet( FdSet& fdset )
  505. {
  506. fdset.setRead(mFd);
  507. if ( mSendData != NULL || mTxFifo.messageAvailable() )
  508. {
  509. fdset.setWrite(mFd);
  510. }
  511. }
  512. void
  513. DtlsTransport::_cleanupConnectionState( SSL *ssl, struct sockaddr_in peer )
  514. {
  515. /*
  516. * SSL_free decrements the ref-count for mDummyBio by 1, so
  517. * add 1 to the ref-count to make sure it does not get free'd
  518. */
  519. CRYPTO_add( &mDummyBio->references, 1, CRYPTO_LOCK_BIO ) ;
  520. SSL_free( ssl ) ;
  521. mDtlsConnections.erase( peer ) ;
  522. }
  523. void
  524. DtlsTransport::_mapDebug( const char *where, const char *action, SSL *ssl )
  525. {
  526. fprintf( stderr, "%s: %s\t%p\n", where, action, ssl ) ;
  527. fprintf( stderr, "map sizet = %d\n", mDtlsConnections.size() ) ;
  528. }
  529. void
  530. DtlsTransport::_printSock( const struct sockaddr_in *sock )
  531. {
  532. fprintf( stderr, "addr = %s\t port = %d\n", inet_ntoa( sock->sin_addr ),
  533. ntohs( sock->sin_port ) ) ;
  534. }
  535. #endif /* USE_DTLS */
  536. #endif /* USE_SSL */
  537. /* ====================================================================
  538. * The Vovida Software License, Version 1.0
  539. *
  540. * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
  541. *
  542. * Redistribution and use in source and binary forms, with or without
  543. * modification, are permitted provided that the following conditions
  544. * are met:
  545. *
  546. * 1. Redistributions of source code must retain the above copyright
  547. * notice, this list of conditions and the following disclaimer.
  548. *
  549. * 2. Redistributions in binary form must reproduce the above copyright
  550. * notice, this list of conditions and the following disclaimer in
  551. * the documentation and/or other materials provided with the
  552. * distribution.
  553. *
  554. * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  555. * and "Vovida Open Communication Application Library (VOCAL)" must
  556. * not be used to endorse or promote products derived from this
  557. * software without prior written permission. For written
  558. * permission, please contact vocal@vovida.org.
  559. *
  560. * 4. Products derived from this software may not be called "VOCAL", nor
  561. * may "VOCAL" appear in their name, without prior written
  562. * permission of Vovida Networks, Inc.
  563. *
  564. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  565. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  566. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  567. * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
  568. * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  569. * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  570. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  571. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  572. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  573. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  574. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  575. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  576. * DAMAGE.
  577. *
  578. * ====================================================================
  579. *
  580. * This software consists of voluntary contributions made by Vovida
  581. * Networks, Inc. and many individuals on behalf of Vovida Networks,
  582. * Inc. For more information on Vovida Networks, Inc., please see
  583. * <http://www.vovida.org/>.
  584. *
  585. */