]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
updated examples
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 30 Aug 2002 18:17:51 +0000 (18:17 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 30 Aug 2002 18:17:51 +0000 (18:17 +0000)
doc/tex/Makefile.am
doc/tex/ex-rfc2818.tex [new file with mode: 0644]
doc/tex/examples.tex

index 985c9a62dc82c88e5ad7f9b2cea45b0e36d4d372..08e35a69fffef79a82a7d93051a8f63c362961a2 100644 (file)
@@ -6,7 +6,8 @@ TEX_OBJECTS = gnutls.tex ../../lib/gnutls-api.tex serv1.tex ex1.tex ex2.tex ex3.
        macros.tex cover.tex ciphersuites.tex handshake.tex translayer.tex \
        auth.tex ciphers.tex errors.tex layers.tex alert.tex record.tex \
        funcs.tex examples.tex ex4.tex ../../libextra/gnutls-extra-api.tex \
-       memory.tex intro.tex openpgp.tex x509.tex howto.tex openssl.tex
+       memory.tex intro.tex openpgp.tex x509.tex howto.tex openssl.tex \
+       ex-rfc2818.tex
 
 gnutls.html: $(TEX_OBJECTS)            
        -latex2html gnutls.tex -no_navigation -split 0 \
diff --git a/doc/tex/ex-rfc2818.tex b/doc/tex/ex-rfc2818.tex
new file mode 100644 (file)
index 0000000..8d539ab
--- /dev/null
@@ -0,0 +1,116 @@
+\begin{verbatim}
+
+/* This example was written by Andrew McDonald <andrew@mcdonald.org.uk>
+ * and is licensed under the GNU GPL license.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+
+static int hostname_compare(const char *certname, const char *hostname);
+
+/* This function will check if the given certificate's subject matches
+ * the given hostname. This is an implementation of the matching described
+ * in RFC2818 (HTTPS).
+ */
+int check_certificates_hostname(const gnutls_datum * cert,
+                                const char *hostname)
+{
+
+   char dnsname[GNUTLS_X509_CN_SIZE];
+   int dnsnamesize;
+   int found_dnsname = 0;
+   int ret;
+   gnutls_DN dn;
+   int i = 0;
+
+   /* try matching against:
+    *  1) a DNS name as an alternative name (subjectAltName) extension
+    *     in the certificate
+    *  2) the common name (CN) in the certificate
+    *
+    *  either of these may be of the form: *.domain.tld
+    *
+    *  only try (2) if there is no subjectAltName extension of
+    *  type dNSName
+    */
+
+
+   /* Check through all included subjectAltName extensions, comparing
+    * against all those of type dNSName.
+    */
+   for (i = 0; !(ret < 0); i++) {
+
+      dnsnamesize = GNUTLS_X509_CN_SIZE;
+      ret =
+          gnutls_x509_extract_certificate_subject_alt_name(cert, i,
+                                                           dnsname,
+                                                           &dnsnamesize);
+
+      if (ret == GNUTLS_SAN_DNSNAME) {
+         found_dnsname = 1;
+         if (hostname_compare(dnsname, hostname)) {
+            return 1;
+         }
+      }
+
+   }
+
+   if (!found_dnsname) {
+      /* not got the necessary extension, use CN instead 
+       */
+      if (gnutls_x509_extract_certificate_dn(cert, &dn) != 0) {
+         /* got an error, can't find a name 
+          */
+         return 0;
+      }
+
+      if (hostname_compare(dn.common_name, hostname)) {
+         return 1;
+      }
+   }
+
+   /* not found a matching name
+    */
+   return 0;
+}
+
+/* compare hostname against certificate, taking account of wildcards
+ * return 1 on success or 0 on error 
+ */
+static int hostname_compare(const char *certname, const char *hostname)
+{
+   const char *cmpstr1, *cmpstr2;
+
+   if (strlen(certname) == 0 || strlen(hostname) == 0)
+      return 0;
+
+   if (strlen(certname) > 2 && strncmp(certname, "*.", 2) == 0) {
+      /* a wildcard certificate */
+
+      cmpstr1 = certname + 1;
+
+      /* find the first dot in hostname, compare from there on */
+      cmpstr2 = strchr(hostname, '.');
+
+      if (cmpstr2 == NULL) {
+         /* error, the hostname we're connecting to is only a local part */
+         return 0;
+      }
+
+      if (strcmp(cmpstr1, cmpstr2) == 0) {
+         return 1;
+      }
+
+      return 0;
+   }
+
+   if (strcmp(certname, hostname) == 0) {
+      return 1;
+   }
+
+   return 0;
+}
+
+\end{verbatim}
index 3877154aef136569f81a5249b1da1c41387cc965..b3e32fa223a71ee1163e7773f576b68442cc34bd 100644 (file)
@@ -21,6 +21,19 @@ This function should be called after a successful
 
 \input{ex3}
 
+\subsection{Verifying peer's hostname in a certificate}
+\par HTTPS clients have to verify not only the peer's certificate,
+but also the hostname in this certificate. That is to know that
+they actually connected to the right site.
+RFC2818 specifies some hostname checking algorithm, and this (a simple form)
+is implemented in the following example.
+
+\par
+This function should be called after a successful
+\printfunc{gnutls_certificate_verify_peers}{gnutls\_certificate\_verify\_peers}
+
+\input{ex-rfc2818}
+
 \subsection{Client with Resume capability example}
 \label{resume-example}
 This is the same client as above, but here we add support for session