Topic: serverUnixTime value

Hello

I'm interested in writing a sample client app that performs an SSL handshake, and dumps the serverUnixTime Value. I was thinking of using the client as a starting point. Does the wolfSSL API offer access to the unix time field?

Also, I tried executing the client as per the getting started guide...

./examples/client/client -h gmail.google.com -p 443 -d -g

But I get this error:

err = -313, revcd alert fatal error
wolfSSL error: SSL_connect failed


I also tried mail.google.com to no avail.

Please note that I have only compiled from source (./configure, make), and did not install (make install).

Share

Re: serverUnixTime value

Hi,

As of the wolfSSL 3.9.6 release, we now have a GetTime() API in <wolfssl/wolfcrypt/asn_public.h> that returns the seconds since the Unix epoch:

/* Time */
/* Returns seconds (Epoch/UTC)
 * timePtr: is "time_t", which is typically "long"
 * Example:
    long lTime;
    rc = wc_GetTime(&lTime, (word32)sizeof(lTime));
 */
WOLFSSL_API int wc_GetTime(void* timePtr, word32 timeSize);

./examples/client/client -h gmail.google.com -p 443 -d -g
But I get this error:
err = -313, revcd alert fatal error
wolfSSL error: SSL_connect failed

With recent changes to the google.com servers, wolfSSL now needs the TLS Supported Curves Extension enabled to successfully connect to gmail/google.com.  Can you try re-compiling wolfSSL using the "--enable-tlsx" (to enable all TLS Extensions) or "--enable-supportedcurves" option?

Thanks,
Chris

Re: serverUnixTime value

Hi Chris

Thanks for the reply. Yes, I know about that API, but I am specifically interested in the Server random response. I know that this is not a required field per the RFC, but I would still like to parse it out from the SSL handshake.

I tried the enable tlsx and supported curves, but that doesn't get rid of the error message.

also a related question, which root CA cert should I use for the google.com test? does wolfSSL already come populated with some root CAs?

Share

Re: serverUnixTime value

Some more information:
I took all the pem files from my /etc/ssl/certs dir and made a new dir. I then used one of those based on the host I was trying to ssl handshake with.

for instance:

./examples/client/client -h umich.edu -p 443 -A mycerts/AddTrust_External_Root.pem -v 1 -d
err = -313, revcd alert fatal error
wolfSSL error: SSL_connect failed

I compiled wolfSSL like the following

./configure --enable-tlsx --enable-supportedcurves --disable-fastmath
make
sudo make install

But I still get that error. Any ideas?

Share

5 (edited by earlenceferns 2016-06-16 23:19:34)

Re: serverUnixTime value

Some more info.

I compiled with with ./configure --enable-tlsx --enable-supportedcurves --disable-fastmath --enable-sslv3 --enable-curve25519 --enable-debug

and then $ ./examples/client/client -h google.com -p 443 -A ../ssltime/certs/Equifax_Secure_CA.pem seems to work. However, when I try

./examples/client/client -h umich.edu -p 443 -A ../ssltime/certs/AddTrust_External_Root.pem

I get:

connect state: CLIENT_HELLO_SENT
SSL version error
wolfSSL error occurred, error = -326
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return -326
wolfSSL Entering ERR_error_string
err = -326, record layer version error
wolfSSL error: SSL_connect failed


with -v 1:

connect state: CLIENT_HELLO_SENT
received record layer msg
got ALERT!
Got alert
wolfSSL error occurred, error = 40
wolfSSL error occurred, error = -313
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return -313
wolfSSL Entering ERR_error_string
err = -313, revcd alert fatal error
wolfSSL error: SSL_connect failed


with -v 2:

connect state: CLIENT_HELLO_SENT
SSL version error
wolfSSL error occurred, error = -326
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return -326
wolfSSL Entering ERR_error_string
err = -326, record layer version error
wolfSSL error: SSL_connect failed


with -v 3:

connect state: CLIENT_HELLO_SENT
SSL version error
wolfSSL error occurred, error = -326
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return -326
wolfSSL Entering ERR_error_string
err = -326, record layer version error
wolfSSL error: SSL_connect failed


I also wrote my own sample program to do an SSL handshake:

struct addrinfo* resolveHost(char *hostname, char *port) {
  struct addrinfo hints, *res, *p;
  int status;
  char ipstr[INET6_ADDRSTRLEN];

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC; //IP v4 or v6 we dont care
  hints.ai_socktype = SOCK_STREAM;

  status = getaddrinfo(hostname, port, &hints, &res);
  if (status != 0)
    return NULL;

