]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Removed the application field and added an expiration field.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 10 Feb 2012 09:35:29 +0000 (10:35 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 10 Feb 2012 09:35:29 +0000 (10:35 +0100)
doc/cha-cert-auth.texi
doc/cha-gtls-examples.texi
doc/examples/ex-verify-ssh.c
lib/includes/gnutls/gnutls.h.in
lib/verify-ssh.c

index 7fb41a60dd195e0ff064a8f6a01ffe10100ab591..a2656ad94d97984f0e574ee0c15d1a5264230d9b 100644 (file)
@@ -87,7 +87,7 @@ acceptable.  The framework is illustrated on @ref{fig:x509}.
 * X.509 distinguished names::
 * Verifying X.509 certificate paths::
 * Verifying a certificate in the context of TLS session::
-* Verifying a certificate using SSH-style authentication::
+* Verifying a certificate using trust on first use authentication::
 @end menu
 
 @node X.509 certificate structure
@@ -277,15 +277,16 @@ about the peer's identity. It is required to verify if the
 certificate's owner is the one you expect. For more information
 consult @xcite{RFC2818} and section @ref{ex:verify} for an example.
 
-@node Verifying a certificate using SSH-style authentication
-@subsection Verifying a certificate using SSH-style authentication
+@node Verifying a certificate using trust on first use authentication
+@subsection Verifying a certificate using trust on first use authentication
 @cindex verifying certificate paths
 @cindex SSH-style authentication
+@cindex Trust on first use
 @tindex gnutls_certificate_verify_flags
 
-It is possible to use an SSH-style authentication method in GnuTLS.
-That means that having seen and associated a public key with a host
-is enough to trust it on the subsequent connections.
+It is possible to use a trust on first use (similar to SSH) authentication 
+method in GnuTLS. That means that having seen and associated a public key 
+with a host is enough to trust it on the subsequent connections.
 A hybrid system with X.509 and SSH authentication is 
 shown in @ref{Simple client example with SSH-style certificate verification}.
 
index 9d253a0045db6337513aadb18d54da540b7394c7..637653c46ab7b4a7c573ca334ebdb0235000e0be 100644 (file)
@@ -70,8 +70,9 @@ resumption.
 
 This is an alternative verification function that will use the
 X.509 certificate authorities for verification, but also assume an
-SSH-like authentication system. That is the user is prompted on unknown 
-public keys and known public keys are considered trusted.
+trust on first use (SSH-like) authentication system. That is the user is 
+prompted on unknown public keys and known public keys are considered 
+trusted.
 
 @verbatiminclude examples/ex-verify-ssh.c
 
index c9a66b27bc19a9f89eae7cc238a4e4315d8c3be6..fb211c5746e1bc127a884018c9e772bdb8745dc1 100644 (file)
@@ -92,8 +92,10 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
 
   gnutls_x509_crt_deinit (cert);
   
-  ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "443", 
-                                    GNUTLS_CRT_X509, &cert_list[0], 0);
+  /* service may be obtained alternatively using getservbyport() */
+  ret = gnutls_verify_stored_pubkey(NULL, hostname, "https", 
+                                    GNUTLS_CRT_X509, &cert_list[0], 
+                                    0, 0);
   if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
     {
       fprintf(stderr, "Host %s is not known.", hostname);
@@ -128,7 +130,7 @@ _ssh_verify_certificate_callback (gnutls_session_t session)
   /* user trusts the key -> store it */
   if (ret != 0)
     {
-      ret = gnutls_store_pubkey(NULL, NULL, hostname, "443", GNUTLS_CRT_X509, &cert_list[0], 0);
+      ret = gnutls_store_pubkey(NULL, hostname, "https", GNUTLS_CRT_X509, &cert_list[0], 0);
       if (ret < 0)
         fprintf(stderr, "gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
     }
index 415e282719a0d059755efc9e8d0c67acf1a8ceb6..f5adbf5863d04c45c53795ec652558e05a3f9d58 100644 (file)
@@ -1658,18 +1658,18 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
 
   /* ssh style functions */
   int gnutls_verify_stored_pubkey(const char* file, 
-                            const char* application,
                             const char* host,
                             const char* service,
                             gnutls_certificate_type_t cert_type,
                             const gnutls_datum_t * cert, unsigned int flags);
 
   int gnutls_store_pubkey(const char* file, 
-                    const char* application,
                     const char* host,
                     const char* service,
                     gnutls_certificate_type_t cert_type,
-                    const gnutls_datum_t * cert, unsigned int flags);
+                    const gnutls_datum_t * cert, 
+                    time_t expiration,
+                    unsigned int flags);
 
 
   /* Gnutls error codes. The mapping to a TLS alert is also shown in
index 8d6562f705a76ae7f4be4304b433f2aec4191e26..23ac819e62b4e449eff8548aae9d931a52ca0961 100644 (file)
@@ -38,7 +38,7 @@
 static int raw_pubkey_to_base64(gnutls_datum_t* pubkey);
 static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey);
 static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey);
-static int find_stored_pubkey(const char* file, const char* application,
+static int find_stored_pubkey(const char* file, 
                               const char* host, const char* service, 
                               const gnutls_datum_t* skey);
 static int find_config_file(char* file, size_t max_size);
@@ -47,7 +47,6 @@ static int find_config_file(char* file, size_t max_size);
 /**
  * gnutls_verify_stored_pubkey:
  * @file: A file specifying the stored keys (use NULL for the default)
- * @application: non-NULL with an application name if this key is application-specific
  * @host: The peer's name
  * @service: non-NULL if this key is specific to a service (e.g. http)
  * @cert_type: The type of the certificate
@@ -68,7 +67,6 @@ static int find_config_file(char* file, size_t max_size);
  **/
 int
 gnutls_verify_stored_pubkey(const char* file, 
-                            const char* application,
                             const char* host,
                             const char* service,
                             gnutls_certificate_type_t cert_type,
@@ -107,7 +105,7 @@ char local_file[MAX_FILENAME];
       goto cleanup;
     }
 
-  ret = find_stored_pubkey(file, application, host, service, &pubkey);
+  ret = find_stored_pubkey(file, host, service, &pubkey);
   if (ret < 0)
     return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
   
@@ -117,15 +115,16 @@ cleanup:
   return ret;
 }
 
