From 6d59f5974548d661f95141831704bf0cb019f7f8 Mon Sep 17 00:00:00 2001
From: Andy Green <andy.green@linaro.org>
Date: Thu, 15 Oct 2015 09:12:58 +0800
Subject: [PATCH] LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED

Requested by Bruce Perens

http://ml.libwebsockets.org/pipermail/libwebsockets/2015-June/001834.html

Signed-off-by: Andy Green <andy.green@linaro.org>
---
 changelog           | 3 +++
 lib/libwebsockets.h | 1 +
 lib/ssl.c           | 8 ++++++--
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/changelog b/changelog
index 200e542a..0a9318b9 100644
--- a/changelog
+++ b/changelog
@@ -9,6 +9,9 @@ User api changes
 LWS_CALLBACK_CLIENT_CONNECTION_ERROR may provide an error string if in is
 non-NULL.  If so, the string has length len.
 
+LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED is available to relax the requirement
+for peer certs if you are using the option to require client certs.
+
 v1.4-chrome43-firefox36
 =======================
 
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 28986ff3..7fae18e8 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -177,6 +177,7 @@ enum libwebsocket_context_options {
 	LWS_SERVER_OPTION_LIBEV = 16,
 	LWS_SERVER_OPTION_DISABLE_IPV6 = 32,
 	LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = 64,
+	LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = 128,
 };
 
 enum libwebsocket_callback_reasons {
diff --git a/lib/ssl.c b/lib/ssl.c
index 1cb8c3d4..b033dbf3 100644
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -158,14 +158,18 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 	if (info->options &
 			LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
 		
+		int verify_options = SSL_VERIFY_PEER;
+	
+		if (!(info->options & LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
+			verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+		
 		SSL_CTX_set_session_id_context(context->ssl_ctx,
 				(unsigned char *)context, sizeof(void *));
 
 		/* absolutely require the client cert */
 
 		SSL_CTX_set_verify(context->ssl_ctx,
-		       SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
-						       OpenSSL_verify_callback);
+		       verify_options, OpenSSL_verify_callback);
 
 		/*
 		 * give user code a chance to load certs into the server
-- 
GitLab