  /*for(p = res; p != NULL; p = p->ai_next)
  {
    void *addr;

    if (p->ai_family == AF_INET) //IPv4
    {
      struct sockaddr_in *ipv4 = (struct sockaddr_in *) p->ai_addr;
      addr = &(ipv4->sin_addr);
    }
    else
    {
      struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) p->ai_addr;
      addr = &(ipv6->sin6_addr);
    }

    //convert IP to string
    inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
    printf("%s\n", ipstr);
  }

  freeaddrinfo(res);*/

  return res; //to be freed upon program exit
}

void driver(char *hostname, char *port, char *capath) {
  int sockfd;
  WOLFSSL_CTX* ctx;
  WOLFSSL* ssl;

  wolfSSL_Init();

  struct addrinfo *host = resolveHost(hostname, port);

  if ((ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL)
    printf("%s\n", "wolfSSL_CTX_new error");
  else {
    //load up CA certs
    int err;
    if ((err = wolfSSL_CTX_load_verify_locations(ctx, capath, NULL)) != SSL_SUCCESS) {
      char buffer[WOLFSSL_MAX_ERROR_SZ];
      printf("%s: %s\n", "error loading up CA cert", wolfSSL_ERR_error_string(err, buffer));
    }
    else {
      //we are ready to SSL handshake
      if (host != NULL) {
        sockfd = socket(host->ai_family, host->ai_socktype, host->ai_protocol);
        int ret = connect(sockfd, host->ai_addr, host->ai_addrlen);
        if (ret < 0)
          printf("error in connect: %s\n", strerror(errno));
        else {
          printf("Connected to %s:%s!\n", hostname, port);

          if ((ssl = wolfSSL_new(ctx)) == NULL)
            printf("%s\n", "wolfSSL_new error");
          else {
            wolfSSL_set_fd(ssl, sockfd);
            if (wolfSSL_connect(ssl) == SSL_SUCCESS)
              printf("%s\n", "SSL handshake complete");
            else {
              int err = wolfSSL_get_error(ssl, 0);
              char buffer[WOLFSSL_MAX_ERROR_SZ];
              printf("%s: %s\n", "SSL handshake error", wolfSSL_ERR_error_string(err, buffer));
            }
          }
        }
      }
      else
           printf("error looking up IP for %s\n", hostname);
    }
  }

  wolfSSL_CTX_free(ctx);
  wolfSSL_Cleanup();

  close(sockfd);
  freeaddrinfo(host);
}

int main(int argc, char *argv[]) {
  char *hostname = (char *) argv[1];
  char *port = (char *) argv[2];
  char *cert = (char *) argv[3];
  printf("cert: %s\n", cert);
  driver(hostname, port, cert);
  return 0;
}

and when I run this like

./a.out google.com 443 Equifax_Secure_CA.pem

I get the usual recvd alert fatal error.

Not sure what's going on here. Did I compile incorrectly? Did I install incorrectly?

Share

Re: serverUnixTime value

Hi,

--------- Server Random ----------

The server random value is sent during the ServerHello message of the SSL/TLS handshake.  This is later used to calculate the master secret.

wolfSSL exposes the following two functions when compiled with OPENSSL_EXTRA defined:

<wolfssl/ssl.h>

void wolfSSL_KeepArrays(WOLFSSL* ssl);
void wolfSSL_FreeArrays(WOLFSSL* ssl);
int wolfSSL_get_keys(WOLFSSL*,unsigned char** ms, unsigned int* msLen,
          unsigned char** sr, unsigned int* srLen,
          unsigned char** cr, unsigned int* crLen);

wolfSSL_get_keys() will give your application access to the master secret (ms), server random (sr), and client random (cr).  The pointers you pass in will point to those values held by wolfSSL internally.  The sizes of each are returned through msLen, srLen, and crLen.  This function must be called after the handshake completes.

Before the handshake starts, you need to call wolfSSL_KeepArrays() so these arrays remain available after the handshake finishes.  Your application can free the arrays by calling wolfSSL_FreeArrays(), or wait for the WOLFSSL object to be freed.

---------- umich.edu ----------

For connecting to "umich.edu", this server only supports static RSA cipher suites.  By default, wolfSSL has static RSA cipher suites disabled by default.  You can enable them at compile time by defining WOLFSSL_STATIC_RSA.  Adding that to your ./configure would be:

./configure --enable-tlsx --enable-supportedcurves --disable-fastmath C_EXTRA_FLAGS="-DWOLFSSL_STATIC_RSA"

After this, the example client will connect successfully to "umich.edu" using the attached root CA certificate:

./examples/client/client -h umich.edu -p 443 -v 1 -A addtrustexternalcaroot.crt

To determine the cipher suites and protocol version supported by "umich.edu", I used the "ssl-enum-ciphers" script provided by the nmap tool:

nmap --script ssl-enum-ciphers -p 443 umich.edu

Best Regards,
Chris