[Help-gnutls] non-existing CA bundle

Daniel Stenberg daniel at haxx.se
Sun Apr 10 00:15:48 CEST 2005


On Sat, 9 Apr 2005, Nikos Mavrogiannopoulos wrote:

> Could you send me a small program that can reproduce this problem?

Sorry for all the noise tonight, but I truly expect this to be my last mail 
for a few hours! ;-)

Here's how to repeat a problem that seems to be the same one I get. At least 
it loops in the the handshake loop "forever". (The assert line numbers are 
slightly different though.)

Attached to this mail is a test application source code. I built it on Linux 
and linked with GnuTLS 1.2.0.

In my earlier post, I tried the app against the sourceforge HTTPS server and 
it worked fine.

Now I tried it against my test server (for the curl test suite) and I get the 
problem. The test server in question is simply stunnel running with my dumb 
HTTP test server behind it.

The 'httpssserver.pl' I use is a script that just starts stunnel with the 
proper options. See here:

http://cool.haxx.se/cvs.cgi/curl/tests/httpsserver.pl?rev=HEAD&content-type=text/vnd.viewcvs-markup

I figure you could get away with using _anything_ to stunnel to in order to 
get this test setup working since the handshake never completes and thus 
stunnel never passes anything through to the other program.

-- 
          -=- Daniel Stenberg -=- http://daniel.haxx.se -=-
   ech`echo xiun|tr nu oc|sed 'sx\([sx]\)\([xoi]\)xo un\2\1 is xg'`ol
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <gnutls/gnutls.h>
#include <fcntl.h>

void nonblock(int sockfd)
{
  /* most recent unix versions */
  int flags;

  flags = fcntl(sockfd, F_GETFL, 0);
  fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
}

#define MAX_BUF 1024
#define SA struct sockaddr
#define MSG "GET / HTTP/1.0\r\n\r\n"

/* Connects to the peer and returns a socket
 * descriptor.
 */
int tcp_connect(void)
{
#if 0
    const char *PORT = "443";
    const char *SERVER = "66.35.250.203"; /* www.sourceforge.net */
#else
    const char *PORT = "8999";
    const char *SERVER = "127.0.0.1";
#endif
    int err, sd;
    struct sockaddr_in sa;

    /* connects to server
     */
    sd = socket(AF_INET, SOCK_STREAM, 0);

    memset(&sa, '\0', sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(atoi(PORT));
    inet_pton(AF_INET, SERVER, &sa.sin_addr);

    err = connect(sd, (SA *) & sa, sizeof(sa));
    if (err < 0) {
        fprintf(stderr, "Connect error\n");
        exit(1);
    }

    nonblock(sd);

    return sd;
}

static void tls_log_func(int level, const char *str)
{
  fprintf(stderr, "|<%d>| %s", level, str);
}

/* closes the given socket descriptor.
 */
void tcp_close(int sd)
{
  shutdown(sd, SHUT_RDWR);    /* no more receptions */
  close(sd);
}

int main()
{
  int ret, sd, ii;
  gnutls_session session;
  gnutls_anon_client_credentials cred;
  char buffer[MAX_BUF + 1];
  char *cafile="doesntexist";
  const int cert_type_priority[3] = { GNUTLS_CRT_X509, 0 };
  int rc;

  /* connect to the peer
   */
  sd = tcp_connect();

  fprintf(stderr, "gnutls: %s\n", gnutls_check_version(NULL));

  gnutls_global_init();

  gnutls_global_set_log_function(tls_log_func);
  gnutls_global_set_log_level(2);

  rc = gnutls_certificate_allocate_credentials(&cred);

  fprintf(stderr, "==> Before SET CA\n");
  rc = gnutls_certificate_set_x509_trust_file(cred,
                                              cafile,
                                              GNUTLS_X509_FMT_PEM);
  fprintf(stderr, "==> After SET CA\n");
  /* Initialize TLS session
   */
  gnutls_init(&session, GNUTLS_CLIENT);

  /* Use default priorities */
  gnutls_set_default_priority(session);
  rc = gnutls_certificate_type_set_priority(session, cert_type_priority);

  rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);

  gnutls_transport_set_ptr(session, (gnutls_transport_ptr) sd);

  fprintf(stderr, "==> Before Handshake\n");
  /* Perform the TLS handshake
   */
  while(1) {
    fd_set fds_read;
    fd_set fds_write;
    struct timeval timeout={1,0};

    ret = gnutls_handshake(session);

    if((ret != GNUTLS_E_AGAIN) &&
       (ret != GNUTLS_E_INTERRUPTED))
      break;

    FD_ZERO(&fds_read);
    FD_ZERO(&fds_write);

    FD_SET(sd, &fds_read);
    FD_SET(sd, &fds_write);
    select(sd+1, &fds_read, &fds_write, NULL, &timeout);
  }

  if (ret < 0) {
    fprintf(stderr, "*** Handshake failed\n");
    gnutls_perror(ret);
  }
  else {
    printf("- Handshake was completed\n");
  }

  tcp_close(sd);

  gnutls_deinit(session);

  gnutls_global_deinit();

  return 0;
}



More information about the Gnutls-help mailing list