static int _verify_response(gnutls_datum_t * data, gnutls_datum_t * nonce, gnutls_x509_crt_t signer) { gnutls_ocsp_resp_t resp; int ret; size_t size; gnutls_x509_crt_t *x509_ca_list = NULL; gnutls_x509_trust_list_t list; unsigned int x509_ncas = 0; unsigned verify; gnutls_datum_t dat; ret = gnutls_ocsp_resp_init(&resp); if (ret < 0) { fprintf(stderr, "ocsp_resp_init: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_ocsp_resp_import(resp, data); if (ret < 0) { fprintf(stderr, "importing response: %s\n", gnutls_strerror(ret)); exit(1); } if (nonce) { gnutls_datum_t rnonce; ret = gnutls_ocsp_resp_get_nonce(resp, NULL, &rnonce); if (ret < 0) { fprintf(stderr, "could not read response's nonce: %s\n", gnutls_strerror(ret)); exit(1); } if (rnonce.size != nonce->size || memcmp(nonce->data, rnonce.data, nonce->size) != 0) { fprintf(stderr, "nonce in the response doesn't match\n"); exit(1); } gnutls_free(rnonce.data); } if (HAVE_OPT(LOAD_TRUST)) { dat.data = (void *) read_binary_file(OPT_ARG(LOAD_TRUST), &size); if (dat.data == NULL) { fprintf(stderr, "reading --load-trust: %s\n", OPT_ARG(LOAD_TRUST)); exit(1); } dat.size = size; ret = gnutls_x509_trust_list_init(&list, 0); if (ret < 0) { fprintf(stderr, "gnutls_x509_trust_list_init: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_crt_list_import2(&x509_ca_list, &x509_ncas, &dat, GNUTLS_X509_FMT_PEM, 0); if (ret < 0 || x509_ncas < 1) { fprintf(stderr, "error parsing CAs: %s\n", gnutls_strerror(ret)); exit(1); } if (HAVE_OPT(VERBOSE)) { unsigned int i; printf("Trust anchors:\n"); for (i = 0; i < x509_ncas; i++) { gnutls_datum_t out; ret = gnutls_x509_crt_print(x509_ca_list[i], GNUTLS_CRT_PRINT_ONELINE, &out); if (ret < 0) { fprintf(stderr, "gnutls_x509_crt_print: %s\n", gnutls_strerror(ret)); exit(1); } printf("%d: %.*s\n", i, out.size, out.data); gnutls_free(out.data); } printf("\n"); } ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0); if (ret < 0) { fprintf(stderr, "gnutls_x509_trust_add_cas: %s\n", gnutls_strerror(ret)); exit(1); } if (HAVE_OPT(VERBOSE)) fprintf(stdout, "Loaded %d trust anchors\n", x509_ncas); ret = gnutls_ocsp_resp_verify(resp, list, &verify, 0); if (ret < 0) { fprintf(stderr, "gnutls_ocsp_resp_verify: %s\n", gnutls_strerror(ret)); exit(1); } } else if (signer) { if (HAVE_OPT(VERBOSE)) { gnutls_datum_t out; ret = gnutls_x509_crt_print(signer, GNUTLS_CRT_PRINT_ONELINE, &out); if (ret < 0) { fprintf(stderr, "gnutls_x509_crt_print: %s\n", gnutls_strerror(ret)); exit(1); } printf("Signer: %.*s\n", out.size, out.data); gnutls_free(out.data); printf("\n"); } ret = gnutls_ocsp_resp_verify_direct(resp, signer, &verify, 0); if (ret < 0) { fprintf(stderr, "gnutls_ocsp_resp_verify_direct: %s\n", gnutls_strerror(ret)); exit(1); } } else { fprintf(stderr, "missing --load-trust or --load-signer\n"); exit(1); } printf("Verifying OCSP Response: "); print_ocsp_verify_res(verify); printf(".\n"); gnutls_ocsp_resp_deinit(resp); return verify; }
static int _verify_response (gnutls_datum_t *data) { gnutls_ocsp_resp_t resp; int ret; size_t size; gnutls_x509_crt_t *x509_ca_list = NULL; unsigned int x509_ncas = 0; gnutls_x509_trust_list_t list; gnutls_x509_crt_t signer; unsigned verify; gnutls_datum_t dat; ret = gnutls_ocsp_resp_init (&resp); if (ret < 0) error (EXIT_FAILURE, 0, "ocsp_resp_init: %s", gnutls_strerror (ret)); ret = gnutls_ocsp_resp_import (resp, data); if (ret < 0) error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret)); if (HAVE_OPT(LOAD_TRUST)) { dat.data = (void*)read_binary_file (OPT_ARG(LOAD_TRUST), &size); if (dat.data == NULL) error (EXIT_FAILURE, errno, "reading --load-trust: %s", OPT_ARG(LOAD_TRUST)); dat.size = size; ret = gnutls_x509_trust_list_init (&list, 0); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s", gnutls_strerror (ret)); ret = gnutls_x509_crt_list_import2 (&x509_ca_list, &x509_ncas, &dat, GNUTLS_X509_FMT_PEM, 0); if (ret < 0 || x509_ncas < 1) error (EXIT_FAILURE, 0, "error parsing CAs: %s", gnutls_strerror (ret)); if (HAVE_OPT(VERBOSE)) { unsigned int i; printf ("Trust anchors:\n"); for (i = 0; i < x509_ncas; i++) { gnutls_datum_t out; ret = gnutls_x509_crt_print (x509_ca_list[i], GNUTLS_CRT_PRINT_ONELINE, &out); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s", gnutls_strerror (ret)); printf ("%d: %.*s\n", i, out.size, out.data); gnutls_free (out.data); } printf("\n"); } ret = gnutls_x509_trust_list_add_cas (list, x509_ca_list, x509_ncas, 0); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s", gnutls_strerror (ret)); if (HAVE_OPT(VERBOSE)) fprintf (stdout, "Loaded %d trust anchors\n", x509_ncas); ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify: %s", gnutls_strerror (ret)); } else if (HAVE_OPT(LOAD_SIGNER)) { ret = gnutls_x509_crt_init (&signer); if (ret < 0) error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret)); dat.data = (void*)read_binary_file (OPT_ARG(LOAD_SIGNER), &size); if (dat.data == NULL) error (EXIT_FAILURE, errno, "reading --load-signer: %s", OPT_ARG(LOAD_SIGNER)); dat.size = size; ret = gnutls_x509_crt_import (signer, &dat, encoding); free (dat.data); if (ret < 0) error (EXIT_FAILURE, 0, "importing --load-signer: %s: %s", OPT_ARG(LOAD_SIGNER), gnutls_strerror (ret)); if (HAVE_OPT(VERBOSE)) { gnutls_datum_t out; ret = gnutls_x509_crt_print (signer, GNUTLS_CRT_PRINT_ONELINE, &out); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s", gnutls_strerror (ret)); printf ("Signer: %.*s\n", out.size, out.data); gnutls_free (out.data); printf("\n"); } ret = gnutls_ocsp_resp_verify_direct (resp, signer, &verify, 0); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify_direct: %s", gnutls_strerror (ret)); } else error (EXIT_FAILURE, 0, "missing --load-trust or --load-signer"); printf ("Verifying OCSP Response: "); print_ocsp_verify_res (verify); printf (".\n"); gnutls_ocsp_resp_deinit (resp); return verify; }