1 /*
2  *
3  *  Copyright (C) 1998-2018, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module: dcmnet
15  *
16  *  Author: Marco Eichelberg
17  *
18  *  Purpose:
19  *    classes: DcmTransportConnection
20  *
21  */
22 
23 #ifndef TLSTRANS_H
24 #define TLSTRANS_H
25 
26 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
27 #include "dcmtk/dcmnet/dcmtrans.h"    /* for DcmTransportConnection */
28 #include "dcmtk/ofstd/ofstream.h"    /* for ostream */
29 #include "dcmtk/dcmtls/tlsdefin.h"
30 
31 #ifdef WITH_OPENSSL
32 
33 // forward declarations of OpenSSL data structures
34 struct ssl_st;
35 typedef struct ssl_st SSL;
36 
37 /** this class represents a TLS (Transport Layer Security) V1 based secure
38  *  transport connection.
39  *  @remark This class is only available if DCMTK is compiled with
40  *  OpenSSL support enabled.
41  */
42 class DCMTK_DCMTLS_EXPORT DcmTLSConnection: public DcmTransportConnection
43 {
44 public:
45 
46   /** constructor.
47    *  @param openSocket TCP/IP socket to be used for the transport connection.
48    *    the connection must already be established on socket level. This object
49    *    takes over control of the socket.
50    *  @param newTLSConnection pointer to initialized OpenSSL connection object
51    *    to be used for this connection.
52    */
53   DcmTLSConnection(DcmNativeSocketType openSocket, SSL *newTLSConnection);
54 
55   /** destructor
56    */
57   virtual ~DcmTLSConnection();
58 
59   /** performs server side handshake on established socket.
60    *  This function is used to establish a secure transport connection
61    *  over the established TCP connection.
62    *  @return TCS_ok if successful, an error code otherwise.
63    */
64   virtual DcmTransportLayerStatus serverSideHandshake();
65 
66   /** performs client side handshake on established socket.
67    *  This function is used to establish a secure transport connection
68    *  over the established TCP connection.
69    *  @return TCS_ok if successful, an error code otherwise.
70    */
71   virtual DcmTransportLayerStatus clientSideHandshake();
72 
73   /** performs a re-negotiation of the connection with different
74    *  connection parameters. Used to change the parameters of the
75    *  secure transport connection.
76    *  @param newSuite string identifying the ciphersuite to be negotiated.
77    *  @return TCS_ok if successful, an error code otherwise.
78    */
79   virtual DcmTransportLayerStatus renegotiate(const char *newSuite);
80 
81   /** attempts to read nbyte bytes from the transport connection and
82    *  writes them into the given buffer.
83    *  @param buf buffer
84    *  @param nbyte number of bytes to read
85    *  @return number of bytes read, negative number if unsuccessful.
86    */
87   virtual ssize_t read(void *buf, size_t nbyte);
88 
89   /** attempts to write nbyte bytes from the given buffer
90    *  to the transport connection.
91    *  @param buf buffer
92    *  @param nbyte number of bytes to write
93    *  @return number of bytes written, negative number if unsuccessful.
94    */
95   virtual ssize_t write(void *buf, size_t nbyte);
96 
97   /** Closes the transport connection. If a secure connection
98    *  is used, a closure alert is sent before the connection
99    *  is closed.
100    */
101   virtual void close();
102 
103   /** returns the size in bytes of the peer certificate of a secure connection.
104    *  @return peer certificate length in bytes
105    */
106   virtual unsigned long getPeerCertificateLength();
107 
108   /* copies the peer certificate of a secure connection into a buffer
109    * specified by the caller. If the buffer is too small to hold the
110    * certificate, nothing is copied and zero is returned.
111    * @param buf buffer into which the certificate is written
112    * @param bufLen size of the buffer in bytes
113    * @return number of bytes written, always less or equal bufLen.
114    */
115   virtual unsigned long getPeerCertificate(void *buf, unsigned long bufLen);
116 
117   /** checks if data is available to be read on the transport connection.
118    *  @param timeout maximum number of seconds to wait if no data is available.
119    *     If this parameter is 0, the function does not block.
120    *  @returns OFTrue if data is available, OFFalse otherwise.
121    */
122   virtual OFBool networkDataAvailable(int timeout);
123 
124   /** returns OFTrue if this connection is a transparent TCP connection,
125    *  OFFalse if the connection is a secure connection.
126    */
127   virtual OFBool isTransparentConnection();
128 
129   /** dump the characteristics of the current connection
130    *  @param str the string to dump into
131    *  @return reference to string
132    */
133   virtual OFString& dumpConnectionParameters(OFString& str);
134 
135   /** returns an error string for a given error code.
136    *  @param code error code
137    *  @return description for error code
138    */
139   virtual const char *errorString(DcmTransportLayerStatus code);
140 
141 private:
142 
143   /// private undefined copy constructor
144   DcmTLSConnection(const DcmTLSConnection&);
145 
146   /// private undefined assignment operator
147   DcmTLSConnection& operator=(const DcmTLSConnection&);
148 
149   /// dump TLS connection details to debug logger
150   void logTLSConnection();
151 
152   /// pointer to the TLS connection structure used by the OpenSSL library
153   SSL *tlsConnection;
154 
155   /// last error code returned by the OpenSSL library
156   unsigned long lastError;
157 };
158 
159 #endif /* WITH_OPENSSL */
160 
161 #endif
162