]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Corrected bugs in gnutls_x509_rdn_get(). Added a test to print the server's trusted...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 14 Feb 2003 15:48:33 +0000 (15:48 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 14 Feb 2003 15:48:33 +0000 (15:48 +0000)
lib/auth_cert.c
lib/gnutls.h.in.in
lib/gnutls_cert.c
lib/gnutls_ui.h
lib/x509/dn.c
lib/x509/rfc2818_hostname.c
src/cli.c
src/common.c
src/tests.c
src/tests.h
src/tls_test.c

index e6fe3054cc645d334869334d0904e68e9fbc3347..f254b4966b53982cb6da6ac69df7b82fd2e8bcad 100644 (file)
@@ -286,7 +286,9 @@ static int _gnutls_find_acceptable_client_cert(gnutls_session session,
 
        /* use the callback 
         */
-       if (indx == -1 && session->internals.client_cert_callback != NULL && cred->ncerts > 0) {        /* use a callback to get certificate */
+       if (indx == -1 && session->internals.client_cert_callback != NULL && try == -1) {
+               /* use a callback to get certificate 
+                */
                gnutls_datum *my_certs = NULL;
                gnutls_datum *issuers_dn = NULL;
                uint issuers_dn_len = 0;
index 6b6bf74192240397ce9c3898feb6d57a3bb9c993..a54a9e35e6db9c8b2dc045c4a9a5cca601ac14e1 100644 (file)
@@ -388,3 +388,4 @@ void gnutls_openpgp_send_key(gnutls_session session, gnutls_openpgp_key_status s
 /* fingerprint */
 int gnutls_fingerprint(gnutls_digest_algorithm algo, const gnutls_datum* data, 
        char* result, size_t* result_size);
+
index 4f17c8c78739239ee53942ab3d362c62ce2ea26f..5e0638a51b462fba7ceec79b6c4514d3855ca1ed 100644 (file)
@@ -178,7 +178,7 @@ void gnutls_certificate_server_set_request(gnutls_session session,
   * @func: is the callback function
   *
   * The callback's function form is:
-  * int (*callback)(gnutls_session, gnutls_datum *client_cert, int ncerts, gnutls_datum* req_ca_cert, int nreqs);
+  * int (*callback)(gnutls_session, gnutls_datum *client_cert, int ncerts, gnutls_datum* req_ca_dn, int nreqs);
   *
   * 'client_cert' contains 'ncerts' gnutls_datum structures which hold
   * the raw certificates (DER for X.509 or binary for OpenPGP), of the
@@ -198,10 +198,10 @@ void gnutls_certificate_server_set_request(gnutls_session session,
   * public key algorithms.
   *
   * If the callback function is provided then gnutls will call it
-  * once with NULL parameters. If the callback function returns
+  * once with NULL parameters (except for the sesion). If the callback function returns
   * a positive or zero number then gnutls will attempt to automaticaly
   * choose the appropriate certificate. If gnutls fails to find an appropriate
-  * certificate, then it will call the callback function again with the 
+  * certificate, then it will call the callback function again with the
   * appropriate parameters.
   *
   * In case the callback returned a negative number then gnutls will
@@ -210,7 +210,8 @@ void gnutls_certificate_server_set_request(gnutls_session session,
   * only to the return value of the callback function.
   *
   * The callback function should return the index of the certificate
-  * choosen by the user. -1 indicates that the user
+  * choosen by the user. The index is relative to the certificates in the
+  * callback's parameter. The value (-1) indicates that the user
   * does not want to use client authentication.
   *
   * This function returns 0 on success.
@@ -342,7 +343,6 @@ int gnutls_certificate_verify_peers(gnutls_session session)
 
        info = _gnutls_get_auth_info(session);
        if (info == NULL) {
-               gnutls_assert();
                return GNUTLS_E_NO_CERTIFICATE_FOUND;
        }
        
@@ -376,7 +376,6 @@ time_t gnutls_certificate_expiration_time_peers(gnutls_session session)
 
        info = _gnutls_get_auth_info(session);
        if (info == NULL) {
-               gnutls_assert();
                return (time_t) -1;
        }
 
@@ -417,7 +416,6 @@ time_t gnutls_certificate_activation_time_peers(gnutls_session session)
 
        info = _gnutls_get_auth_info(session);
        if (info == NULL) {
-               gnutls_assert();
                return (time_t) -1;
        }
        
index 38c14bd001096712116aaa240982823aa75cb34a..53c81362072271e894d42f12832624602774f4f9 100644 (file)
@@ -8,10 +8,14 @@ typedef enum gnutls_x509_subject_alt_name {
 
 # ifdef LIBGNUTLS_VERSION /* These are defined only in gnutls.h */
 
-typedef int gnutls_certificate_client_select_function(gnutls_session, 
-       const gnutls_datum *, unsigned int, const gnutls_datum *, unsigned int);
-typedef int gnutls_certificate_server_select_function(gnutls_session, 
-       const gnutls_datum *, unsigned int);
+/* Callback prototypes for the certificate authentication
+ * callbacks.
+ */
+typedef int gnutls_certificate_client_select_function(
+   gnutls_session, const gnutls_datum *client_cert, int ncerts, 
+   const gnutls_datum* req_ca_cert, int nreqs);
+typedef int gnutls_certificate_server_select_function(
+   gnutls_session, const gnutls_datum *server_certs, int ncerts);
 
 /* Functions that allow AUTH_INFO structures handling
  */
index e9bcf100169b0fcdfc2e2e24c09da05a71378503..47fbca4416f93c882bad1b903643b6cd05a435e2 100644 (file)
@@ -116,7 +116,9 @@ int _gnutls_x509_parse_dn(ASN1_TYPE asn1_struct,
                _gnutls_int2str(k1, counter);
                _gnutls_str_cpy(tmpbuffer1, sizeof(tmpbuffer1),
                                asn1_rdn_name);
-               _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), ".?");
+               if (strlen(tmpbuffer1) > 0)
+                       _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), ".");
+               _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), "?");
                _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), counter);
 
                len = sizeof(value) - 1;
@@ -142,8 +144,10 @@ int _gnutls_x509_parse_dn(ASN1_TYPE asn1_struct,
                        _gnutls_int2str(k2, counter);
                        _gnutls_str_cpy(tmpbuffer2, sizeof(tmpbuffer2),
                                        tmpbuffer1);
-                       _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2),
-                                       ".?");
+                       if (strlen( tmpbuffer2) > 0)
+                               _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2),
+                                       ".");
+                       _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2), "?");
                        _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2),
                                        counter);
 
