Bond's TCP Library  1.0
Bond's TCP Client/Server Library
tcp::SSL Class Reference

Encapsulates an SSL connection data structure. More...

#include <tcpssl.h>

Collaboration diagram for tcp::SSL:

Public Member Functions

 SSL (DataSocket &owner, SSLContext &context)
 Constructor. More...
 
virtual ~SSL ()
 Destructor.
 
void setOptions (bool verifypeer=false)
 Sets default options for all SSL objects created from this context. More...
 
bool setCertificateAndKey (const char *certfile, const char *keyfile)
 Sets the certificate filename and key filename. More...
 
void setPrivateKeyPassword (string value)
 Sets the value of the private key password.
 
virtual int passwordCallback (char *buf, int size, int rwflag)
 Called when a password to decrypt a private key is required. More...
 
bool setfd (int socket)
 Sets the socket file descripter for this SSL object. More...
 
string & getSubjectName ()
 Returns the peer certificate subject name or an empty string if none was sent.
 
bool verifyResult ()
 Return true if the peer certificate was verified or if no certificate was presented.
 
bool connect ()
 Starts the SSL client handshake sequence.
 
bool accept ()
 Starts the SSL server handshake sequence.
 
size_t read (void *buffer, size_t size)
 Reads and decrypts SSL socket data. More...
 
size_t write (const void *buffer, size_t size)
 Encrypts and writes SSL socket data. More...
 
void clear ()
 Resets the SSL object for another connection. More...
 
void shutdown ()
 Closes the SSL connection gracefully.
 
void setHostname (const string value)
 A client/server may store the internal hostname property for certificate post validation.
 

Public Attributes

bool requiresCertPostValidation { false }
 If True, the certificate will be checked for validity on the first read/write operation.
 

Protected Member Functions

bool performCertPostValidation ()
 Performs a post handshake validation of the peer certificate. More...
 
virtual bool validateSubjectName (const string &subjectName, const string &hostName)
 Validate the peer certificate subject name. More...
 

Protected Attributes

DataSocketowner_
 A reference to the socket

 
SSLMode mode_
 Either SERVER or CLIENT

 
::SSLssl_
 The openSSL handle for API calls.
 

Friends

class SSLContext
 

Detailed Description

Encapsulates an SSL connection data structure.

Definition at line 109 of file tcpssl.h.

Constructor & Destructor Documentation

◆ SSL()

tcp::SSL::SSL ( DataSocket owner,
SSLContext context 
)

Constructor.

Parameters
owner[in] The tcp::Session or tcp::Client this SSL object is for
context[in] The context object used as defaults for this SSL connection

Definition at line 396 of file tcpssl.cpp.

396  : owner_(owner)
397 {
398  mode_ = context.mode_;
399  ssl_ = SSL_new(context.ctx_);
400 }

Member Function Documentation

◆ clear()

void tcp::SSL::clear ( )

Resets the SSL object for another connection.

This method could be used by a client reconnecting to the same server

Definition at line 632 of file tcpssl.cpp.

633 {
634  int res = SSL_clear(ssl_);
635  if ( res != 1) {
636  unsigned long ssl_err = ERR_get_error();
637  print_error_string(ssl_err,"SSL_clear");
638  }
639 }

◆ passwordCallback()

int tcp::SSL::passwordCallback ( char *  buf,
int  size,
int  rwflag 
)
virtual

Called when a password to decrypt a private key is required.

Descendant classes may want to override this to provide a more secure means of storing the private key password. The default behavior is to return the value of keypass_.

Remarks
See the openSSL function SSL_CTX_set_default_passwd_cb for more details
This must be public because it is called from the passwordCallback() function
This password callback function only applies to private keys assigned to this SSL_CTX object, it is not 'inherited' from any SSL objects created from it.

Definition at line 460 of file tcpssl.cpp.

461 {
462  (void)rwflag;
463  if (!keypass_.empty()) {
464  int lsize = max<int>(size,keypass_.length());
465  strncpy(buf,keypass_.c_str(),lsize);
466  return lsize;
467  } else {
468  return 0;
469  }
470 }

◆ performCertPostValidation()

bool tcp::SSL::performCertPostValidation ( )
protected

Performs a post handshake validation of the peer certificate.

