summaryrefslogtreecommitdiff
path: root/ace/SSL/SSL_Context.h
blob: 6188f17e84000da980637e8bf62d4f22ae01ad47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
// -*- C++ -*-

//=============================================================================
/**
 *  @file    SSL_Context.h
 *
 *  $Id$
 *
 *  @author Carlos O'Ryan <coryan@ece.uci.edu>
 */
//=============================================================================


#ifndef ACE_SSL_CONTEXT_H
#define ACE_SSL_CONTEXT_H

#include "ace/pre.h"

#include "SSL_Export.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "ace/SString.h"
#include "ace/Synch.h"

#include <openssl/ssl.h>

#ifdef ACE_HAS_THREADS
extern "C"
{

  /// Mutex locking/unlocking callback for OpenSSL multithread
  /// support.
  void ACE_SSL_locking_callback (int mode,
                                 int type,
                                 const char * file,
                                 int line);

  /// Return the current thread ID.  OpenSSL uses this on platforms
  /// that need it.
  unsigned long ACE_SSL_thread_id (void);
}
#endif  /* ACE_HAS_THREADS */


class ACE_SSL_Export ACE_SSL_Data_File
{
public:

  /// Default constructor
  ACE_SSL_Data_File (void);

  /// Contructor from a file name and the file type.
  ACE_SSL_Data_File (const char *file_name,
                     int type = SSL_FILETYPE_PEM);

  /// The file name
  const char *file_name (void) const;

  /// The type
  int type (void) const;

private:

  /// The file name
  ACE_CString file_name_;

  /// The type, used by the SSL library to parse the file contents.
  int type_;
};

// ****************************************************************


/**
 * @class ACE_SSL_Context
 *
 * @brief A wrapper for the OpenSSL SSL_CTX related functions.
 *
 * This class provides a wrapper for the SSL_CTX data structure.
 * Since most applications have a single SSL_CTX structure, this class
 * can be used as a singleton.
 */
class ACE_SSL_Export ACE_SSL_Context
{
  friend void ACE_SSL_locking_callback (int, int, const char *, int);

public:

  enum {
    INVALID_METHOD = -1,
    SSLv2_client = 1,
    SSLv2_server,
    SSLv2,
    SSLv3_client,
    SSLv3_server,
    SSLv3,
    SSLv23_client,
    SSLv23_server,
    SSLv23,
    TLSv1_client,
    TLSv1_server,
    TLSv1
  };

  /// Constructor
  ACE_SSL_Context (void);

  /// Destructor
  ~ACE_SSL_Context (void);

  /// The Singleton context, the SSL components use the singleton if
  /// nothing else is available.
  static ACE_SSL_Context *instance (void);

  /**
   * Set the CTX mode.  The mode can be set only once, afterwards the
   * function has no effect and returns -1.
   * Once the mode is set the underlying SSL_CTX is initialized and
   * the class can be used.
   * If the mode is not set, then the class automatically initializes
   * itself to the default mode.
   */
  int set_mode (int mode = ACE_SSL_Context::SSLv23);

  int get_mode (void) const;

  /// Get the SSL context
  SSL_CTX *context (void);

  /// Get the file name and file format used for the private key
  int private_key_type (void) const;
  const char *private_key_file_name (void) const;

  /// Set the private key file.
  /**
   * @note This method should only be called after a certificate has
   *       been set since key verification is performed against the
   *       certificate, among other things.
   */
  int private_key (const char *file_name,
                   int type = SSL_FILETYPE_PEM);

  /// Verify that the private key is valid.
  /**
   * @note This method should only be called after a certificate has
   *       been set since key verification is performed against the
   *       certificate, among other things.
   */
  int verify_private_key (void);

  /// Get the file name and file format used for the certificate file
  int certificate_type (void) const;
  const char *certificate_file_name (void) const;

  /// Set the certificate file.
  int certificate (const char *file_name,
                   int type = SSL_FILETYPE_PEM);


  /**
   *  Load the location of the trusted certification authority
   *  certificates.  Note that CA certificates are stored in PEM format
   *  as a sequence of certificates in <ca_file> or as a set of
   *  individual certificates in <ca_dir> (or both).
   *
   *  Note this method is called by set_mode() to load the default
   *  environment settings for <ca_file> and <ca_dir>, if any. This
   *  allows for automatic service configuration (and backward
   *  compatibility with previous versions.
   *
   *  Note that the underlying SSL function will add valid file and
   *  directory names to the load location lists maintained as part of
   *  the SSL_CTX table.  (... It therefore dosn't make sense to keep a
   *  copy of the file and path name of the most recently added
   *  <ca_file> or <ca_path>.
   *
   *  @return 0 for success or -1 on error.
   *
   *  @see OpenSSL manual SSL_CTX_load_verify_locations(3) for a
   *  detailed description of the CA file and directory requirements
   *  and processing.
  */
  int load_trusted_ca(const char* ca_file = 0, const char* ca_dir = 0);

  /**
     Test whether any CA locations have been successfully loaded and
     return the number of successful attempts.

     @return  >0 This value indicates the number of successful CA load
                 attempts .
     @return  0  If all CA load attempts have failed.
  */
  int have_trusted_ca(void) const;


