Procházet zdrojové kódy

Enable peer verification in set_ssl_option. Updated user manual for new config options.

Mateusz Gralka před 9 roky
rodič
revize
01c22c76d8
2 změnil soubory, kde provedl 31 přidání a 2 odebrání
  1. 10 1
      docs/UserManual.md
  2. 21 1
      src/civetweb.c

+ 10 - 1
docs/UserManual.md

@@ -386,6 +386,16 @@ See the [Wikipedia page on HTTP status codes](http://en.wikipedia.org/wiki/HTTP_
 URL encoded request strings are decoded in the server, unless it is disabled
 by setting this option to `no`.
 
+### ssl_verify_peer `no`
+Enable client's certificate verification by the server.
+
+### ssl_ca_path
+The name of a directory containing CA certificates. Each file in the directory
+must contain only a single CA certificate, and the files must be named by the
+subject name’s hash and an extension of “.0”. If there is more than one
+certificate with the same subject name they should have extensions ".0", ".1",
+".2" and so on.
+
 # Lua Scripts and Lua Server Pages
 Pre-built Windows and Mac civetweb binaries have built-in Lua scripting
 support as well as support for Lua Server Pages.
@@ -549,4 +559,3 @@ An example is shown in
 - Embedding with OpenSSL on Windows might fail because of calling convention.
   To force Civetweb to use `__stdcall` convention, add `/Gz` compilation
   flag in Visual Studio compiler.
-

+ 21 - 1
src/civetweb.c

@@ -811,6 +811,7 @@ typedef int socklen_t;
 typedef struct ssl_st SSL;
 typedef struct ssl_method_st SSL_METHOD;
 typedef struct ssl_ctx_st SSL_CTX;
+typedef struct x5099_store_ctx_st X509_STORE_CTX;
 
 struct ssl_func {
 	const char *name;  /* SSL function name */
@@ -842,6 +843,8 @@ struct ssl_func {
 #define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr)
 #define SSL_CTX_set_verify (*(void (*)(SSL_CTX *, int, int))ssl_sw[19].ptr)
 #define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr)
+#define SSL_CTX_load_verify_locations 										   \
+(*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[21].ptr)
 
 #define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr)
 #define CRYPTO_set_locking_callback                                            \
@@ -876,6 +879,7 @@ static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
                                    {"SSL_pending", NULL},
                                    {"SSL_CTX_set_verify", NULL},
                                    {"SSL_shutdown", NULL},
+								   {"SSL_CTX_load_verify_locations", NULL},
                                    {NULL, NULL}};
 
 /* Similar array as ssl_sw. These functions could be located in different
@@ -9876,7 +9880,8 @@ sslize(struct mg_connection *conn, SSL_CTX *s, int (*func)(SSL *))
 		return 0;
 	}
 
-	return (conn->ssl = SSL_new(s)) != NULL
+	conn->ssl = SSL_new(s);
+	return (conn->ssl != NULL)
 	       && SSL_set_fd(conn->ssl, conn->client.sock) == 1
 	       && func(conn->ssl) == 1;
 }
@@ -10008,6 +10013,8 @@ set_ssl_option(struct mg_context *ctx)
 {
 	const char *pem;
 	int callback_ret;
+	int should_verify_peer;
+	const char* ca_path;
 
 	/* If PEM file is not specified and the init_ssl callback
 	 * is not specified, skip SSL initialization. */
@@ -10072,6 +10079,19 @@ set_ssl_option(struct mg_context *ctx)
 		(void)SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem);
 	}
 
+	should_verify_peer = (ctx->config[SSL_VERIFY_PEER] != NULL)
+		&& (mg_strcasecmp(ctx->config[SSL_VERIFY_PEER], "yes") == 0);
+
+	if (should_verify_peer) {
+		ca_path = ctx->config[SSL_CA_PATH];
+		if ((ca_path != NULL
+		&& SSL_CTX_load_verify_locations(ctx->ssl_ctx, NULL, ca_path)) == 0) {
+			mg_cry(fc(ctx), "SSL_CTX_new (SSL_CTX_load_verify_locations) error: %s", ssl_error());
+			return 0;
+		}
+		SSL_CTX_set_verify(ctx->ssl_ctx, 3, 0);
+	}
+
 	return 1;
 }