The post validation is performed on the first read or write operation If the post validation fails the session is disconnected. This check is only performed if requiresCertPostValidation is true

Definition at line 533 of file tcpssl.cpp.

534 {
535  if (!verifyResult()) {
536  cerr << "Peer certificate validation failed" << endl;
537  return false;
538  } else {
539 
540  if (!getSubjectName().empty()) {
542  if (!validateSubjectName(subjectName_,hostname_)) {
543  cerr << "Peer certificate subject name '" << subjectName_ << "' does not match host name '" << hostname_ << "'" << endl;
544  return false;
545  }
546  }
547 
548  }
549 
550  return true;
551 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read()

size_t tcp::SSL::read ( void *  buffer,
size_t  size 
)

Reads and decrypts SSL socket data.

Parameters
buffer[in] Where to place the read data
size[in] The size of buffer
Returns
The number of bytes actually read
Remarks
Logs error messages to cerr

Definition at line 594 of file tcpssl.cpp.

595 {
598 
599  int res = SSL_read(ssl_,buffer,size);
600  if (res <= 0) {
601  unsigned long ssl_err = SSL_get_error(ssl_,res);
602  switch (ssl_err) {
603  case SSL_ERROR_NONE: return 0;
604  case SSL_ERROR_WANT_READ: return 0; break;
605  case SSL_ERROR_WANT_WRITE: wantsWrite(); return read(buffer,size); break;
606  default: print_error_string(ssl_err,"SSL_read"); return 0;
607  }
608  } else {
609  return res;
610  }
611 }
Here is the call graph for this function:

◆ setCertificateAndKey()

bool tcp::SSL::setCertificateAndKey ( const char *  certfile,
const char *  keyfile 
)

Sets the certificate filename and key filename.

Sets the certificate and key file for the SSL connection To set this property for all client or server connections, see the corresponding method in the SSLContext class

Parameters
certfile[in] The filename of a certificate chain in PEM (or CRT) format
keyfile[in] The filename of a private key in PEM (or CRT) format
Returns
True of the certificate and key were successfully set, false otherwise. Check cerr log for details.
Remarks
If the keyfile requires a password to decrypt, passwordCallback will be called to provide that password.

Definition at line 418 of file tcpssl.cpp.

419 {
420  long res = 1;
421  unsigned long ssl_err = 0;
422 
423  if ((certfile && !keyfile) || (!certfile && keyfile)) {
424  cerr << "Error: Both a certificate and a private key file are required" << endl;
425  return false;
426  }
427 
428  if (certfile && keyfile) {
429  res = SSL_use_certificate_file(ssl_, certfile, SSL_FILETYPE_PEM);
430  ssl_err = ERR_get_error();
431  if ( res != 1) {
432  print_error_string(ssl_err,"SSL_use_certificate_file");
433  return false;
434  }
435 
436  res = SSL_use_PrivateKey_file(ssl_, keyfile, SSL_FILETYPE_PEM);
437  ssl_err = ERR_get_error();
438  if (res != 1) {
439  print_error_string(ssl_err,"SSL_use_PrivateKey_file");
440  return false;
441  }
442 
443  /* Make sure the key and certificate file match. */
444  res = SSL_check_private_key(ssl_);
445  ssl_err = ERR_get_error();
446  if ( res != 1) {
447  print_error_string(ssl_err,"SSL_CTX_check_private_key");
448  return false;
449  }
450 
451  SSL_set_default_passwd_cb(ssl_,&ssl_password_callback);
452  SSL_set_default_passwd_cb_userdata(ssl_,this);
453 
454  return true;
455  } else {
456  return false;
457  }
458 }

◆ setfd()

bool tcp::SSL::setfd ( int  socket)

Sets the socket file descripter for this SSL object.

An application must set the file descriptor for the socket prior to calling accept() or connect()

Parameters
socket[in] The linux socket handle

Definition at line 472 of file tcpssl.cpp.

473 {
474  if (socket == 0) {
475  cerr << "SSL::setfd: socket is NULL" << endl;
476  return false;
477  } else {
478  int res = SSL_set_fd(ssl_,socket);
479  if (res != 1) {
480  unsigned long ssl_err = ERR_get_error();
481  print_error_string(ssl_err,"SSL::set_fd");
482  return false;
483  } else {
484  return true;
485  }
486  }
487 }

◆ setOptions()

void tcp::SSL::setOptions ( bool  verifypeer = false)

Sets default options for all SSL objects created from this context.

Additional options can be set in the SSLContext object associated with this SSL object

Parameters
verifypeer[in] If true, the server/client will validate the peer certificate
Remarks
Logs error information to cerr but does not return error information.

Definition at line 407 of file tcpssl.cpp.

408 {
409  if (verifypeer) {
410  SSL_set_verify(ssl_, SSL_VERIFY_PEER, verify_callback);
411  } else {
412  SSL_set_verify(ssl_, SSL_VERIFY_NONE, NULL);
413  }
414 
415  printSSLErrors();
416 }
Here is the call graph for this function:

◆ validateSubjectName()

bool tcp::SSL::validateSubjectName ( const string &  subjectName,
const string &  hostName 
)
protectedvirtual

Validate the peer certificate subject name.

This function should return true if the subject name is considered valid. It is intended to verify that the hostname matches the certificate subjectname. The default implementation uses whte wildcmp function to perform a wildcard compare. Only called if checkPeerSubjectName is true.

Definition at line 528 of file tcpssl.cpp.

529 {
530  return wildcmp(subjectName.c_str(),hostname.c_str());
531 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ write()

size_t tcp::SSL::write ( const void *  buffer,
size_t  size 
)

Encrypts and writes SSL socket data.

Parameters
buffer[in] Where to place the read data
size[in] The size of buffer
Returns
The number of bytes actually read
Remarks
Logs error messages to cerr

Definition at line 613 of file tcpssl.cpp.

614 {
617 
618  int res = SSL_write(ssl_,buffer,size);
619  if (res <= 0) {
620  unsigned long ssl_err = SSL_get_error(ssl_,res);
621  switch (ssl_err) {
622  case SSL_ERROR_NONE: return 0;
623  case SSL_ERROR_WANT_READ: wantsRead(); return write(buffer,size); break;
624  case SSL_ERROR_WANT_WRITE: return write(buffer,size); break;
625  default: print_error_string(ssl_err,"SSL_write"); return 0; break;
626  }
627  } else {
628  return res;
629  }
630 }
Here is the call graph for this function:

The documentation for this class was generated from the following files:
tcp::printSSLErrors
void printSSLErrors()
This method logs openSSL errors to cerr.
Definition: tcpssl.cpp:56
tcp::verify_callback
int verify_callback(int preverify, X509_STORE_CTX *x509_ctx)
Prints the certificate details to clog.
Definition: tcpssl.cpp:195
tcp::SSL::write
size_t write(const void *buffer, size_t size)
Encrypts and writes SSL socket data.
Definition: tcpssl.cpp:613
tcp::SSL::performCertPostValidation
bool performCertPostValidation()
Performs a post handshake validation of the peer certificate.
Definition: tcpssl.cpp:533
tcp::SSL::requiresCertPostValidation
bool requiresCertPostValidation
If True, the certificate will be checked for validity on the first read/write operation.
Definition: tcpssl.h:195
tcp::SSL::validateSubjectName
virtual bool validateSubjectName(const string &subjectName, const string &hostName)
Validate the peer certificate subject name.
Definition: tcpssl.cpp:528
tcp::DataSocket::disconnected
void disconnected() override
Called when a connection is disconnected.
Definition: tcpsocket.cpp:202
tcp::SSL::read
size_t read(void *buffer, size_t size)
Reads and decrypts SSL socket data.
Definition: tcpssl.cpp:594
tcp::SSL::ssl_
::SSL * ssl_
The openSSL handle for API calls.
Definition: tcpssl.h:218
tcp::wildcmp
int wildcmp(const char *wild, const char *string)
Wildcard compare function.
Definition: tcpssl.cpp:62
tcp::SSL::getSubjectName
string & getSubjectName()
Returns the peer certificate subject name or an empty string if none was sent.
Definition: tcpssl.cpp:489
tcp::SSL::owner_
DataSocket & owner_
A reference to the socket
Definition: tcpssl.h:216
tcp::SSL::mode_
SSLMode mode_
Either SERVER or CLIENT
Definition: tcpssl.h:217
tcp::SSL::verifyResult
bool verifyResult()
Return true if the peer certificate was verified or if no certificate was presented.
Definition: tcpssl.cpp:553