From: Nikos Mavrogiannopoulos Date: Fri, 30 Aug 2002 18:17:51 +0000 (+0000) Subject: updated examples X-Git-Tag: gnutls_0_5_5~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9e315cf6678c3ac2aa49266ca8ebf4c7efbd5263;p=thirdparty%2Fgnutls.git updated examples --- diff --git a/doc/tex/Makefile.am b/doc/tex/Makefile.am index 985c9a62dc..08e35a69ff 100644 --- a/doc/tex/Makefile.am +++ b/doc/tex/Makefile.am @@ -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 index 0000000000..8d539abccb --- /dev/null +++ b/doc/tex/ex-rfc2818.tex @@ -0,0 +1,116 @@ +\begin{verbatim} + +/* This example was written by Andrew McDonald + * and is licensed under the GNU GPL license. + */ + +#include +#include +#include + +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} diff --git a/doc/tex/examples.tex b/doc/tex/examples.tex index 3877154aef..b3e32fa223 100644 --- a/doc/tex/examples.tex +++ b/doc/tex/examples.tex @@ -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