xref: /openbsd-src/regress/lib/libcrypto/ocsp/ocsp_test.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 #include <stdio.h>
2 #include <netdb.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <err.h>
6 #include <sys/socket.h>
7 
8 #include <openssl/ssl.h>
9 #include <openssl/ocsp.h>
10 
11 static int tcp_connect(char *host, char *port) {
12 	int error, sd = -1;
13 	struct addrinfo hints, *res, *r;
14 
15 	memset(&hints, 0, sizeof(struct addrinfo));
16 	hints.ai_family = AF_INET;
17 	hints.ai_socktype = SOCK_STREAM;
18 
19 	error = getaddrinfo(host, port, &hints, &res);
20 	if (error != 0) {
21 		perror("getaddrinfo()");
22 		exit(-1);
23 	}
24 
25 	for (r = res; r != NULL; r = r->ai_next) {
26 		sd = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
27 		if (sd == -1)
28 			continue;
29 
30 		if (connect(sd, r->ai_addr, r->ai_addrlen) == 0)
31 			break;
32 
33 		close(sd);
34 	}
35 
36 	freeaddrinfo(res);
37 
38 	return sd;
39 }
40 
41 int main(int argc, char *argv[]) {
42 	int sd, ocsp_status;
43 	const unsigned char *p;
44 	long len;
45 	OCSP_RESPONSE *rsp = NULL;
46 	OCSP_BASICRESP *br = NULL;
47 	X509_STORE     *st = NULL;
48 	STACK_OF(X509) *ch = NULL;
49 	char *host, *port;
50 #ifdef _PATH_SSL_CA_FILE
51 	char *cafile = _PATH_SSL_CA_FILE;
52 #else
53 	char *cafile = "/etc/ssl/cert.pem";
54 #endif
55 
56 	SSL *ssl;
57 	SSL_CTX *ctx;
58 
59 	SSL_library_init();
60 	SSL_load_error_strings();
61 
62 	ctx = SSL_CTX_new(SSLv23_client_method());
63 
64 	if (!SSL_CTX_load_verify_locations(ctx, cafile, NULL)) {
65 		printf("failed to load %s\n", cafile);
66 		exit(-1);
67 	}
68 
69 	if (argc != 3)
70 		errx(-1, "need a host and port to connect to");
71 	else {
72 		host = argv[1];
73 		port = argv[2];
74 	}
75 
76 	sd = tcp_connect(host, port);
77 
78 	ssl = SSL_new(ctx);
79 
80 	SSL_set_fd(ssl, (int) sd);
81 	SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
82 
83 	if (SSL_connect(ssl) <= 0) {
84 		printf("SSL connect error\n");
85 		exit(-1);
86 	}
87 
88 	if (SSL_get_verify_result(ssl) != X509_V_OK) {
89 		printf("Certificate doesn't verify from host %s port %s\n", host, port);
90 		exit(-1);
91 	}
92 
93 	/* ==== VERIFY OCSP RESPONSE ==== */
94 
95 
96 	len = SSL_get_tlsext_status_ocsp_resp(ssl, &p);
97 
98 	if (!p) {
99 		printf("No OCSP response received for %s port %s\n", host, port);
100 		exit(-1);
101 	}
102 
103 	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
104 	if (!rsp) {
105 		puts("Invalid OCSP response");
106 		exit(-1);
107 	}
108 
109 	ocsp_status = OCSP_response_status(rsp);
110 	if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
111 		printf("Invalid OCSP response status: %s (%d)",
112 		       OCSP_response_status_str(ocsp_status), ocsp_status);
113 		exit(-1);
114 	}
115 
116 	br = OCSP_response_get1_basic(rsp);
117 	if (!br) {
118 		puts("Invalid OCSP response");
119 		exit(-1);
120 	}
121 
122 	ch = SSL_get_peer_cert_chain(ssl);
123 	st = SSL_CTX_get_cert_store(ctx);
124 
125 	if (OCSP_basic_verify(br, ch, st, 0) <= 0) {
126 		puts("OCSP response verification failed");
127 		exit(-1);
128 	}
129 
130 	printf("OCSP validated from %s %s\n", host, port);
131 
132 	return 0;
133 }
134 
135