Simplified certificate verification by adding gnutls_certificate_verify_peers3().
[gnutls.git] / doc / examples / ex-verify-ssh.c
blob28e09ac97e4d62453c9f8bb95ab105b0886acb87
1 /* This example code is placed in the public domain. */
3 #ifdef HAVE_CONFIG_H
4 #include <config.h>
5 #endif
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <gnutls/gnutls.h>
11 #include <gnutls/x509.h>
12 #include "examples.h"
14 /* This function will verify the peer's certificate, check
15 * if the hostname matches. In addition it will perform an
16 * SSH-style authentication, where ultimately trusted keys
17 * are only the keys that have been seen before.
19 int
20 _ssh_verify_certificate_callback (gnutls_session_t session)
22 unsigned int status;
23 const gnutls_datum_t *cert_list;
24 unsigned int cert_list_size;
25 int ret;
26 const char *hostname;
28 /* read hostname */
29 hostname = gnutls_session_get_ptr (session);
31 /* This verification function uses the trusted CAs in the credentials
32 * structure. So you must have installed one or more CA certificates.
34 ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
35 if (ret < 0)
37 printf ("Error\n");
38 return GNUTLS_E_CERTIFICATE_ERROR;
41 if (status & GNUTLS_CERT_INVALID)
42 printf ("The certificate is not trusted.\n");
44 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
45 printf ("The certificate hasn't got a known issuer.\n");
47 if (status & GNUTLS_CERT_REVOKED)
48 printf ("The certificate has been revoked.\n");
50 if (status & GNUTLS_CERT_EXPIRED)
51 printf ("The certificate has expired\n");
53 if (status & GNUTLS_CERT_NOT_ACTIVATED)
54 printf ("The certificate is not yet activated\n");
56 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
57 if (cert_list == NULL)
59 printf ("No certificate was found!\n");
60 return GNUTLS_E_CERTIFICATE_ERROR;
63 /* service may be obtained alternatively using getservbyport() */
64 ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "https",
65 gnutls_certificate_type_get (session),
66 &cert_list[0], 0);
67 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
69 printf("Host %s is not known.", hostname);
70 if (status == 0)
71 printf("Its certificate is valid for %s.\n", hostname);
73 /* the certificate must be printed and user must be asked on
74 * whether it is trustworthy. --see gnutls_x509_crt_print() */
76 /* if not trusted */
77 return GNUTLS_E_CERTIFICATE_ERROR;
79 else if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
81 printf("Warning: host %s is known but has another key associated.", hostname);
82 printf("It might be that the server has multiple keys, or you are under attack\n");
83 if (status == 0)
84 printf("Its certificate is valid for %s.\n", hostname);
86 /* the certificate must be printed and user must be asked on
87 * whether it is trustworthy. --see gnutls_x509_crt_print() */
89 /* if not trusted */
90 return GNUTLS_E_CERTIFICATE_ERROR;
92 else if (ret < 0)
94 printf("gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(ret));
95 return ret;
98 /* user trusts the key -> store it */
99 if (ret != 0)
101 ret = gnutls_store_pubkey(NULL, NULL, hostname, "https",
102 gnutls_certificate_type_get (session),
103 &cert_list[0], 0, 0);
104 if (ret < 0)
105 printf("gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
108 /* notify gnutls to continue handshake normally */
109 return 0;