00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file SSL_Asynch_Stream.h 00006 * 00007 * $Id: SSL_Asynch_Stream.h 84181 2009-01-16 22:37:49Z shuston $ 00008 * 00009 * @author Alexander Libman <alibman@baltimore.com> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_SSL_ASYNCH_STREAM_H 00014 #define ACE_SSL_ASYNCH_STREAM_H 00015 00016 #include /**/ "ace/pre.h" 00017 #include "SSL_Context.h" 00018 00019 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00020 #pragma once 00021 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00022 00023 #if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS))) 00024 00025 #include "SSL_Asynch_BIO.h" 00026 00027 #include "ace/Asynch_IO_Impl.h" 00028 #include "ace/Message_Block.h" 00029 #include "ace/Synch_Traits.h" 00030 #include "ace/Thread_Mutex.h" 00031 00032 /* 00033 * This facility doesn't follow the normal ACE asynch I/O support classes' 00034 * interface/implementation arrangement. It's not needed because rather than 00035 * branching off to platform-specific APIs, all platforms use the OpenSSL 00036 * API. Thus, you can think of this class as the implementation class (for 00037 * OpenSSL) and there's no separate interface class. 00038 * Also, since both read and write operations are defined in one I/O 00039 * factory, there's no single Result class defined as there is for 00040 * ACE_Asynch_Read_Stream, et al. There are separate result classes defined 00041 * for read and write operations. 00042 */ 00043 00044 #if defined (ACE_WIN32) 00045 # include "ace/WIN32_Asynch_IO.h" 00046 typedef ACE_WIN32_Asynch_Result A_RESULT; 00047 typedef ACE_WIN32_Asynch_Read_Stream_Result ARS_RESULT; 00048 typedef ACE_WIN32_Asynch_Write_Stream_Result AWS_RESULT; 00049 00050 # define ERR_CANCELED ERROR_OPERATION_ABORTED 00051 00052 #else 00053 # include "ace/POSIX_Asynch_IO.h" 00054 typedef ACE_POSIX_Asynch_Result A_RESULT; 00055 typedef ACE_POSIX_Asynch_Read_Stream_Result ARS_RESULT; 00056 typedef ACE_POSIX_Asynch_Write_Stream_Result AWS_RESULT; 00057 00058 # define ERR_CANCELED ECANCELED 00059 00060 #endif /* ACE_WIN32 */ 00061 00062 00063 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00064 00065 class ACE_SSL_Asynch_Stream; // Forward decl for use in result class def. 00066 00067 /** 00068 * @class ACE_SSL_Asynch_Read_Stream_Result 00069 * 00070 * Result class that communicates result of read operations initiated on 00071 * an ACE_SSL_Asynch_Stream object. 00072 */ 00073 class ACE_SSL_Asynch_Read_Stream_Result : public ARS_RESULT 00074 { 00075 /// Factory class will have special permissions. 00076 friend class ACE_SSL_Asynch_Stream; 00077 00078 protected: 00079 ACE_SSL_Asynch_Read_Stream_Result (ACE_Handler &handler, 00080 ACE_HANDLE handle, 00081 ACE_Message_Block &message_block, 00082 size_t bytes_to_read, 00083 const void* act, 00084 ACE_HANDLE event, 00085 int priority, 00086 int signal_number); 00087 }; 00088 00089 /** 00090 * @class ACE_SSL_Asynch_Write_Stream_Result 00091 * 00092 * Result class that communicates result of write operations initiated on 00093 * an ACE_SSL_Asynch_Stream object. 00094 */ 00095 class ACE_SSL_Asynch_Write_Stream_Result : public AWS_RESULT 00096 { 00097 /// Factory class will have special permissions. 00098 friend class ACE_SSL_Asynch_Stream; 00099 00100 protected: 00101 ACE_SSL_Asynch_Write_Stream_Result (ACE_Handler &handler, 00102 ACE_HANDLE handle, 00103 ACE_Message_Block &message_block, 00104 size_t bytes_to_read, 00105 const void* act, 00106 ACE_HANDLE event, 00107 int priority, 00108 int signal_number); 00109 }; 00110 00111 00112 /** 00113 * @class ACE_SSL_Asynch_Result 00114 * 00115 * Result class that is used internally for socket close notifications. 00116 */ 00117 class ACE_SSL_Asynch_Result : public A_RESULT 00118 { 00119 public: 00120 ACE_SSL_Asynch_Result (ACE_Handler &handler); 00121 00122 void complete (size_t bytes_transferred, 00123 int success, 00124 const void * completion_key, 00125 u_long error); 00126 }; 00127 00128 00129 // Only provide forward declarations to prevent possible abuse of the 00130 // friend declarations in ACE_SSL_Asynch_Stream. 00131 struct ACE_SSL_Asynch_Stream_Accessor; 00132 00133 /** 00134 * @class ACE_SSL_Asynch_Stream 00135 * 00136 * @brief This class is a factory for initiating asynchronous reads 00137 * and writes on an SSL stream. 00138 * 00139 * Once open() is called, multiple asynchronous read and write operations 00140 * can be started using this class. The handler object (derived from 00141 * ACE_Handler) specified in open() will receive completion events for the 00142 * operations initiated via this class. 00143 */ 00144 class ACE_SSL_Export ACE_SSL_Asynch_Stream 00145 : public ACE_Asynch_Operation, 00146 public ACE_Handler 00147 { 00148 public: 00149 00150 // Use a class/struct to work around scoping 00151 // problems for extern "C" free functions with some compilers. For 00152 // example, some can't handle 00153 // 00154 // friend ::some_extern_c_free_function (...) 00155 // 00156 // Note that we could use a straight C++ (i.e. not extern "C") free 00157 // function, but using a class or struct allows us to hide the 00158 // interface from the user, which prevents abuse of this friend 00159 // relationship. 00160 friend struct ACE_SSL_Asynch_Stream_Accessor; 00161 00162 enum Stream_Type 00163 { 00164 ST_CLIENT = 0x0001, 00165 ST_SERVER = 0x0002 00166 }; 00167 00168 /// Constructor. 00169 /** 00170 * @arg context Pointer to an ACE_SSL_Context instance containing 00171 * the OpenSSL information to be associated with this 00172 * ACE_SSL_Asynch_Stream. The needed SSL data will be 00173 * copied before return. Therefore, this object can be 00174 * reused, modified, or deleted upon return. If a 0 pointer 00175 * is passed, the ACE_SSL_Context::instance() method will 00176 * be called to get access to a singleton. 00177 */ 00178 ACE_SSL_Asynch_Stream (Stream_Type s_type = ST_SERVER, 00179 ACE_SSL_Context * context = 0); 00180 00181 /// Destructor 00182 virtual ~ACE_SSL_Asynch_Stream (void); 00183 00184 int cancel (void); 00185 00186 int close (void); 00187 00188 /// Return a pointer to the underlying SSL structure. 00189 SSL *ssl (void) const; 00190 00191 /** 00192 * Initializes the factory with information which will be used with 00193 * each asynchronous call. 00194 * 00195 * @arg handler The ACE_Handler that will be called to handle completions 00196 * for operations initiated using this factory. 00197 * @arg handle The handle that future read/write operations will use. 00198 * 00199 * @retval 0 for success. 00200 * @retval -1 for failure; consult @c errno for further information. 00201 */ 00202 int open (ACE_Handler &handler, 00203 ACE_HANDLE handle = ACE_INVALID_HANDLE, 00204 const void *completion_key = 0, 00205 ACE_Proactor *proactor = 0); 00206 00207 /** 00208 * Initiates an asynchronous read. If the operation is successfully 00209 * initiated, the handle_read_stream() method will be called on the 00210 * ACE_Handler object passed to open() when the operation completes. 00211 * Data is read into the specified ACE_Message_Block beginning at its 00212 * write pointer; the block's write pointer is updated to reflect any 00213 * added data when the operation completes. 00214 * 00215 * @arg message_block The specified ACE_Message_Block will receive any 00216 * data that is read. Data will be read into the 00217 * block beginning at the block's write pointer. 00218 * @arg num_bytes_to_read The maximum number of bytes to read. The actual 00219 * amount read may be less. 00220 * @arg act ACT which is passed to the completion handler in 00221 * the result object. 00222 * @arg priority Specifies the operation priority. This has an 00223 * affect on POSIX only. Works like @i nice in Unix. 00224 * Negative values are not allowed. 0 means priority 00225 * of the operation same as the process priority. 00226 * 1 means priority of the operation is one less than 00227 * process, and so forth. This parameter has no 00228 * affect on Win32. 00229 * @arg signal_number The POSIX4 real-time signal number to be used 00230 * for the operation. signal_number ranges from 00231 * ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is 00232 * unused on non-POSIX4 systems. 00233 * 00234 * @retval 0 for success. 00235 * @retval -1 for failure; consult @c errno for further information. 00236 */ 00237 int read (ACE_Message_Block &message_block, 00238 size_t num_bytes_to_read, 00239 const void *act = 0, 00240 int priority = 0, 00241 int signal_number = ACE_SIGRTMIN); 00242 00243 /** 00244 * Initiates an asynchronous write. If the operation is successfully 00245 * initiated, the handle_write_stream() method will be called on the 00246 * ACE_Handler object passed to open() when the operation completes. 00247 * Data is taken from the specified ACE_Message_Block beginning at its 00248 * read pointer; the block's read pointer is updated to reflect any 00249 * data successfully sent when the operation completes. 00250 * 00251 * @arg message_block The specified ACE_Message_Block is the source of 00252 * data that is written. Data will be taken from the 00253 * block beginning at the block's read pointer. 00254 * @arg bytes_to_write The maximum number of bytes to write. The actual 00255 * amount written may be less. 00256 * @arg act ACT which is passed to the completion handler in 00257 * the result object. 00258 * @arg priority Specifies the operation priority. This has an 00259 * affect on POSIX only. Works like @i nice in Unix. 00260 * Negative values are not allowed. 0 means priority 00261 * of the operation same as the process priority. 00262 * 1 means priority of the operation is one less than 00263 * process, and so forth. This parameter has no 00264 * affect on Win32. 00265 * @arg signal_number The POSIX4 real-time signal number to be used 00266 * for the operation. signal_number ranges from 00267 * ACE_SIGRTMIN to ACE_SIGRTMAX. This argument is 00268 * unused on non-POSIX4 systems. 00269 * 00270 * @retval 0 for success. 00271 * @retval -1 for failure; consult @c errno for further information. 00272 */ 00273 int write (ACE_Message_Block &message_block, 00274 size_t bytes_to_write, 00275 const void *act = 0, 00276 int priority = 0, 00277 int signal_number = ACE_SIGRTMIN); 00278 00279 protected: 00280 /// Virtual from ACE_Asynch_Operation. Since this class is essentially an 00281 /// implementation class, simply return 0. 00282 virtual ACE_Asynch_Operation_Impl *implementation (void) const { return 0; } 00283 00284 /// virtual from ACE_Handler 00285 00286 /// This method is called when BIO write request is completed. It 00287 /// processes the IO completion and calls do_SSL_state_machine(). 00288 virtual void handle_write_stream 00289 (const ACE_Asynch_Write_Stream::Result &result); 00290 00291 /// This method is called when BIO read request is completed. It 00292 /// processes the IO completion and calls do_SSL_state_machine(). 00293 virtual void handle_read_stream 00294 (const ACE_Asynch_Read_Stream::Result &result); 00295 00296 /// This method is called when all SSL sessions are closed and no 00297 /// more pending AIOs exist. It also calls users handle_wakeup(). 00298 virtual void handle_wakeup (void); 00299 00300 /** 00301 * This method will be called after a successful SSL handshake indicating 00302 * that the peer's certificate chain (if any) has been verified and the key 00303 * exchange has completed. When a peer certificate is required, this 00304 * method must be used to perform additional checks beyond the verification 00305 * performed by OpenSSL. 00306 * 00307 * Check 1: 00308 * 00309 * SSL clients that require a peer certificate must specify SSL_VERIFY_PEER 00310 * via ACE_SSL_Context::default_verify_mode. If the peer sends an invalid 00311 * certificate, the SSL handshake will fail; however, if the peer does not 00312 * send a certificate, the SSL handshake will complete successfully which 00313 * may not be acceptable. In this case, you must override this method in a 00314 * subclass and return false if the call to SSL_get_peer_certificate returns 00315 * null. 00316 * 00317 * Check 2: 00318 * 00319 * An additional post handshake check that you should perform is to verify 00320 * the certificate's FQDN against the host address you intended to connect 00321 * to. This check will prevent an attacker from using a certificate signed 00322 * by your CA to usurp your session. For further info on this check, see 00323 * the post_connection_check method in Example 5-8 of 'Network Security with 00324 * OpenSSL' by Viega, et. al. 00325 * 00326 * Return: 00327 * 00328 * false - Terminate the connection. Outstanding IO complete with ERR_CANCELED. 00329 * 00330 * true - Proceed with connection. The default implementation returns true. 00331 */ 00332 virtual bool post_handshake_check (void); 00333 00334 /** 00335 * @name SSL State Machine 00336 */ 00337 //@{ 00338 int do_SSL_state_machine (void); 00339 int do_SSL_handshake (void); 00340 int do_SSL_read (void); 00341 int do_SSL_write(void); 00342 int do_SSL_shutdown(void); 00343 //@} 00344 00345 void print_error (int err_ssl, 00346 const ACE_TCHAR *pText); 00347 00348 int pending_BIO_count (void); 00349 00350 /// This method is called to notify user handler when user's read in 00351 /// done. 00352 int notify_read (int bytes_transferred, int error); 00353 00354 /// This method is called to notify user handler when user's write 00355 /// in done. 00356 int notify_write (int bytes_transferred, int error); 00357 00358 /// This method is called to notify ourself that SSL session is 00359 /// shutdown and that there is no more I/O activity now and in the 00360 /// future. 00361 int notify_close(void); 00362 00363 /** 00364 * @name BIO Helpers 00365 */ 00366 //@{ 00367 int ssl_bio_read (char * buf, size_t len, int & errval); 00368 int ssl_bio_write (const char * buf, size_t len, int & errval); 00369 //@} 00370 00371 private: 00372 00373 // Preventing copying through construction or assignment. 00374 ACE_SSL_Asynch_Stream (ACE_SSL_Asynch_Stream const &); 00375 ACE_SSL_Asynch_Stream & operator= (ACE_SSL_Asynch_Stream const &); 00376 00377 protected: 00378 00379 /// Stream Type ST_CLIENT/ST_SERVER 00380 Stream_Type type_; 00381 00382 /// The proactor 00383 ACE_Proactor * proactor_; 00384 00385 /// External,i.e user handler 00386 ACE_Handler * ext_handler_; 00387 00388 /// External, i.e. read result faked for user 00389 ACE_SSL_Asynch_Read_Stream_Result * ext_read_result_ ; 00390 00391 /// External, i.e. write result faked for user 00392 ACE_SSL_Asynch_Write_Stream_Result * ext_write_result_ ; 00393 00394 /// Stream state/flags 00395 enum Stream_Flag 00396 { 00397 /// istream_ open OK 00398 SF_STREAM_OPEN = 0x0001, 00399 /// request to SSL shutdown 00400 SF_REQ_SHUTDOWN = 0x0002, 00401 /// SSL shutdown finished 00402 SF_SHUTDOWN_DONE = 0x0004, 00403 /// Close notification sent 00404 SF_CLOSE_NTF_SENT = 0x0008, 00405 /// Stream can be safely destroyed 00406 SF_DELETE_ENABLE = 0x0010 00407 }; 00408 00409 int flags_; 00410 00411 /// The SSL session. 00412 SSL * ssl_; 00413 00414 /// Flag ensures that post_connection_check() is called at most one time. 00415 bool handshake_complete_; 00416 00417 /// The BIO implementation 00418 BIO * bio_; 00419 00420 /// The real streams which work under the ssl connection. 00421 /// BIO performs I/O via this streams 00422 enum BIO_Flag // internal IO flags 00423 { 00424 /// End of stream 00425 BF_EOS = 0x01, 00426 /// Real AIO in progress 00427 BF_AIO = 0x02 00428 }; 00429 00430 /** 00431 * @name Internal stream, buffer and info for BIO read 00432 */ 00433 //@{ 00434 ACE_Asynch_Read_Stream bio_istream_; 00435 ACE_Message_Block bio_inp_msg_; 00436 int bio_inp_errno_; 00437 int bio_inp_flag_; 00438 //@} 00439 00440 /** 00441 * @name Internal stream, buffer and info for BIO write 00442 */ 00443 //@{ 00444 ACE_Asynch_Write_Stream bio_ostream_; 00445 ACE_Message_Block bio_out_msg_; 00446 int bio_out_errno_; 00447 int bio_out_flag_; 00448 //@} 00449 00450 /// Mutex to protect work 00451 ACE_SYNCH_MUTEX mutex_; 00452 00453 }; 00454 00455 ACE_END_VERSIONED_NAMESPACE_DECL 00456 00457 #if defined(__ACE_INLINE__) 00458 #include "SSL_Asynch_Stream.inl" 00459 #endif /* __ACE_INLINE__ */ 00460 00461 #endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 || 00462 ACE_HAS_AIO_CALLS) */ 00463 00464 #include /**/ "ace/post.h" 00465 00466 #endif /* ACE_SSL_ASYNCH_STREAM_H */