Exemple #1
0
/* Return value:
 * SSL_OK: the SSL connection is accepted
 * SSL_ERROR: failed, call ossSSLGetError() & ossSSLGetErrorMessage() for reason
 */
INT32 ossSSLAccept(SSLHandle* handle)
{
   INT32 status;
   INT32 ret = SDB_OK;

   SSL_ASSERT(NULL != handle);
   SSL_ASSERT(NULL != handle->ssl);

   do
   {
      status = SSL_accept(handle->ssl);
      ret = _ossSSLCheckStatus(handle, status);
   } while (SSL_AGAIN == ret);

   return ret;
}
Exemple #2
0
/* Return value:
 * SSL_OK: the SSL connection is accepted
 * SSL_ERROR: failed, call ossSSLGetError() & ossSSLGetErrorMessage() for reason
 */
INT32 ossSSLShutdown(SSLHandle* handle)
{
   INT32 status;
   INT32 ret = SSL_OK;

   SSL_ASSERT(NULL != handle);
   SSL_ASSERT(NULL != handle->ssl);

   do
   {
      status = SSL_shutdown(handle->ssl);
      ret = _ossSSLCheckStatus(handle, status);
   } while (SSL_AGAIN == ret);

   return ret;
}
Exemple #3
0
/* Return value:
 * >0: the number of bytes actually write to SSL connection
 * SSL_AGAIN: need to write again
 * SSL_ERROR: failed, call ossSSLGetError() & ossSSLGetErrorMessage() for reason
 * SSL_TIMEOUT: only in windows
 */
INT32 ossSSLWrite(SSLHandle* handle, const void* buf, INT32 num)
{
   INT32 status;
   INT32 ret = SSL_OK;

   SSL_ASSERT(NULL != handle);
   SSL_ASSERT(NULL != handle->ssl);
   SSL_ASSERT(NULL != buf);

   status = SSL_write(handle->ssl, buf, num);
   ret = _ossSSLCheckStatus(handle, status);

   if (SSL_OK != ret)
   {
      status = ret;
   }

   return status;
}
Exemple #4
0
void ossSSLFreeContext(SSLContext** context)
{
   SSL_ASSERT(NULL != context);

   if (NULL != *context)
   {
      SSL_CTX_free(*context);
      *context = NULL;
   }
}
Exemple #5
0
void ossSSLFreeHandle(SSLHandle** handle)
{
   SSL_ASSERT(NULL != handle);

   if (NULL != *handle)
   {
      SSLHandle* h = *handle;

      /* h->bufferBIO will be freed by SSL_free() */
      if (NULL != h->ssl)
      {
         SSL_free(h->ssl);
      }
      OPENSSL_free(h);
      *handle = NULL;
   }
}
Exemple #6
0
static INT32 _ossSSLCheckStatus(SSLHandle* handle, INT32 status)
{
   INT32 err;
   INT32 ret = SDB_OK;

   SSL_ASSERT(NULL != handle);

   err = SSL_get_error(handle->ssl, status);
   handle->error = err;
   switch(err)
   {
   case SSL_ERROR_WANT_WRITE:
   case SSL_ERROR_WANT_READ:
      ret = SSL_AGAIN;
      /* pass through */
   case SSL_ERROR_NONE:
      if (NULL != handle->bufferBIO)
      {
         if (!BIO_flush(handle->bufferBIO))
         {
            handle->error = SSL_ERROR_SYSCALL;
            ret = SSL_ERROR;
         }
      }
      break;
   default:
#ifdef _WINDOWS
      {
         /* OPENSSL considers WSAETIMEDOUT as an error */
         INT32 lastError = WSAGetLastError();
         if (WSAETIMEDOUT == lastError)
         {
            ret = SSL_TIMEOUT;
         }
      }
#else
      ret = SSL_ERROR;
#endif
   }

   return ret;
}
Exemple #7
0
void drown_new(drown_ctx * dctx)
{
    dctx->ctx = BN_CTX_new();
    SSL_ASSERT(dctx->ctx != NULL);

    dctx->n = BN_new();
    SSL_ASSERT(dctx->n != NULL);

    dctx->e = BN_new();
    SSL_ASSERT(dctx->e != NULL);

    dctx->c = BN_new();
    SSL_ASSERT(dctx->c != NULL);

    dctx->s = BN_new();
    SSL_ASSERT(dctx->s != NULL);

    dctx->mt = BN_new();
    SSL_ASSERT(dctx->mt != NULL);
}
Exemple #8
0
INT32 ossSSLGetError(SSLHandle* handle)
{
   SSL_ASSERT(NULL != handle);

   return handle->error;
}
Exemple #9
0
/* Return value:
 * SSL_OK: the SSL handle is created
 * SSL_ERROR: failed, call ossSSLERRGetError() & ossSSLERRGetErrorMessage() for reason
 */