-static int parse_line(char* line, const char* application,
-                      size_t application_len,
+static int parse_line(char* line, 
                       const char* host, size_t host_len,
                       const char* service, size_t service_len,
+                      time_t now,
                       const gnutls_datum_t *skey)
 {
 char* p, *kp;
 char* savep = NULL;
 size_t kp_len;
+time_t expiration;
 
   /* read version */
   p = strtok_r(line, "|", &savep);
@@ -135,31 +134,32 @@ size_t kp_len;
   if (strncmp(p, "g0", 2) != 0)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
 
-  /* read application */
+  /* read host */
   p = strtok_r(NULL, "|", &savep);
   if (p == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
     
-  if (p[0] != '*' && strcmp(p, application)!=0)
+  if (p[0] != '*' && strcmp(p, host) != 0)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
 
-  /* read host */
+  /* read service */
   p = strtok_r(NULL, "|", &savep);
   if (p == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
     
-  if (p[0] != '*' && strcmp(p, host) != 0)
+  if (p[0] != '*' && strcmp(p, service) != 0)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
 
-  /* read service */
+  /* read expiration */
   p = strtok_r(NULL, "|", &savep);
   if (p == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
     
-  if (p[0] != '*' && strcmp(p, service) != 0)
-    return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+  expiration = (time_t)atol(p);
+  if (expiration > 0 && now > expiration)
+    return gnutls_assert_val(GNUTLS_E_EXPIRED);
 
-  /* read service */
+  /* read key */
   kp = strtok_r(NULL, "|", &savep);
   if (kp == NULL)
     return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
@@ -180,7 +180,7 @@ size_t kp_len;
 
 /* Returns the base64 key if found 
  */
-static int find_stored_pubkey(const char* file, const char* application,
+static int find_stored_pubkey(const char* file, 
                              const char* host, const char* service, 
                              const gnutls_datum_t* skey)
 {
@@ -188,11 +188,11 @@ FILE* fd;
 char* line = NULL;
 size_t line_size = 0;
 int ret, l2, mismatch = 0;
-size_t application_len = 0, host_len = 0, service_len = 0;
+size_t host_len = 0, service_len = 0;
+time_t now = gnutls_time(0);
 
   if (host != NULL) host_len = strlen(host);
   if (service != NULL) service_len = strlen(service);
-  if (application != NULL) application_len = strlen(application);
 
   fd = fopen(file, "rb");
   if (fd == NULL)
@@ -203,8 +203,7 @@ size_t application_len = 0, host_len = 0, service_len = 0;
       l2 = getline(&line, &line_size, fd);
       if (l2 > 0)
         {
-          ret = parse_line(line, application, application_len,
-                          host, host_len, service, service_len, skey);
+          ret = parse_line(line, host, host_len, service, service_len, now, skey);
           if (ret == 0) /* found */
             {
               goto cleanup;
@@ -380,15 +379,16 @@ cleanup:
 /**
  * gnutls_store_pubkey:
  * @file: A file specifying the stored keys (use NULL for the default)
- * @application: non-NULL with an application name if this key is application-specific
  * @host: The peer's name
  * @service: non-NULL if this key is specific to a service (e.g. http)
  * @cert_type: The type of the certificate
  * @cert: The data of the certificate
+ * @expiration: The expiration time (use 0 to disable expiration)
  * @flags: should be 0.
  *
  * This function will store to verify the provided certificate to 
- * the list of stored public keys. 
+ * the list of stored public keys. The key will be considered valid until 
+ * the provided expiration time.
  *
  * Note that this function is not thread safe.
  *
@@ -399,11 +399,12 @@ cleanup:
  **/
 int
 gnutls_store_pubkey(const char* file, 
-                    const char* application,
                     const char* host,
                     const char* service,
                     gnutls_certificate_type_t cert_type,
-                    const gnutls_datum_t * cert, unsigned int flags)
+                    const gnutls_datum_t * cert, 
+                    time_t expiration,
+                    unsigned int flags)
 {
 FILE* fd = NULL;
 gnutls_datum_t pubkey = { NULL, 0 };
@@ -454,11 +455,11 @@ char local_file[MAX_FILENAME];
       goto cleanup;
     }
 
-  if (application == NULL) application = "*";
   if (service == NULL) service = "*";
   if (host == NULL) host = "*";
 
-  fprintf(fd, "|g0|%s|%s|%s|%.*s\n", application, host, service, pubkey.size, pubkey.data);
+  fprintf(fd, "|g0|%s|%s|%lu|%.*s\n", host, service, (unsigned long)expiration, 
+    pubkey.size, pubkey.data);
 
   ret = 0;