Added gnutls_certificate_verification_status_print().
[gnutls.git] / doc / examples / ex-verify-ssh.c
blob9251b78b231943cac83d6016d1c093397c77ab60
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, type;
26 gnutls_datum_t out;
27 const char *hostname;
29 /* read hostname */
30 hostname = gnutls_session_get_ptr (session);
32 /* This verification function uses the trusted CAs in the credentials
33 * structure. So you must have installed one or more CA certificates.
35 ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
36 if (ret < 0)
38 printf ("Error\n");
39 return GNUTLS_E_CERTIFICATE_ERROR;
42 type = gnutls_certificate_type_get (session);
44 ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
45 if (ret < 0)
47 printf ("Error\n");
48 return GNUTLS_E_CERTIFICATE_ERROR;
51 printf ("%s", out.data);
53 gnutls_free(out.data);
55 /* Do SSH verification */
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 type, &cert_list[0], 0);
66 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
68 printf("Host %s is not known.", hostname);
69 if (status == 0)
70 printf("Its certificate is valid for %s.\n", hostname);
72 /* the certificate must be printed and user must be asked on
73 * whether it is trustworthy. --see gnutls_x509_crt_print() */
75 /* if not trusted */
76 return GNUTLS_E_CERTIFICATE_ERROR;
78 else if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
80 printf("Warning: host %s is known but has another key associated.", hostname);
81 printf("It might be that the server has multiple keys, or you are under attack\n");
82 if (status == 0)
83 printf("Its certificate is valid for %s.\n", hostname);
85 /* the certificate must be printed and user must be asked on
86 * whether it is trustworthy. --see gnutls_x509_crt_print() */
88 /* if not trusted */
89 return GNUTLS_E_CERTIFICATE_ERROR;
91 else if (ret < 0)
93 printf("gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(ret));
94 return ret;
97 /* user trusts the key -> store it */
98 if (ret != 0)
100 ret = gnutls_store_pubkey(NULL, NULL, hostname, "https",
101 type, &cert_list[0], 0, 0);
102 if (ret < 0)
103 printf("gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
106 /* notify gnutls to continue handshake normally */
107 return 0;