Add a nasty little ocsp regress test in the hope pedants will make it better.
authorbeck <beck@openbsd.org>
Mon, 4 Jul 2016 23:43:30 +0000 (23:43 +0000)
committerbeck <beck@openbsd.org>
Mon, 4 Jul 2016 23:43:30 +0000 (23:43 +0000)
regress/lib/libcrypto/Makefile
regress/lib/libcrypto/ocsp/Makefile [new file with mode: 0644]
regress/lib/libcrypto/ocsp/ocsp_test.c [new file with mode: 0644]

index 4931d0f..a82ae25 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.22 2015/09/25 16:12:30 jsing Exp $
+#      $OpenBSD: Makefile,v 1.23 2016/07/04 23:43:30 beck Exp $
 
 SUBDIR= \
        aead \
@@ -27,6 +27,7 @@ SUBDIR= \
        ige \
        md4 \
        md5 \
+       ocsp \
        pbkdf2 \
        pkcs7 \
        poly1305 \
diff --git a/regress/lib/libcrypto/ocsp/Makefile b/regress/lib/libcrypto/ocsp/Makefile
new file mode 100644 (file)
index 0000000..5748b48
--- /dev/null
@@ -0,0 +1,21 @@
+#      $OpenBSD: Makefile,v 1.1 2016/07/04 23:43:30 beck Exp $
+
+TESTS = \
+       ocsp_test
+
+REGRESS_TARGETS= all_tests
+
+LDADD=         -lcrypto -lssl
+DPADD=         ${LIBCRYPTO} ${LIBSSL}
+WARNINGS=      Yes
+LDFLAGS+=      -lcrypto -lssl
+CFLAGS+=       -DLIBRESSL_INTERNAL -Wall -Wundef -Werror
+
+CLEANFILES+= ${TESTS}
+
+all_tests: ${TESTS}
+       @for test in $>; do \
+               ./$$test www.amazon.com 443; \
+       done
+
+.include <bsd.regress.mk>
diff --git a/regress/lib/libcrypto/ocsp/ocsp_test.c b/regress/lib/libcrypto/ocsp/ocsp_test.c
new file mode 100644 (file)
index 0000000..11dcda7
--- /dev/null
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include <openssl/ssl.h>
+#include <openssl/ocsp.h>
+
+static int tcp_connect(char *host, char *port) {
+       int err, sd = -1;
+       struct addrinfo hints, *res, *r;
+
+       memset(&hints, 0, sizeof(struct addrinfo));
+       hints.ai_family = AF_INET;
+       hints.ai_socktype = SOCK_STREAM;
+
+       err = getaddrinfo(host, port, &hints, &res);
+       if (err != 0) {
+               perror("getaddrinfo()");
+               exit(-1);
+       }
+
+       for (r = res; r != NULL; r = r->ai_next) {
+               sd = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+               if (sd == -1)
+                       continue;
+
+               if (connect(sd, r->ai_addr, r->ai_addrlen) == 0)
+                       break;
+
+               close(sd);
+       }
+
+       freeaddrinfo(res);
+
+       return sd;
+}
+
+int main(int argc, char *argv[]) {
+       int sd, ocsp_status;
+       const unsigned char *p;
+       long len;
+       OCSP_RESPONSE *rsp = NULL;
+       OCSP_BASICRESP *br = NULL;
+       X509_STORE     *st = NULL;
+       STACK_OF(X509) *ch = NULL;
+
+       SSL *ssl;
+       SSL_CTX *ctx;
+
+       SSL_library_init();
+       SSL_load_error_strings();
+
+       ctx = SSL_CTX_new(SSLv23_client_method());
+
+       SSL_CTX_load_verify_locations(ctx, "/etc/ssl/cert.pem", NULL);
+
+       sd = tcp_connect(argv[1], argv[2]);
+
+       ssl = SSL_new(ctx);
+
+       SSL_set_fd(ssl, (int) sd);
+       SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
+
+       if (SSL_connect(ssl) <= 0) {
+               puts("SSL connect error");
+               exit(-1);
+       }
+
+       if (SSL_get_verify_result(ssl) != X509_V_OK) {
+               puts("Certificate doesn't verify");
+               exit(-1);
+       }
+
+       /* ==== VERIFY OCSP RESPONSE ==== */
+
+
+       len = SSL_get_tlsext_status_ocsp_resp(ssl, &p);
+
+       if (!p) {
+               puts("No OCSP response received");
+               exit(-1);
+       }
+
+       rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+       if (!rsp) {
+               puts("Invalid OCSP response");
+               exit(-1);
+       }
+
+       ocsp_status = OCSP_response_status(rsp);
+       if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+               printf("Invalid OCSP response status: %s (%d)",
+                      OCSP_response_status_str(ocsp_status), ocsp_status);
+               exit(-1);
+       }
+
+       br = OCSP_response_get1_basic(rsp);
+       if (!br) {
+               puts("Invalid OCSP response");
+               exit(-1);
+       }
+
+       ch = SSL_get_peer_cert_chain(ssl);
+       st = SSL_CTX_get_cert_store(ctx);
+
+       if (OCSP_basic_verify(br, ch, st, 0) <= 0) {
+               puts("OCSP response verification failed");
+               exit(-1);
+       }
+
+       printf("OCSP validated from %s %s\n", argv[1], argv[2]);
+
+       return 0;
+}
+