Improved PKCS7 support
[gnutls.git] / doc / tex / ex1.tex
blob83bfa5e19ce75a1cd7e5b0a113ef26cdac4b52e3
1 \subsection{Client with Resume capability example}
2 \label{resume-example}
3 \begin{verbatim}
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
11 #include <gnutls.h>
13 #define MAX_BUF 1024
14 #define CRLFILE "crl.pem"
15 #define CAFILE "ca.pem"
16 #define SA struct sockaddr
17 #define MSG "GET / HTTP/1.0\r\n\r\n"
19 const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
20 const int kx_priority[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
21 const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
22 const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
23 const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
25 int main()
27 const char *PORT = "443";
28 const char *SERVER = "127.0.0.1";
29 int err, ret;
30 int sd, ii, alert;
31 struct sockaddr_in sa;
32 GNUTLS_STATE state;
33 char buffer[MAX_BUF + 1];
34 GNUTLS_CERTIFICATE_CLIENT_CREDENTIALS xcred;
35 /* variables used in session resuming */
36 int t;
37 char *session;
38 char *session_id;
39 int session_size;
40 int session_id_size;
41 char *tmp_session_id;
42 int tmp_session_id_size;
44 if (gnutls_global_init() < 0) {
45 fprintf(stderr, "global state initialization error\n");
46 exit(1);
48 /* X509 stuff */
49 if (gnutls_certificate_allocate_client_sc(&xcred) < 0) {
50 fprintf(stderr, "memory error\n");
51 exit(1);
53 gnutls_certificate_set_x509_trust_file(xcred, CAFILE, CRLFILE, GNUTLS_X509_FMT_PEM);
55 for (t = 0; t < 2; t++) { /* connect 2 times to the server */
57 sd = socket(AF_INET, SOCK_STREAM, 0);
58 memset(&sa, '\0', sizeof(sa));
59 sa.sin_family = AF_INET;
60 sa.sin_port = htons(atoi(PORT));
61 inet_pton(AF_INET, SERVER, &sa.sin_addr);
63 err = connect(sd, (SA *) & sa, sizeof(sa));
64 if (err < 0) {
65 fprintf(stderr, "Connect error");
66 exit(1);
68 gnutls_init(&state, GNUTLS_CLIENT);
70 gnutls_protocol_set_priority(state, protocol_priority);
71 gnutls_cipher_set_priority(state, cipher_priority);
72 gnutls_compression_set_priority(state, comp_priority);
73 gnutls_kx_set_priority(state, kx_priority);
74 gnutls_mac_set_priority(state, mac_priority);
76 gnutls_cred_set(state, GNUTLS_CRD_CERTIFICATE, xcred);
78 if (t > 0) { /* if this is not the first time we connect */
79 gnutls_session_set_data(state, session, session_size);
80 free(session);
83 gnutls_transport_set_ptr( state, sd);
85 /* Perform the TLS handshake
87 ret = gnutls_handshake( state);
89 if (ret < 0) {
90 fprintf(stderr, "*** Handshake failed\n");
91 gnutls_perror(ret);
92 goto end;
93 } else {
94 printf("- Handshake was completed\n");
97 if (t == 0) { /* the first time we connect */
98 /* get the session data size */
99 gnutls_session_get_data(state, NULL, &session_size);
100 session = malloc(session_size);
102 /* put session data to the session variable */
103 gnutls_session_get_data(state, session, &session_size);
105 /* keep the current session ID. This is only needed
106 * in order to check if the server actually resumed this
107 * connection.
109 gnutls_session_get_id(state, NULL, &session_id_size);
110 session_id = malloc(session_id_size);
111 gnutls_session_get_id(state, session_id, &session_id_size);
113 } else { /* the second time we connect */
115 /* check if we actually resumed the previous session */
116 gnutls_session_get_id(state, NULL, &tmp_session_id_size);
117 tmp_session_id = malloc(tmp_session_id_size);
118 gnutls_session_get_id(state, tmp_session_id, &tmp_session_id_size);
120 if (memcmp(tmp_session_id, session_id, session_id_size) == 0) {
121 printf("- Previous session was resumed\n");
122 } else {
123 fprintf(stderr, "*** Previous session was NOT resumed\n");
125 free(tmp_session_id);
126 free(session_id);
129 /* This function was defined in a previous example
131 print_info(state);
133 gnutls_record_send( state, MSG, strlen(MSG));
135 ret = gnutls_record_recv( state, buffer, MAX_BUF);
136 if (gnutls_error_is_fatal(ret) == 1 || ret == 0) {
137 if (ret == 0) {
138 printf("- Peer has closed the GNUTLS connection\n");
139 goto end;
140 } else {
141 fprintf(stderr, "*** Received corrupted data(%d) - server has terminated the connection abnormally\n",
142 ret);
143 goto end;
145 } else {
146 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
147 alert = gnutls_alert_get(state);
148 printf("* Received alert [%d]: %s\n", alert, gnutls_alert_get_name(alert));
149 if (ret == GNUTLS_E_REHANDSHAKE) {
150 printf("* Received HelloRequest message (server asked to rehandshake)\n");
151 gnutls_alert_send_appropriate( state, ret); /* we don't want rehandshake */
155 if (ret > 0) {
156 printf("- Received %d bytes: ", ret);
157 for (ii = 0; ii < ret; ii++) {
158 fputc(buffer[ii], stdout);
160 fputs("\n", stdout);
162 gnutls_bye( state, GNUTLS_SHUT_RDWR);
164 end:
166 shutdown(sd, SHUT_RDWR); /* no more receptions */
167 close(sd);
169 gnutls_deinit(state);
171 } /* for() */
173 gnutls_certificate_free_client_sc(xcred);
175 gnutls_global_deinit();
177 return 0;
180 \end{verbatim}