Skip to content

Commit

Permalink
Use load_cafile for stream cafile loading
Browse files Browse the repository at this point in the history
dixyes committed Jan 23, 2024
1 parent 3e3c11c commit 31c66f2
Showing 2 changed files with 87 additions and 1 deletion.
85 changes: 84 additions & 1 deletion ext/src/swow_socket.c
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ static PHP_METHOD(Swow_Socket, open)
}

SWOW_THROW_ON_ERROR_START_EX(swow_socket_exception_ce) {
php_stream_from_zval_no_verify(stream, z_socket);
php_stream_from_zval_no_verify(stream, z_socket);
} SWOW_THROW_ON_ERROR_END();
if (stream == NULL) {
RETURN_THROWS();
@@ -576,6 +576,88 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swow_Socket_enableCrypto,
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null")
ZEND_END_ARG_INFO()

cat_bool_t swow_load_stream_cafile(cat_ssl_context_t *context, const char *cafile) {
php_stream *stream;
X509 *cert;
BIO *buffer;
int buffer_active = 0;
char *line = NULL;
size_t line_len;
long certs_added = 0;
X509_STORE *cert_store = SSL_CTX_get_cert_store(context->ctx);

// printf("load file %s\n", cafile);

stream = php_stream_open_wrapper(cafile, "rb", 0, NULL);

if (stream == NULL) {
php_error(E_WARNING, "failed loading cafile stream: `%s'", cafile);
return 0;
} else if (stream->wrapper->is_url) {
php_stream_close(stream);
php_error(E_WARNING, "remote cafile streams are disabled for security purposes");
return 0;
}

cert_start: {
line = php_stream_get_line(stream, NULL, 0, &line_len);
if (line == NULL) {
goto stream_complete;
} else if (!strcmp(line, "-----BEGIN CERTIFICATE-----\n") ||
!strcmp(line, "-----BEGIN CERTIFICATE-----\r\n")
) {
buffer = BIO_new(BIO_s_mem());
buffer_active = 1;
goto cert_line;
} else {
efree(line);
goto cert_start;
}
}

cert_line: {
BIO_puts(buffer, line);
efree(line);
line = php_stream_get_line(stream, NULL, 0, &line_len);
if (line == NULL) {
goto stream_complete;
} else if (!strcmp(line, "-----END CERTIFICATE-----") ||
!strcmp(line, "-----END CERTIFICATE-----\n") ||
!strcmp(line, "-----END CERTIFICATE-----\r\n")
) {
goto add_cert;
} else {
goto cert_line;
}
}

add_cert: {
BIO_puts(buffer, line);
efree(line);
cert = PEM_read_bio_X509(buffer, NULL, 0, NULL);
BIO_free(buffer);
buffer_active = 0;
if (cert && X509_STORE_add_cert(cert_store, cert)) {
++certs_added;
X509_free(cert);
}
goto cert_start;
}

stream_complete: {
php_stream_close(stream);
if (buffer_active == 1) {
BIO_free(buffer);
}
}

if (certs_added == 0) {
php_error(E_WARNING, "no valid certs found cafile stream: `%s'", cafile);
}

return certs_added > 0;
}

static PHP_METHOD(Swow_Socket, enableCrypto)
{
#ifdef CAT_SSL
@@ -592,6 +674,7 @@ static PHP_METHOD(Swow_Socket, enableCrypto)
ZEND_PARSE_PARAMETERS_END();

cat_socket_crypto_options_init(&options, is_client);
options.load_cafile = swow_load_stream_cafile;
if (options_array != NULL) {
swow_hash_str_fetch_bool(options_array, "verify_peer", &options.verify_peer);
swow_hash_str_fetch_bool(options_array, "verify_peer_name", &options.verify_peer_name);
3 changes: 3 additions & 0 deletions ext/src/swow_stream.c
Original file line number Diff line number Diff line change
@@ -744,6 +744,8 @@ static int swow_stream_setup_crypto(php_stream *stream,
return SUCCESS;
}

cat_bool_t swow_load_stream_cafile(cat_ssl_context_t *context, const char *cafile);

static int swow_stream_enable_crypto(php_stream *stream,
swow_netstream_data_t *swow_sock, php_netstream_data_t *sock, cat_socket_t *socket,
php_stream_xport_crypto_param *cparam)
@@ -756,6 +758,7 @@ static int swow_stream_enable_crypto(php_stream *stream,
zval *val;

cat_socket_crypto_options_init(&options, is_client);
options.load_cafile = swow_load_stream_cafile;
if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) {
options.verify_peer = cat_false;
}

0 comments on commit 31c66f2

Please sign in to comment.