Skip to content

Commit c00d686

Browse files
committed
feature: add FFI interface to verify SSL client certificate
1 parent d987a0c commit c00d686

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

src/ngx_stream_lua_ssl_certby.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,4 +1317,104 @@ ngx_stream_lua_ffi_set_priv_key(ngx_stream_lua_request_t *r,
13171317
}
13181318

13191319

1320+
static int
1321+
ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
1322+
{
1323+
/*
1324+
* we never terminate handshake here and user can later use
1325+
* $ssl_client_verify to check verification result.
1326+
*
1327+
* this is consistent with Nginx behavior.
1328+
*/
1329+
return 1;
1330+
}
1331+
1332+
1333+
int
1334+
ngx_stream_lua_ffi_ssl_verify_client(ngx_stream_lua_request_t *r,
1335+
int depth,
1336+
void *cdata, char **err)
1337+
{
1338+
ngx_ssl_conn_t *ssl_conn;
1339+
STACK_OF(X509) *chain = cdata;
1340+
STACK_OF(X509_NAME) *name_chain = NULL;
1341+
X509 *x509 = NULL;
1342+
X509_NAME *subject = NULL;
1343+
X509_STORE *ca_store = NULL;
1344+
#ifdef OPENSSL_IS_BORINGSSL
1345+
size_t i;
1346+
#else
1347+
int i;
1348+
#endif
1349+
1350+
if (r->connection == NULL || r->connection->ssl == NULL) {
1351+
*err = "bad request";
1352+
return NGX_ERROR;
1353+
}
1354+
1355+
ssl_conn = r->connection->ssl->connection;
1356+
if (ssl_conn == NULL) {
1357+
*err = "bad ssl conn";
1358+
return NGX_ERROR;
1359+
}
1360+
1361+
ca_store = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(ssl_conn));
1362+
if (ca_store == NULL) {
1363+
*err = "SSL_CTX_get_cert_store() failed";
1364+
return NGX_ERROR;
1365+
}
1366+
1367+
SSL_set_verify(ssl_conn, SSL_VERIFY_PEER, ngx_ssl_verify_callback);
1368+
1369+
SSL_set_verify_depth(ssl_conn, depth);
1370+
1371+
if (chain != NULL) {
1372+
/* construct name chain */
1373+
1374+
name_chain = sk_X509_NAME_new_null();
1375+
if (name_chain == NULL) {
1376+
*err = "sk_X509_NAME_new_null() failed";
1377+
return NGX_ERROR;
1378+
}
1379+
1380+
for (i = 0; i < sk_X509_num(chain); i++) {
1381+
x509 = sk_X509_value(chain, i);
1382+
if (x509 == NULL) {
1383+
*err = "sk_X509_value() failed";
1384+
goto failed;
1385+
}
1386+
1387+
/* add subject to name chain, which will be sent to client */
1388+
subject = X509_NAME_dup(X509_get_subject_name(x509));
1389+
if (subject == NULL) {
1390+
*err = "X509_get_subject_name() failed";
1391+
goto failed;
1392+
}
1393+
1394+
if (!sk_X509_NAME_push(name_chain, subject)) {
1395+
*err = "sk_X509_NAME_push() failed";
1396+
X509_NAME_free(subject);
1397+
goto failed;
1398+
}
1399+
1400+
/* add to trusted CA store */
1401+
if (X509_STORE_add_cert(ca_store, x509) == 0) {
1402+
*err = "X509_STORE_add_cert() failed";
1403+
goto failed;
1404+
}
1405+
}
1406+
1407+
SSL_set_client_CA_list(ssl_conn, name_chain);
1408+
}
1409+
1410+
return NGX_OK;
1411+
1412+
failed:
1413+
1414+
sk_X509_NAME_free(name_chain);
1415+
1416+
return NGX_ERROR;
1417+
}
1418+
1419+
13201420
#endif /* NGX_STREAM_SSL */

0 commit comments

Comments
 (0)