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