  /**
   *  @todo Complete this documentation where elipses(...) are used
   *
   *  @doc Use this method when certificate chain verification is
   *  required.  The default server behaviour is SSL_VERIFY_NONE
   *  i.e. client certicates are requested for verified. This method
   *  can be used to configure server to request client certificates
   *  and perform the certificate verification. If <strict> is set
   *  true the client connection is rejected when certificate
   *  verification fails.  Otherwise the session is accepted with a
   *  warning, which is the default behaviour.  If <once> is set true
   *  (default), certificates are requested only once per session.
   *  The last parameter <depth> can be used to set the verification
   *  depth.
   *
   *  Note for verification to work correctly there should be a valid
   *  CA name list set using load_trusted_ca().
   *
   *  @see OpenSSL documentation of SSL_CTX_set_verify(3) for details of
   *  the verification process.
   *
   *  @see OpenSSL documentation ... set_verify_depth(3) ...
   *
   *  Note that this method overrides the use of the
   *  default_verify_mode() method.
   */
  void set_verify_peer (int strict = 0,
                        int once = 1,
                        int depth = 0);


  /// TODO: a implementation that will lookup the CTX table for the list
  /// of files and paths etc.
  /// Query the location of trusted certification authority
  /// certificates.
  // const char* ca_file_name(void) const;
  // const char* ca_dir_name(void) const;



  /**
   * Set and query the default verify mode for this context, it is
   * inherited by all the ACE_SSL objects created using the context.
   * It can be overriden on a per-ACE_SSL object.
   */
  void default_verify_mode (int mode);
  int default_verify_mode (void) const;

  /**
   * @name OpenSSL Random Number Generator Seed Related Methods
   *
   * These are methods that can be used to seed OpenSSL's
   * pseudo-random number generator.  These methods can be called more
   * than once.
   */
  //@{
  /// Seed the underlying random number generator.  This value should
  /// have at least 128 bits of entropy.
  int random_seed (const char * seed);

  /// Set the Entropy Gathering Daemon (EGD) UNIX domain socket file to
  /// read random seed values from.
  int egd_file (const char * socket_file);

  /**
   * Set the file that contains the random seed value state, and the
   * amount of bytes to read.  "-1" bytes causes the entire file to be
   * read.
   */
  int seed_file (const char * seed_file, long bytes = -1);
  //@}

  /// Print SSL error corresponding to the given error code.
  static void report_error (unsigned long error_code);

  /// Print the last SSL error for the current thread.
  static void report_error (void);

  /**
   * @name Diffie-Hellman (DH) Parameters
   *
   * When using DSS-based certificates, Diffie-Hellman keys need to be
   * exchanged.  These must be provided in the form of DH key
   * generation parameters loaded in, or as fixed keys hardcoded into
   * the code itself.  ACE_SSL supports loaded parameters.
   *
   */
  //@{
  /**
   * Load Diffie-Hellman parameters from file_name.  The specified file can be
   * a standalone file containing only DH parameters (e.g., as created
   * by <code>openssl dhparam</code>), or it can be a certificate which has
   * a PEM-encoded set of DH params concatenated on to i.
   */
  int dh_params (const char *file_name, int type = SSL_FILETYPE_PEM);
  const char *dh_params_file_name () const;
  int dh_params_file_type () const;
  //@}

private:

  /// Verify if the context has been initialized or not.
  void check_context (void);

  /// @@ More to document
  void ssl_library_init ();
  void ssl_library_fini ();

  // = Prevent assignment and initialization.
  //@{
  ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_SSL_Context &))
  ACE_UNIMPLEMENTED_FUNC (ACE_SSL_Context (const ACE_SSL_Context &))
  //@}

private:
  // @@ Carlos, I protected this variable with an ACE_GUARD, just like
  //    what we do for the orb_init_count_ variable in
  //    tao/ORB.cpp.   The code isn't pretty but it should suffice
  //    until the SSL context is stored in a Singleton.
  //       -Ossama

  /// The SSL_CTX structure
  SSL_CTX *context_;

  /// Cache the mode so we can answer fast
  int mode_;

  /// The private key, certificate, and Diffie-Hellman paramters files
  ACE_SSL_Data_File private_key_;
  ACE_SSL_Data_File certificate_;
  ACE_SSL_Data_File dh_params_;

  /// The default verify mode.
  int default_verify_mode_;

  /// count of successful CA load attempts
  int have_ca_;

  /// Reference count of the number of times the ACE_SSL_Context was
  /// initialized.
  static int library_init_count_;

  // @@ This should also be done with a singleton, otherwise it is not
  //    thread safe and/or portable to some weird platforms...

#ifdef ACE_HAS_THREADS
  /// Array of mutexes used internally by OpenSSL when the SSL
  /// application is multithreaded.
  static ACE_mutex_t * lock_;

  // @@ This should also be managed by a singleton.
#endif

};

#if defined(__ACE_INLINE__)
#include "SSL_Context.inl"
#endif /* __ACE_INLINE__ */

#include "ace/post.h"

#endif  /* ACE_SSL_CONTEXT_H */