INT32 ossSSLNewHandle(SSLHandle** handle, SSLContext* ctx, SOCKET sock,
                             const char* initialBytes, INT32 len)
{
   SSLHandle* h = NULL;
   SSL* ssl = NULL;
   BIO* bufferBIO = NULL;
   BIO* socketBIO = NULL;
   INT32 ret = SSL_OK;

   SSL_ASSERT(NULL != handle);
   SSL_ASSERT(NULL != ctx);
   SSL_ASSERT(len >= 0);

   h = (SSLHandle*)OPENSSL_malloc(sizeof(SSLHandle));
   if (NULL == h)
   {
      goto error;
   }
   _SSLHandleInit(h);
   h->sock = sock;

   ssl = SSL_new(ctx);
   if (NULL == ssl)
   {
      goto error;
   }
   h->ssl = ssl;

   if (0 == len)
   {
      /* there is no initial bytes, so we just set the socket to SSL */
      ret = SSL_set_fd(ssl, sock);
      if (!ret)
      {
         goto error;
      }
   }
   else /* len > 0 */
   {
      SSL_ASSERT(NULL != initialBytes);

      /*
       * There are initial SSL bytes, so we should give these bytes to SSL by some way.
       * Here we create a buffer BIO, and put these bytes to it.
       * Then we create a socket BIO, and set a BIO chain to link 
       * the buffer and socket by BIO_push().
       * Finally, we set the buffer to SSL instead of the socket.
       *
       * NOTE: when do SSL operations, it should explicitly flush the buffer.
       */

      bufferBIO = BIO_new(BIO_f_buffer());
      if (NULL == bufferBIO)
      {
         goto error;
      }

      ret = BIO_set_buffer_read_data(bufferBIO, (void*)initialBytes, len);
      if (!ret)
      {
         goto error;
      }

      socketBIO = BIO_new_socket(sock, BIO_NOCLOSE);
      if (NULL == socketBIO)
      {
         goto error;
      }

      /* link socket to the buffer */
      if (NULL == BIO_push(bufferBIO, socketBIO))
      {
         goto error;
      }

      /* SSL_free() will also free bufferBIO,
       * so it's no need to free bufferBIO later when free the SSL handle.
       */
      SSL_set_bio(ssl, bufferBIO, bufferBIO);

      /* hold the bufferBIO pointer so we can flush it when do SSL operations */
      h->bufferBIO = bufferBIO;
   }

   *handle = h;
   ret = SDB_OK;

done:
   return ret;
error:
   if (NULL != bufferBIO)
   {
      BIO_free(bufferBIO);
   }
   if (NULL != socketBIO)
   {
      BIO_free(socketBIO);
   }
   if (NULL != ssl)
   {
      SSL_free(ssl);
   }
   if (NULL != h)
   {
      OPENSSL_free(h);
   }
   ret = SSL_ERROR;
   goto done;
}
Exemple #10
0
INT32 ossSSLNewContext(SSLContext** context, SSLCertificate* cert, SSLKey* key)
{
   SSLContext* ctx = NULL;
   INT32 ret = SDB_OK;

   SSL_ASSERT(NULL != context);
   SSL_ASSERT(NULL != key);
   SSL_ASSERT(NULL != cert);

   ctx = SSL_CTX_new(SSLv23_method ());
   if (NULL == ctx)
   {
      goto error;
   }

   /* SSL_OP_ALL - Activate all bug workaround options, to support buggy client SSL's.
    * SSL_OP_NO_SSLv2 - Disable SSL v2 support
    */
   SSL_CTX_set_options(ctx, (SSL_OP_ALL | SSL_OP_NO_SSLv2));

   /* HIGH - Enable strong ciphers
    * !EXPORT - Disable export ciphers (40/56 bit)
    * !aNULL - Disable anonymous auth ciphers
    * @STRENGTH - Sort ciphers based on strength
    */
   SSL_CTX_set_cipher_list(ctx, "HIGH:!EXPORT:!aNULL@STRENGTH");

   /* If renegotiation is needed, don't return from recv() or send() until it's successful.
    * NOTE: this is for blocking sockets only.
    */
   SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);

   /* disable session caching */
   SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

   ret = SSL_CTX_use_certificate(ctx, cert);
   if (!ret)
   {
      goto error;
   }

   ret = SSL_CTX_use_PrivateKey(ctx, key);
   if (!ret)
   {
      goto error;
   }

   ret = SSL_CTX_check_private_key(ctx);
   if (!ret)
   {
      goto error;
   }

   *context = ctx;
   ret = SSL_OK;

done:
   return ret;
error:
   if (NULL != ctx)
   {
      SSL_CTX_free(ctx);
   }
   ret = SSL_ERROR;
   goto done;
}