1 /*
2  *
3  *  Copyright (C) 2017-2019, 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: dcmtls
15  *
16  *  Author: Jan Schlamelcher, Marco Eichelberg
17  *
18  *  Purpose:
19  *    classes: DcmTLSOptions
20  *
21  */
22 
23 #ifndef TLSOPT_H
24 #define TLSOPT_H
25 
26 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
27 #include "dcmtk/ofstd/ofstream.h"     /* for ostream */
28 #include "dcmtk/dcmtls/tlslayer.h"    /* for DcmTLSTransportLayer */
29 
30 class OFConsoleApplication;
31 class OFCommandLine;
32 class DcmTLSTransportLayer;
33 struct T_ASC_Network;
34 struct T_ASC_Parameters;
35 
36 /** A class that handles the command line arguments used by applications
37  *  that support TLS.
38  *  DcmTLSOptions handles storing the relevant options, printing the associated
39  *  help text an information (e.g. OpenSSL library version), parsing and
40  *  evaluating the given command line arguments and creating a
41  *  DcmTLSTransportLayer object based on the collected information.
42  */
43 class DCMTK_DCMTLS_EXPORT DcmTLSOptions
44 {
45 public:
46 
47     /** Constructor.
48      *  @param networkRole the network role to create a transport layer for
49      */
50     DcmTLSOptions(T_ASC_NetworkRole networkRole);
51 
52     /// Destructor
53     virtual ~DcmTLSOptions();
54 
55     /** Add TLS specific command line options to the OFCommandLine object
56      *  passed to the constructor.
57      *  @param cmd a reference to an OFCommandLine object used to parse
58      *    the command line argument give to the calling application.
59      */
60     void addTLSCommandlineOptions(OFCommandLine& cmd);
61 
62     /** Parse and evaluate the given command line arguments.
63      *  @param app a reference to an OFConsoleApplication object used in the
64      *    calling application.
65      *  @param cmd a reference to an OFCommandLine object used to parse
66      *    the command line argument give to the calling application.
67      */
68     void parseArguments(OFConsoleApplication& app, OFCommandLine& cmd);
69 
70     /** Create a DcmTLSTransportLayer object based on the collected command
71      *  line arguments.
72      *  @param net pointer to network object in which the transport layer
73      *    should be registered. May be NULL, in which case the caller
74      *    must activate the transport layer manually using ASC_setTransportLayer().
75      *  @param params pointer to the association negotiation parameters object.
76      *    For an association acceptor, this parameter is passed as NULL.
77      *    If NULL is passed and the caller in an association requestor,
78      *    then it is the responsibility of the caller to call ASC_setTransportLayerType()
79      *    and set the right transport layer type for the association parameters.
80      *  @param app a reference to an OFConsoleApplication object used in the
81      *    calling application.
82      *  @param cmd a reference to an OFCommandLine object used to parse
83      *    the command line argument give to the calling application.
84      *  @return EC_Normal if successful, an error code otherwise
85      */
86     OFCondition createTransportLayer(
87       T_ASC_Network *net,
88       T_ASC_Parameters *params,
89       OFConsoleApplication& app,
90       OFCommandLine& cmd);
91 
92     /** Update the random seed file if this was requested by the given command
93      *  line arguments.
94      *  @return EC_Normal if the random seed file was successfully updated or
95      *    if the user did not request the random seed file to be update. An
96      *    error condition indicating what went wrong in case the random seed
97      *    file could not be updated.
98      */
99     OFCondition writeRandomSeed();
100 
101     /** Returns true if a secure connection was requested, false otherwise.
102      *  Caller must ensure that parseArguments() has been run before this method.
103      *  @return true if secure connection requested, false otherwise
104      */
105     OFBool secureConnectionRequested() const;
106 
107     /** Returns a pointer to the transport layer object, or NULL if the object
108      *  has not yet been created by a call to createTransportLayer().
109      *  @return pointer to transport layer object, may be NULL.
110      */
111     DcmTransportLayer *getTransportLayer();
112 
113     /** checks if the command line option --list-ciphers was given.
114      *  In this case the list of supported TLS ciphersuites should be
115      *  printed to stdout and the application should terminate.
116      *  @return true if --list-ciphers option was found, false otherwise.
117      */
118     static OFBool listOfCiphersRequested(OFCommandLine& cmd);
119 
120     /** print a list of supported ciphersuites to the given output stream
121      *  @param app a reference to an OFConsoleApplication object used in the
122      *    calling application.
123      *  @param os output stream
124      */
125     static void printSupportedCiphersuites(OFConsoleApplication& app, STD_NAMESPACE ostream& os);
126 
127     /** Print OpenSSL library version string.
128      *  Does nothing if OpenSSL is not available.
129      */
130     static void printLibraryVersion();
131 
132 private:
133 #ifdef WITH_OPENSSL
134     /// flag indicating the file format of certificates and private keys: PEM or ASN.1
135     /// @remark this member is only available if DCMTK is compiled with
136     /// OpenSSL support enabled.
137     DcmKeyFileFormat opt_keyFileFormat;
138 
139     /// flag indicating whether we will authenticate ourselves using a certificate and private key
140     /// @remark this member is only available if DCMTK is compiled with
141     /// OpenSSL support enabled.
142     OFBool opt_doAuthenticate;
143 
144     /// filename of private key file we use to authenticate ourselves
145     /// @remark this member is only available if DCMTK is compiled with
146     /// OpenSSL support enabled.
147     const char* opt_privateKeyFile;
148 
149     /// filename of certificate file we use to authenticate ourselves
150     /// @remark this member is only available if DCMTK is compiled with
151     /// OpenSSL support enabled.
152     const char* opt_certificateFile;
153 
154     /** password for reading the private key file, may be NULL.
155      *  In this case the password is read from STDIN.
156      *  @remark this member is only available if DCMTK is compiled with
157      *  OpenSSL support enabled.
158      */
159     const char* opt_passwd;
160 
161     /// DICOM TLS Security Profile selected
162     /// @remark this member is only available if DCMTK is compiled with
163     /// OpenSSL support enabled.
164     DcmTLSSecurityProfile opt_tlsProfile;
165 
166     /// filename of file containing at least 1K of entropy used to seed the PRNG
167     /// @remark this member is only available if DCMTK is compiled with
168     /// OpenSSL support enabled.
169     const char* opt_readSeedFile;
170 
171     /// filename to which the modified PRNG state is written back
172     /// @remark this member is only available if DCMTK is compiled with
173     /// OpenSSL support enabled.
174     const char* opt_writeSeedFile;
175 
176     /// indicates whether we should verify the remote peer's certificate
177     /// @remark this member is only available if DCMTK is compiled with
178     /// OpenSSL support enabled.
179     DcmCertificateVerification opt_certVerification;
180 
181     /// filename of Diffie-Hellman parameters file, may be NULL
182     /// @remark this member is only available if DCMTK is compiled with
183     /// OpenSSL support enabled.
184     const char* opt_dhparam;
185 
186     /// a flag indicating whether or not a secure connection was requested
187     /// @remark this member is only available if DCMTK is compiled with
188     /// OpenSSL support enabled.
189     OFBool opt_secureConnection;
190 
191     /// indicates whether we act as client, server or both
192     T_ASC_NetworkRole opt_networkRole;
193 
194     /// pointer to the secure transport layer managed by this object
195     /// @remark this member is only available if DCMTK is compiled with
196     /// OpenSSL support enabled.
197     DcmTLSTransportLayer *tLayer;
198 #endif // WITH_OPENSSL
199 };
200 
201 #endif // TLSOPT_H
202