[gnutls-help] gnutls_certificate_set_x509_trust_file and Cygwin
Alexander Ausserstorfer
bavariasound at chiemgau-net.de
Sat Apr 20 08:03:51 CEST 2013
Zitat von Alexander Ausserstorfer <bavariasound at chiemgau-net.de>:
> Under Cygwin I set gnutls_certificate_set_x509_trust_file to
>
> #define CAFILE "/usr/ssl/certs/ca-bundle.trust.crt"
>
> gnutls_certificate_set_x509_trust_file (cert_cret, CAFILE,
> GNUTLS_X509_FMT_PEM);
>
> ca-bundle.trust.crt was part of Cygwin. Now, the function
> gnutls_certificate_set_x509_trust_file returns 0 and all later
> verification of certificates fails. I suppose that the function
> should return another number as 0. Is that mind right?
Yesterday the staff kicked me out the computer room, and today the
wireless network access here doesn't work, so sorry for the
circumstances.
The first question is if I use the right certificates. The file
ca-bundle.trust.crt at cygwin/usr/ssl/certs/ sais:
############################################################################
This is a bundle of X.509 certificates of public Certificate
Authorities. It was generated from the Mozilla root CA list. These
certificates are in the OpenSSL "TRUSTED CERTIFICATE" format and have
trust bits accordingly.
Source: mozilla/security/nss/lib/ckfw/builtins/certdata.txt
[...]
############################################################################
Then I use the function
gnutls_certificate_set_x509_trust_file (cert_cred, CAFILE,
GNUTLS_X509_FMT_PEM)
to add the list but the function returns zero. It is the first time I
try GnuTLS. It seems to me that the function does nothing. I work with
Cygwin. May be Cygwin is the problem?
Here is all the code I wrote (I hope copy & paste work here correctly):
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h> // AF_INET, SOCK_STREAM, connect()
#include <netdb.h> // struct hostent
#include <netinet/in.h> // struct sockadd_in
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
#include <string.h>
#define MAX_BUF 1024
#define MAXMSG 512
#define CAFILE "/usr/ssl/certs/ca-bundle.trust.crt"
struct hostent *hostinfo;
struct sockaddr_in name;
static int _verify_certificate_callback (gnutls_session_t session);
void IP_number(struct sockaddr_in *name, char *servername, uint16_t port)
{
char serverIP[16];
if(hostinfo=gethostbyname(servername))
{
// converting name in IP number
inet_ntop(PF_INET,hostinfo->h_addr_list[0],serverIP,16);
printf("IP: %s\n",serverIP);
name->sin_family = PF_INET;
name->sin_port = htons(port);
name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
}
else
{
fprintf(stderr, "Unknown host %s.\n",servername);
exit (EXIT_FAILURE);
}
}
main()
{
int ret, sd, ii;
gnutls_session_t session;
gnutls_srp_client_credentials_t srp_cred;
gnutls_certificate_credentials_t cert_cred;
char buffer2[MAX_BUF + 1];
const char *err;
// Required data
char server[30];
printf("Server: ");
scanf("%s",server);
char USER[30]="";
printf("User: ");
scanf("%s",USER);
char *password;
password=(char *)getpass("Password: ");
char buffer[MAXMSG];
uint16_t port=110;
int sock=-1;
size_t size;
// converting server name in IP number
IP_number(&name, server, port);
// Creating socket for connection to this server
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
perror("socket");
exit (EXIT_FAILURE);
}
// Making the connection
if (connect(sock, (struct sockaddr *) &name, sizeof (struct
sockaddr_in)) < 0)
{
perror ("connect");
exit (EXIT_FAILURE);
}
// Reading
int amount = read(sock, buffer, MAXMSG);
printf("%.*s", amount, buffer);
write(sock,"CAPA\r\n",6);
amount = read(sock, buffer, MAXMSG);
printf("%.*s", amount, buffer);
write(sock,"STLS\r\n",6);
amount = read(sock, buffer, MAXMSG);
printf("%.*s", amount, buffer);
// Security connection
gnutls_global_init();
gnutls_srp_allocate_client_credentials (&srp_cred);
gnutls_certificate_allocate_credentials (&cert_cred);
printf("\nAnzahl der verarbeiteten Zertifikate:
%d\n",gnutls_certificate_set_x509_trust_file (cert_cred, CAFILE,
GNUTLS_X509_FMT_PEM));
gnutls_certificate_set_verify_function (cert_cred,
_verify_certificate_callback);
gnutls_srp_set_client_credentials (srp_cred, USER, password);
gnutls_init (&session, GNUTLS_CLIENT);
gnutls_session_set_ptr (session, (void *) server);
gnutls_server_name_set (session, GNUTLS_NAME_DNS, server, strlen(server));
/* Use default priorities */
ret = gnutls_priority_set_direct (session,
"NORMAL:+SRP:+SRP-RSA:+SRP-DSS", &err);
if (ret < 0)
{
if (ret == GNUTLS_E_INVALID_REQUEST)
{
fprintf (stderr, "Syntax error at: %s\n", err);
}
exit(1);
}
gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cert_cred);
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sock);
do
{
ret = gnutls_handshake (session);
} while (ret < 00 && gnutls_error_is_fatal (ret) == 0);
if (ret < 0)
{
fprintf (stderr, "*** Handshake failed\n");
gnutls_perror (ret);
goto end;
}
else
{
printf ("- Handshake was completed\n");
}
gnutls_record_send(session, "USER ########\r\n",15);
ret = gnutls_record_recv(session,buffer2,MAX_BUF);
if (gnutls_error_is_fatal (ret) != 0 || ret == 0)
{
if (ret == 0)
{
printf ("- Peer has closed the GnuTLS connection\n");
goto end;
}
else
{
fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
goto end;
}
}
if (ret > 0)
{
printf ("- Reveived %d bytes: ", ret);
for (ii = 0 ; ii < ret; ii++)
{
fputc (buffer2[ii], stdout);
}
fputs ("\n", stdout);
}
gnutls_record_send(session, "PASS ########\r\n",15);
ret = gnutls_record_recv(session,buffer2,MAX_BUF);
if (gnutls_error_is_fatal (ret) != 0 || ret == 0)
{
if (ret == 0)
{
printf ("- Peer has closed the GnuTLS connection\n");
goto end;
}
else
{
fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
goto end;
}
}
if (ret > 0)
{
printf ("- Reveived %d bytes: ", ret);
for (ii = 0 ; ii < ret; ii++)
{
fputc (buffer2[ii], stdout);
}
fputs ("\n", stdout);
}
gnutls_record_send(session, "RETR 1\r\n",8);
ret = gnutls_record_recv(session,buffer2,MAX_BUF);
if (gnutls_error_is_fatal (ret) != 0 || ret == 0)
{
if (ret == 0)
{
printf ("- Peer has closed the GnuTLS connection\n");
goto end;
}
else
{
fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
goto end;
}
}
if (ret > 0)
{
printf ("- Reveived %d bytes: ", ret);
for (ii = 0 ; ii < ret; ii++)
{
fputc (buffer2[ii], stdout);
}
fputs ("\n", stdout);
}
gnutls_bye (session, GNUTLS_SHUT_RDWR);
end:
// Closing socket
close(sock);
gnutls_deinit(session);
gnutls_srp_free_client_credentials (srp_cred);
gnutls_certificate_free_credentials (cert_cred);
gnutls_global_deinit();
printf("Ready\n");
}
static int _verify_certificate_callback (gnutls_session_t session)
{
unsigned int status;
const gnutls_datum_t *cert_list;
unsigned int cert_list_size;
int ret;
gnutls_x509_crt_t cert;
const char *hostname;
/* read hostname */
hostname = gnutls_session_get_ptr (session);
/* This varification function uses the trusted CAs in the credentials
* structure. So you must have installed one or more CA certificates.
*/
ret = gnutls_certificate_verify_peers2 (session, &status);
if (ret < 0)
{
printf ("Error\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
printf ("The certificate hasn't got a known issuer\n");
if (status & GNUTLS_CERT_REVOKED)
printf ("The certificate has been revoked\n");
if (status & GNUTLS_CERT_EXPIRED)
printf ("The certificate has expired\n");
if (status & GNUTLS_CERT_NOT_ACTIVATED)
printf ("The certificate is not yet activated\n");
if (status & GNUTLS_CERT_INVALID)
{
printf ("The certificate is not trusted\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
/* Up to here the process is the same for X.509 certificates and
* OpenPGP keys. From now on X.509 certificates are assumed. This can
* be easily extended to work with openpgp keys as well.
*/
if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
return GNUTLS_E_CERTIFICATE_ERROR;
if (gnutls_x509_crt_init (&cert) < 0 )
{
printf ("error in initialization\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
if (cert_list == NULL)
{
printf ("No certificate was found!\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
{
printf ("error parsing certificate\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (!gnutls_x509_crt_check_hostname (cert, hostname))
{
printf ("The certificate's owner does not match hostname
'%s'\n", hostname);
return GNUTLS_E_CERTIFICATE_ERROR;
}
gnutls_x509_crt_deinit (cert);
/* notify gnutls to continue handshake normally */
return 0;
}
Some sensible data were replaced by ########. Thanks for any help / hints.
Alex'
--
http://home.chiemgau-net.de/ausserstorfer/
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
More information about the Gnutls-help
mailing list