2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
28 #include <gnutls/gnutls.h>
29 #include <gnutls/ocsp.h>
30 #include <gnutls/x509.h>
31 #include <gnutls/crypto.h>
33 /* Gnulib portability files. */
36 #include <version-etc.h>
37 #include <read-file.h>
40 #include <ocsptool-common.h>
41 #include <ocsptool-args.h>
45 static unsigned int encoding
;
46 unsigned int verbose
= 0;
49 tls_log_func (int level
, const char *str
)
51 fprintf (stderr
, "|<%d>| %s", level
, str
);
57 gnutls_ocsp_req_t req
;
62 ret
= gnutls_ocsp_req_init (&req
);
64 error (EXIT_FAILURE
, 0, "ocsp_req_init: %s", gnutls_strerror (ret
));
66 if (HAVE_OPT(LOAD_REQUEST
))
67 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_REQUEST
), &size
);
69 dat
.data
= (void*)fread_file (infile
, &size
);
71 error (EXIT_FAILURE
, errno
, "reading request");
74 ret
= gnutls_ocsp_req_import (req
, &dat
);
77 error (EXIT_FAILURE
, 0, "importing request: %s", gnutls_strerror (ret
));
79 ret
= gnutls_ocsp_req_print (req
, GNUTLS_OCSP_PRINT_FULL
, &dat
);
81 error (EXIT_FAILURE
, 0, "ocsp_req_print: %s", gnutls_strerror (ret
));
83 printf ("%.*s", dat
.size
, dat
.data
);
84 gnutls_free (dat
.data
);
86 gnutls_ocsp_req_deinit (req
);
90 _response_info (const gnutls_datum_t
* data
)
92 gnutls_ocsp_resp_t resp
;
96 ret
= gnutls_ocsp_resp_init (&resp
);
98 error (EXIT_FAILURE
, 0, "ocsp_resp_init: %s", gnutls_strerror (ret
));
100 ret
= gnutls_ocsp_resp_import (resp
, data
);
102 error (EXIT_FAILURE
, 0, "importing response: %s", gnutls_strerror (ret
));
104 if (ENABLED_OPT(VERBOSE
))
105 ret
= gnutls_ocsp_resp_print (resp
, GNUTLS_OCSP_PRINT_FULL
, &buf
);
107 ret
= gnutls_ocsp_resp_print (resp
, GNUTLS_OCSP_PRINT_COMPACT
, &buf
);
109 error (EXIT_FAILURE
, 0, "ocsp_resp_print: %s", gnutls_strerror (ret
));
111 printf ("%.*s", buf
.size
, buf
.data
);
112 gnutls_free (buf
.data
);
114 gnutls_ocsp_resp_deinit (resp
);
123 if (HAVE_OPT(LOAD_RESPONSE
))
124 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_RESPONSE
), &size
);
126 dat
.data
= (void*)fread_file (infile
, &size
);
127 if (dat
.data
== NULL
)
128 error (EXIT_FAILURE
, errno
, "reading response");
131 _response_info(&dat
);
132 gnutls_free (dat
.data
);
135 static gnutls_x509_crt_t
138 gnutls_x509_crt_t crt
;
143 if (!HAVE_OPT(LOAD_ISSUER
))
144 error (EXIT_FAILURE
, 0, "missing --load-issuer");
146 ret
= gnutls_x509_crt_init (&crt
);
148 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
150 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_ISSUER
), &size
);
154 error (EXIT_FAILURE
, errno
, "reading --load-issuer: %s", OPT_ARG(LOAD_ISSUER
));
156 ret
= gnutls_x509_crt_import (crt
, &dat
, encoding
);
159 error (EXIT_FAILURE
, 0, "importing --load-issuer: %s: %s",
160 OPT_ARG(LOAD_ISSUER
), gnutls_strerror (ret
));
165 static gnutls_x509_crt_t
168 gnutls_x509_crt_t crt
;
173 if (!HAVE_OPT(LOAD_CERT
))
174 error (EXIT_FAILURE
, 0, "missing --load-cert");
176 ret
= gnutls_x509_crt_init (&crt
);
178 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
180 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_CERT
), &size
);
184 error (EXIT_FAILURE
, errno
, "reading --load-cert: %s", OPT_ARG(LOAD_CERT
));
186 ret
= gnutls_x509_crt_import (crt
, &dat
, encoding
);
189 error (EXIT_FAILURE
, 0, "importing --load-cert: %s: %s",
190 OPT_ARG(LOAD_CERT
), gnutls_strerror (ret
));
196 generate_request (void)
200 _generate_request(load_cert(), load_issuer(), &dat
, ENABLED_OPT(NONCE
));
202 fwrite (dat
.data
, 1, dat
.size
, outfile
);
204 gnutls_free (dat
.data
);
209 _verify_response (gnutls_datum_t
*data
)
211 gnutls_ocsp_resp_t resp
;
214 gnutls_x509_crt_t
*x509_ca_list
= NULL
;
215 unsigned int x509_ncas
= 0;
216 gnutls_x509_trust_list_t list
;
217 gnutls_x509_crt_t signer
;
221 ret
= gnutls_ocsp_resp_init (&resp
);
223 error (EXIT_FAILURE
, 0, "ocsp_resp_init: %s", gnutls_strerror (ret
));
225 ret
= gnutls_ocsp_resp_import (resp
, data
);
227 error (EXIT_FAILURE
, 0, "importing response: %s", gnutls_strerror (ret
));
229 if (HAVE_OPT(LOAD_TRUST
))
231 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_TRUST
), &size
);
232 if (dat
.data
== NULL
)
233 error (EXIT_FAILURE
, errno
, "reading --load-trust: %s", OPT_ARG(LOAD_TRUST
));
236 ret
= gnutls_x509_trust_list_init (&list
, 0);
238 error (EXIT_FAILURE
, 0, "gnutls_x509_trust_list_init: %s",
239 gnutls_strerror (ret
));
241 ret
= gnutls_x509_crt_list_import2 (&x509_ca_list
, &x509_ncas
, &dat
,
242 GNUTLS_X509_FMT_PEM
, 0);
243 if (ret
< 0 || x509_ncas
< 1)
244 error (EXIT_FAILURE
, 0, "error parsing CAs: %s",
245 gnutls_strerror (ret
));
247 if (HAVE_OPT(VERBOSE
))
250 printf ("Trust anchors:\n");
251 for (i
= 0; i
< x509_ncas
; i
++)
255 ret
= gnutls_x509_crt_print (x509_ca_list
[i
],
256 GNUTLS_CRT_PRINT_ONELINE
, &out
);
258 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_print: %s",
259 gnutls_strerror (ret
));
261 printf ("%d: %.*s\n", i
, out
.size
, out
.data
);
262 gnutls_free (out
.data
);
267 ret
= gnutls_x509_trust_list_add_cas (list
, x509_ca_list
, x509_ncas
, 0);
269 error (EXIT_FAILURE
, 0, "gnutls_x509_trust_add_cas: %s",
270 gnutls_strerror (ret
));
272 if (HAVE_OPT(VERBOSE
))
273 fprintf (stdout
, "Loaded %d trust anchors\n", x509_ncas
);
275 ret
= gnutls_ocsp_resp_verify (resp
, list
, &verify
, 0);
277 error (EXIT_FAILURE
, 0, "gnutls_ocsp_resp_verify: %s",
278 gnutls_strerror (ret
));
280 else if (HAVE_OPT(LOAD_SIGNER
))
282 ret
= gnutls_x509_crt_init (&signer
);
284 error (EXIT_FAILURE
, 0, "crt_init: %s", gnutls_strerror (ret
));
286 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_SIGNER
), &size
);
287 if (dat
.data
== NULL
)
288 error (EXIT_FAILURE
, errno
, "reading --load-signer: %s", OPT_ARG(LOAD_SIGNER
));
291 ret
= gnutls_x509_crt_import (signer
, &dat
, encoding
);
294 error (EXIT_FAILURE
, 0, "importing --load-signer: %s: %s",
295 OPT_ARG(LOAD_SIGNER
), gnutls_strerror (ret
));
297 if (HAVE_OPT(VERBOSE
))
301 ret
= gnutls_x509_crt_print (signer
, GNUTLS_CRT_PRINT_ONELINE
, &out
);
303 error (EXIT_FAILURE
, 0, "gnutls_x509_crt_print: %s",
304 gnutls_strerror (ret
));
306 printf ("Signer: %.*s\n", out
.size
, out
.data
);
307 gnutls_free (out
.data
);
311 ret
= gnutls_ocsp_resp_verify_direct (resp
, signer
, &verify
, 0);
313 error (EXIT_FAILURE
, 0, "gnutls_ocsp_resp_verify_direct: %s",
314 gnutls_strerror (ret
));
317 error (EXIT_FAILURE
, 0, "missing --load-trust or --load-signer");
319 printf ("Verifying OCSP Response: ");
320 print_ocsp_verify_res (verify
);
323 gnutls_ocsp_resp_deinit (resp
);
329 verify_response (void)
334 if (HAVE_OPT(LOAD_RESPONSE
))
335 dat
.data
= (void*)read_binary_file (OPT_ARG(LOAD_RESPONSE
), &size
);
337 dat
.data
= (void*)fread_file (infile
, &size
);
338 if (dat
.data
== NULL
)
339 error (EXIT_FAILURE
, errno
, "reading response");
342 _verify_response(&dat
);
345 static void ask_server(const char* url
)
347 gnutls_datum_t resp_data
;
349 gnutls_x509_crt_t cert
, issuer
;
352 issuer
= load_issuer();
354 ret
= send_ocsp_request(url
, cert
, issuer
, &resp_data
, ENABLED_OPT(NONCE
));
357 fprintf(stderr
, "Cannot send OCSP request\n");
361 _response_info (&resp_data
);
363 if (HAVE_OPT(LOAD_SIGNER
) || HAVE_OPT(LOAD_TRUST
))
365 fprintf(outfile
, "\n");
366 v
= _verify_response(&resp_data
);
370 fprintf(stderr
, "\nResponse could not be verified (use --load-signer).\n");
374 if (HAVE_OPT(OUTFILE
) && v
== 0)
376 fwrite(resp_data
.data
, 1, resp_data
.size
, outfile
);
381 main (int argc
, char **argv
)
385 set_program_name (argv
[0]);
387 if ((ret
= gnutls_global_init ()) < 0)
388 error (EXIT_FAILURE
, 0, "global_init: %s", gnutls_strerror (ret
));
390 optionProcess( &ocsptoolOptions
, argc
, argv
);
392 gnutls_global_set_log_function (tls_log_func
);
393 gnutls_global_set_log_level (OPT_VALUE_DEBUG
);
395 if (HAVE_OPT(OUTFILE
))
397 outfile
= fopen (OPT_ARG(OUTFILE
), "wb");
399 error (EXIT_FAILURE
, errno
, "%s", OPT_ARG(OUTFILE
));
404 if (HAVE_OPT(INFILE
))
406 infile
= fopen (OPT_ARG(INFILE
), "rb");
408 error (EXIT_FAILURE
, errno
, "%s", OPT_ARG(INFILE
));
413 if (ENABLED_OPT(INDER
))
414 encoding
= GNUTLS_X509_FMT_DER
;
416 encoding
= GNUTLS_X509_FMT_PEM
;
418 if (HAVE_OPT(REQUEST_INFO
))
420 else if (HAVE_OPT(RESPONSE_INFO
))
422 else if (HAVE_OPT(GENERATE_REQUEST
))
424 else if (HAVE_OPT(VERIFY_RESPONSE
))
426 else if (HAVE_OPT(ASK
))
427 ask_server(OPT_ARG(ASK
));