@@ -323,7 +327,10 @@ int _gnutls_x509_parse_dn_oid(ASN1_TYPE asn1_struct,
                _gnutls_int2str(k1, counter);
                _gnutls_str_cpy(tmpbuffer1, sizeof(tmpbuffer1),
                                asn1_rdn_name);
-               _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), ".?");
+
+               if (strlen( tmpbuffer1) > 0)
+                       _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), ".");
+               _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), "?");
                _gnutls_str_cat(tmpbuffer1, sizeof(tmpbuffer1), counter);
 
                len = sizeof(value) - 1;
@@ -350,8 +357,11 @@ int _gnutls_x509_parse_dn_oid(ASN1_TYPE asn1_struct,
                        _gnutls_int2str(k2, counter);
                        _gnutls_str_cpy(tmpbuffer2, sizeof(tmpbuffer2),
                                        tmpbuffer1);
+
+                       if (strlen( tmpbuffer2) > 0)
+                               _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2), ".");
                        _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2),
-                                       ".?");
+                                       "?");
                        _gnutls_str_cat(tmpbuffer2, sizeof(tmpbuffer2),
                                        counter);
 
@@ -490,6 +500,7 @@ int gnutls_x509_rdn_get(const gnutls_datum * idn,
        ASN1_TYPE dn = ASN1_TYPE_EMPTY;
 
        if (sizeof_buf == 0) {
+               gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
@@ -513,7 +524,7 @@ int gnutls_x509_rdn_get(const gnutls_datum * idn,
                return _gnutls_asn2err(result);
        }
 
-       result = _gnutls_x509_parse_dn(dn, "", buf, sizeof_buf);
+       result = _gnutls_x509_parse_dn(dn, "rdnSequence", buf, sizeof_buf);
 
        asn1_delete_structure(&dn);
        return result;
@@ -566,7 +577,7 @@ int gnutls_x509_rdn_get_by_oid(const gnutls_datum * idn, const char* oid, int in
                return _gnutls_asn2err(result);
        }
 
-       result = _gnutls_x509_parse_dn_oid(dn, "", oid, indx, buf, sizeof_buf);
+       result = _gnutls_x509_parse_dn_oid(dn, "rdnSequence", oid, indx, buf, sizeof_buf);
 
        asn1_delete_structure(&dn);
        return result;
index a8856bc378f58da3268b484409702a40a3a3555c..e538684adcf652f7dd99713043a6f4049c39c83a 100644 (file)
@@ -29,7 +29,7 @@
 
 static int hostname_compare(const char *certname, const char *hostname);
 
-/**
+/*-
   * gnutls_x509_check_certificates_hostname - This function compares the given hostname with the hostname in the certificate
   * @cert: should contain a DER encoded certificate
   * @hostname: A null terminated string that contains a DNS name
@@ -40,7 +40,7 @@ static int hostname_compare(const char *certname, const char *hostname);
   *
   * Returns non zero on success, and zero on failure.
   *
-  **/
+  -*/
 int gnutls_x509_check_certificates_hostname(const gnutls_datum * cert,
                                 const char *hostname)
 {
index bbc99d50faeefdd5ea1d061246e168fc5c0f5d44..3c2407dafbc008f1db866d4c064644afba21c8d9 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -1,5 +1,5 @@
 /*
- *      Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
+ *      Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
  *
  * This file is part of GNUTLS.
  *
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/extra.h>
+#include <gnutls/x509.h>
 #include <sys/time.h>
 #include <signal.h>
 #include <netdb.h>
@@ -109,6 +110,38 @@ void init_global_tls_stuff(void);
 
 #define MAX(X,Y) (X >= Y ? X : Y);
 
+/* A callback function to be used at the certificate selection time.
+ */
+static int cert_callback( gnutls_session session, const gnutls_datum* client_certs,
+       int client_certs_num, const gnutls_datum * req_ca_rdn, int nreqs)
+{
+char issuer_dn[256];
+int len, i, ret;
+
+       if (client_certs == NULL && req_ca_rdn == NULL) return -1;
+
+       /* Print the server's trusted CAs
+        */
+       if (nreqs > 0)
+               printf("- Server's trusted authorities:\n");
+       else
+               printf("- Server did not send us any trusted authorities names.\n");
+
+       /* print the names (if any) */
+       for (i=0;i<nreqs;i++) {
+               len = sizeof(issuer_dn);
+               ret = gnutls_x509_rdn_get( &req_ca_rdn[i], issuer_dn, &len);
+               if ( ret >= 0) {
+                       printf("   [%d]: ", i);
+                       printf("%s\n", issuer_dn);
+               }
+       }
+
+       return -1;
+
+}
+
+
 /* initializes a gnutls_session with some defaults.
  */
 static gnutls_session init_tls_session( const char* hostname)
@@ -136,6 +169,8 @@ static gnutls_session init_tls_session( const char* hostname)
    gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
 
+   gnutls_certificate_client_set_select_function( session, cert_callback);
+
    /* send the fingerprint */
    if (fingerprint != 0)
       gnutls_openpgp_send_key(session, GNUTLS_OPENPGP_KEY_FINGERPRINT);
@@ -363,8 +398,6 @@ int main(int argc, char **argv)
 static gaainfo info;
 void gaa_parser(int argc, char **argv)
 {
-   int i, j;
-
    if (gaa(argc, argv, &info) != -1) {
       fprintf(stderr,
              "Error in the arguments. Use the --help or -h parameters to get more information.\n");
@@ -523,6 +556,7 @@ int do_handshake(socket_st* socket)
    return ret;
 }
 
+
 static void tls_log_func( const char* str)
 {
        fprintf(stderr, "|** %s", str);
@@ -609,7 +643,7 @@ int ret;
         fprintf(stderr, "Error setting the OpenPGP trustdb file\n");
       }
    }
-/*     gnutls_certificate_client_callback_func( xcred, cert_callback); */
+
 
    /* SRP stuff */
    if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) {
index d80ecabf1fa3c0783332806028fa6b35d8de182d..467c63601e8c6ee9ec60d3fe7311f6246bf1855c 100644 (file)
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/extra.h>
+#include <gnutls/x509.h>
 #include <time.h>
 
 #define TEST_STRING
@@ -11,13 +12,6 @@ int xml = 0;
 void print_cert_info(gnutls_session session);
 
 #define PRINTX(x,y) if (y[0]!=0) printf(" #   %s %s\n", x, y)
-#define PRINT_DN(X) PRINTX( "CN:", X.common_name); \
-       PRINTX( "OU:", X.organizational_unit_name); \
-       PRINTX( "O:", X.organization); \
-       PRINTX( "L:", X.locality_name); \
-       PRINTX( "S:", X.state_or_province_name); \
-       PRINTX( "C:", X.country); \
-       PRINTX( "E:", X.email)
 #define PRINT_PGP_NAME(X) PRINTX( "NAME:", X.name); \
        PRINTX( "EMAIL:", X.email)
 
@@ -35,80 +29,75 @@ static const char *my_ctime(time_t * tv)
 
 void print_x509_info(gnutls_session session)
 {
-
-       gnutls_x509_dn dn;
+       gnutls_x509_crt crt;
        const gnutls_datum *cert_list;
-       int cert_list_size = 0;
+       int cert_list_size = 0, ret;
        char digest[20];
        char serial[40];
+       char dn[128];
+       int dn_size;
        size_t digest_size = sizeof(digest);
        int i;
        int serial_size = sizeof(serial);
        char printable[120];
        char *print;
        int bits, algo;
-       time_t expiret = gnutls_certificate_expiration_time_peers(session);
-       time_t activet = gnutls_certificate_activation_time_peers(session);
+       time_t expiret, activet;
 
        cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
+       
 
        if (cert_list_size <= 0)
                return;
 
-#if 0 /* FIXME */
-       if (xml) {
-               gnutls_datum res;
-
-               gnutls_x509_certificate_to_xml(&cert_list[0], &res, 0);
-               puts(res.data);
-
-               free(res.data);
-
+       gnutls_x509_crt_init( &crt);
+       ret = gnutls_x509_crt_import( crt, &cert_list[0], GNUTLS_X509_FMT_DER);
+       if (ret < 0) {
+               fprintf(stderr, "Decoding error: %s\n", gnutls_strerror(ret));
                return;
        }
-#endif
 
-       printf(" - Certificate info:\n");
+       printf(" - Got a certificate list of %d certificates.\n", cert_list_size);
+       printf(" - Certificate[0] info:\n");
+
+       expiret = gnutls_x509_crt_get_expiration_time( crt);
+       activet = gnutls_x509_crt_get_activation_time( crt);
 
-       printf(" # Certificate is valid since: %s", my_ctime(&activet));
-       printf(" # Certificate expires: %s", my_ctime(&expiret));
+       printf(" # valid since: %s", my_ctime(&activet));
+       printf(" # expires at: %s", my_ctime(&expiret));
 
        /* Print the fingerprint of the certificate
         */
-       if (gnutls_x509_fingerprint
+       if (gnutls_fingerprint
            (GNUTLS_DIG_MD5, &cert_list[0], digest, &digest_size) >= 0) {
                print = printable;
                for (i = 0; i < digest_size; i++) {
                        sprintf(print, "%.2x ", (unsigned char) digest[i]);
                        print += 3;
                }
-               printf(" # Certificate fingerprint: %s\n", printable);
+               printf(" # fingerprint: %s\n", printable);
        }
 
        /* Print the serial number of the certificate.
         */
 
-       if (gnutls_x509_extract_certificate_serial
-           (&cert_list[0], serial, &serial_size) >= 0) {
+       if (gnutls_x509_crt_get_serial(crt, serial, &serial_size) >= 0) {
                print = printable;
                for (i = 0; i < serial_size; i++) {
                        sprintf(print, "%.2x ", (unsigned char) serial[i]);
                        print += 3;
                }
-               printf(" # Certificate serial number: %s\n", printable);
+               printf(" # serial number: %s\n", printable);
        }
 
        /* Print the version of the X.509 
         * certificate.
         */
-       printf(" # Certificate version: #%d\n",
-              gnutls_x509_extract_certificate_version(&cert_list[0]));
+       printf(" # version: #%d\n", gnutls_x509_crt_get_version(crt));
 
        algo =
-           gnutls_x509_extract_certificate_pk_algorithm(&cert_list[0],
-                                                        &bits);
-       printf(" # Certificate public key algorithm: ");
-
+           gnutls_x509_crt_get_pk_algorithm( crt, &bits);
+       printf(" # public key algorithm: ");
        if (algo == GNUTLS_PK_RSA) {
                printf("RSA\n");
                printf(" #   Modulus: %d bits\n", bits);
@@ -119,31 +108,17 @@ void print_x509_info(gnutls_session session)
                printf("UNKNOWN\n");
        }
 
-#ifndef TEST_STRING
-       gnutls_x509_extract_certificate_dn(&cert_list[0], &dn);
-       PRINT_DN(dn);
-
-       gnutls_x509_extract_certificate_issuer_dn(&cert_list[0], &dn);
-       printf(" # Certificate Issuer's info:\n");
-       PRINT_DN(dn);
-#else
-       { char buf[256];
-         int buf_size = sizeof(buf);
-         int ret;
-         
-       ret = gnutls_x509_extract_certificate_dn_string( buf, buf_size, &cert_list[0], 0);
-       if (ret == 0)
-          printf( " # %s\n", buf);
-       else printf("gnutls_x509_extract_certificate_dn_string() returned %d\n", ret);
-
-       ret = gnutls_x509_extract_certificate_dn_string( buf, buf_size, &cert_list[0], 1);
-       if (ret == 0) {
-          printf(" # Certificate Issuer's info:\n");
-          printf( " # %s\n", buf);
-       } else printf("gnutls_x509_extract_certificate_dn_string() returned %d\n", ret);
-
-        }
-#endif
+       dn_size = sizeof(dn);
+       ret = gnutls_x509_crt_get_dn( crt, dn, &dn_size);
+       if (ret >= 0)
+               printf( " # Subject's DN: %s\n", dn);
+
+       dn_size = sizeof(dn);
+       ret = gnutls_x509_crt_get_issuer_dn( crt, dn, &dn_size);
+       if (ret >= 0)
+               printf(" # Issuer's DN: %s\n", dn);
+
+       gnutls_x509_crt_deinit( crt);
 
 }
 
index 5208f069b2724e30cc21a17814798740abe95e74..f305592882a7397850e7d9a52993f299879bc993 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <gnutls/gnutls.h>
 #include <gnutls/extra.h>
+#include <gnutls/x509.h>
 #include <tests.h>
 #include <unistd.h>
 #include <signal.h>
@@ -587,3 +588,61 @@ int ret;
 
        return SUCCEED;
 }
+
+/* A callback function to be used at the certificate selection time.
+ */
+static int cert_callback( gnutls_session session, const gnutls_datum* client_certs,
+       int client_certs_num, const gnutls_datum * req_ca_rdn, int nreqs)
+{
+char issuer_dn[256];
+int len, i, ret;
+
+       if (client_certs == NULL && req_ca_rdn == NULL) return -1;
+
+       /* Print the server's trusted CAs
+        */
+       printf("\n");
+       if (nreqs > 0)
+               printf("- Server's trusted authorities:\n");
+       else
+               printf("- Server did not send us any trusted authorities names.\n");
+
+       /* print the names (if any) */
+       for (i=0;i<nreqs;i++) {
+               len = sizeof(issuer_dn);
+               ret = gnutls_x509_rdn_get( &req_ca_rdn[i], issuer_dn, &len);
+               if ( ret >= 0) {
+                       printf("   [%d]: ", i);
+                       printf("%s\n", issuer_dn);
+               }
+       }
+
+       return -1;
+
+}
+
+/* Prints the trusted server's CAs. This is only
+ * if the server sends a certificate request packet.
+ */
+int test_server_cas( gnutls_session session) 
+{
+int ret;
+
+       ADD_ALL_CIPHERS(session);
+       ADD_ALL_COMP(session);
+       ADD_ALL_CERTTYPES(session);
+       ADD_ALL_PROTOCOLS(session);
+       ADD_ALL_MACS(session);
+       ADD_ALL_KX(session);
+
+       gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
+        gnutls_certificate_client_set_select_function( session, cert_callback);
+
+       ret = do_handshake( session);
+       if (ret < 0) return FAILED;
+
+       return SUCCEED;
+}
+
+
+
index 0f7083a036e6c4f178dfe695e468e7bfee798497..7ae0b24ea799225cfc9563abb0504f07823582d6 100644 (file)
@@ -25,6 +25,7 @@ int test_unknown_ciphersuites( gnutls_session state);
 int test_openpgp1( gnutls_session state);
 int test_bye( gnutls_session state);
 int test_certificate( gnutls_session state);
+int test_server_cas( gnutls_session state);
 int test_session_resume2( gnutls_session state);
 
 #define GERR(ret) fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret))
index 2adf86d3c476c2b9a6eb4fb7628422e49ed4ddf4..b37e722da6169edb8f8e5721111c4abe98bf9ed0 100644 (file)
@@ -80,6 +80,7 @@ static const TLS_TEST tls_tests[] = {
        { "for TLS 1.0 support", test_tls1, "yes", "no", "dunno" },
        { "for SSL 3.0 support", test_ssl3, "yes", "no", "dunno" },
        { "for certificate information", test_certificate, "", "", "" },
+       { "for trusted CAs", test_server_cas, "", "", "" },
        { "for version rollback bug in RSA PMS", test_rsa_pms, "no", "yes", "dunno" },
        { "for version rollback bug in Client Hello", test_version_rollback, "no", "yes", "dunno" },
        /* this test will disable TLS 1.0 if the server is