Skip to content

Commit 7d1e8b5

Browse files
committed
Use enum instead of string for channel type
1 parent 28e5556 commit 7d1e8b5

9 files changed

Lines changed: 103 additions & 62 deletions

‎ext/openssl/openssl.c‎

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ ZEND_DECLARE_MODULE_GLOBALS(openssl)
5757

5858
zend_class_entry *php_openssl_exception_ce;
5959

60+
/* Openssl\ChannelBindingType enum */
61+
62+
static zend_class_entry *php_openssl_channel_binding_type_ce;
63+
6064
/* OpenSSLCertificate class */
6165

6266
zend_class_entry *php_openssl_certificate_ce;
@@ -757,6 +761,7 @@ PHP_INI_END()
757761
PHP_MINIT_FUNCTION(openssl)
758762
{
759763
php_openssl_exception_ce = register_class_Openssl_OpensslException(zend_ce_exception);
764+
php_openssl_channel_binding_type_ce = register_class_Openssl_ChannelBindingType();
760765

761766
php_openssl_certificate_ce = register_class_OpenSSLCertificate();
762767
php_openssl_certificate_ce->create_object = php_openssl_certificate_create_object;
@@ -5109,31 +5114,15 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
51095114
PHP_FUNCTION(openssl_get_channel_binding)
51105115
{
51115116
php_stream *stream = NULL;
5112-
zend_string *type = NULL;
5117+
zend_enum_Openssl_ChannelBindingType type;
51135118

51145119
ZEND_PARSE_PARAMETERS_START(2, 2)
51155120
PHP_Z_PARAM_STREAM(stream)
5116-
Z_PARAM_STR(type)
5121+
Z_PARAM_ENUM(type, php_openssl_channel_binding_type_ce)
51175122
ZEND_PARSE_PARAMETERS_END();
51185123

5119-
php_openssl_channel_binding_type type_code;
5120-
if (zend_string_equals_literal(type, "tls-unique")) {
5121-
type_code = PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_UNIQUE;
5122-
} else if (zend_string_equals_literal(type, "tls-server-end-point")) {
5123-
type_code = PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_SERVER_ENDPOINT;
5124-
} else if (zend_string_equals_literal(type, "tls-exporter")) {
5125-
type_code = PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_EXPORTER;
5126-
} else {
5127-
zend_value_error(
5128-
"%s(): argument #2 ($channel_binding_type) \"%s\" is not a known "
5129-
"channel binding type, expected \"tls-unique\", "
5130-
"\"tls-server-end-point\" or \"tls-exporter\"",
5131-
get_active_function_name(), ZSTR_VAL(type));
5132-
RETURN_THROWS();
5133-
}
5134-
51355124
zend_string *result = NULL;
5136-
php_openssl_channel_binding_result ret = php_openssl_netstream_get_channel_binding(stream, type_code, &result);
5125+
php_openssl_channel_binding_result ret = php_openssl_netstream_get_channel_binding(stream, type, &result);
51375126
switch (ret) {
51385127
case PHP_OPENSSL_CHANNEL_BINDING_RESULT_OK:
51395128
RETURN_STR(result);

‎ext/openssl/openssl.stub.php‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
<?php
22

3-
/** @generate-class-entries */
3+
/**
4+
* @generate-class-entries
5+
* @generate-c-enums
6+
*/
47

58
namespace Openssl {
69

710
class OpensslException extends Exception
811
{
912
}
1013

14+
/**
15+
* Channel binding type for openssl_get_channel_binding().
16+
* The backing values are the IANA "Channel Binding" registry names.
17+
*/
18+
enum ChannelBindingType: string {
19+
case TlsUnique = 'tls-unique';
20+
case TlsServerEndPoint = 'tls-server-end-point';
21+
case TlsExporter = 'tls-exporter';
22+
}
23+
1124
/**
1225
* @strict-properties
1326
*/
@@ -780,6 +793,6 @@ function openssl_password_verify(string $algo, #[\SensitiveParameter] string $pa
780793
* @param resource $stream
781794
* @refcount 1
782795
*/
783-
function openssl_get_channel_binding($stream, string $channel_binding_type): ?string {}
796+
function openssl_get_channel_binding($stream, Openssl\ChannelBindingType $channel_binding_type): ?string {}
784797

785798
}

‎ext/openssl/openssl_arginfo.h‎

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎ext/openssl/openssl_decl.h‎

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎ext/openssl/php_openssl.h‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ extern zend_module_entry openssl_module_entry;
2323
#include "php_version.h"
2424
#define PHP_OPENSSL_VERSION PHP_VERSION
2525

26+
#include "openssl_decl.h"
27+
2628
#include <openssl/opensslconf.h>
2729
#include <openssl/opensslv.h>
2830
/* OpenSSL version check */
@@ -224,16 +226,6 @@ typedef struct _php_openssl_session_object {
224226
zend_object std;
225227
} php_openssl_session_object;
226228

227-
/* Channel binding data types (RFC 5929, RFC 9266), as used for SASL
228-
* channel binding (e.g. SCRAM-SHA-*-PLUS, RFC 5802 / RFC 5801). The string
229-
* values accepted by openssl_get_channel_binding() are the IANA "Channel
230-
* Binding" registry names. */
231-
typedef enum php_openssl_channel_binding_type {
232-
PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_UNIQUE = 0,
233-
PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_SERVER_ENDPOINT,
234-
PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_EXPORTER,
235-
} php_openssl_channel_binding_type;
236-
237229
/* Result of php_openssl_netstream_get_channel_binding(). */
238230
typedef enum php_openssl_channel_binding_result {
239231
PHP_OPENSSL_CHANNEL_BINDING_RESULT_OK = 0, /* *out holds a zend_string with the data */
@@ -254,7 +246,7 @@ extern zend_class_entry *php_openssl_session_ce;
254246
void php_openssl_session_object_init(zval *zv, SSL_SESSION *session);
255247
bool php_openssl_is_session_ce(zval *val);
256248
SSL_SESSION *php_openssl_session_from_zval(zval *zv);
257-
php_openssl_channel_binding_result php_openssl_netstream_get_channel_binding(struct _php_stream *stream, php_openssl_channel_binding_type type, zend_string **out);
249+
php_openssl_channel_binding_result php_openssl_netstream_get_channel_binding(struct _php_stream *stream, zend_enum_Openssl_ChannelBindingType type, zend_string **out);
258250

259251
#if defined(HAVE_OPENSSL_ARGON2)
260252

‎ext/openssl/tests/openssl_get_channel_binding_errors.phpt‎

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,53 @@ openssl_get_channel_binding(): argument and type error handling
44
openssl
55
--FILE--
66
<?php
7-
/* Unknown channel binding type -> ValueError (checked before the stream). */
7+
/* The enum exposes the three IANA names as backing values. */
8+
foreach (Openssl\ChannelBindingType::cases() as $type) {
9+
echo $type->name, '=', $type->value, "\n";
10+
}
11+
12+
/* A string is not accepted; the parameter requires the enum. */
813
try {
9-
openssl_get_channel_binding(fopen("php://memory", "r"), "not-a-type");
14+
openssl_get_channel_binding(fopen("php://memory", "r"), "tls-unique");
1015
echo "no error\n";
1116
} catch (Throwable $e) {
1217
echo $e::class, ': ', $e->getMessage(), "\n";
1318
}
1419

15-
/* Case-sensitivity: a mismatched case is also unknown. */
20+
/* An unknown string is not accepted either. */
1621
try {
17-
openssl_get_channel_binding(fopen("php://memory", "r"), "TLS-UNIQUE");
22+
openssl_get_channel_binding(fopen("php://memory", "r"), "not-a-type");
1823
echo "no error\n";
1924
} catch (Throwable $e) {
2025
echo $e::class, ': ', $e->getMessage(), "\n";
2126
}
2227

2328
/* Non-stream argument -> TypeError. */
2429
try {
25-
openssl_get_channel_binding(123, "tls-unique");
30+
openssl_get_channel_binding(123, Openssl\ChannelBindingType::TlsUnique);
2631
echo "no error\n";
2732
} catch (Throwable $e) {
2833
echo $e::class, ': ', $e->getMessage(), "\n";
2934
}
3035

31-
/* A stream without transport encryption -> RuntimeException. */
36+
/* A stream without transport encryption -> Openssl\OpensslException. */
3237
$plain = fopen("php://memory", "r");
33-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
38+
foreach (Openssl\ChannelBindingType::cases() as $type) {
3439
try {
35-
openssl_get_channel_binding($plain, $t);
36-
echo "$t: no error\n";
40+
openssl_get_channel_binding($plain, $type);
41+
echo $type->value, ": no error\n";
3742
} catch (Throwable $e) {
38-
echo $t, ': ', $e::class, ': ', $e->getMessage(), "\n";
43+
echo $type->value, ': ', $e::class, ': ', $e->getMessage(), "\n";
3944
}
4045
}
4146
fclose($plain);
4247
?>
4348
--EXPECT--
44-
ValueError: openssl_get_channel_binding(): argument #2 ($channel_binding_type) "not-a-type" is not a known channel binding type, expected "tls-unique", "tls-server-end-point" or "tls-exporter"
45-
ValueError: openssl_get_channel_binding(): argument #2 ($channel_binding_type) "TLS-UNIQUE" is not a known channel binding type, expected "tls-unique", "tls-server-end-point" or "tls-exporter"
49+
TlsUnique=tls-unique
50+
TlsServerEndPoint=tls-server-end-point
51+
TlsExporter=tls-exporter
52+
TypeError: openssl_get_channel_binding(): Argument #2 ($channel_binding_type) must be of type Openssl\ChannelBindingType, string given
53+
TypeError: openssl_get_channel_binding(): Argument #2 ($channel_binding_type) must be of type Openssl\ChannelBindingType, string given
4654
TypeError: openssl_get_channel_binding(): Argument #1 ($stream) must be of type resource, int given
4755
tls-unique: Openssl\OpensslException: Stream does not have transport encryption enabled
4856
tls-server-end-point: Openssl\OpensslException: Stream does not have transport encryption enabled

‎ext/openssl/tests/openssl_get_channel_binding_tls12.phpt‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ $serverCode = <<<'CODE'
2929
echo "SERVER_EXCEPTION accept failed\n";
3030
exit(1);
3131
}
32-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
33-
$v = openssl_get_channel_binding($conn, $t);
34-
fwrite($conn, $t . "=" . (is_string($v) ? bin2hex($v) : "") . "\n");
32+
foreach (Openssl\ChannelBindingType::cases() as $type) {
33+
$v = openssl_get_channel_binding($conn, $type);
34+
fwrite($conn, $type->value . "=" . (is_string($v) ? bin2hex($v) : "") . "\n");
3535
}
3636
phpt_wait();
3737
fclose($conn);
@@ -55,8 +55,8 @@ $clientCode = <<<'CODE'
5555
}
5656
5757
$my = [];
58-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
59-
$my[$t] = openssl_get_channel_binding($client, $t);
58+
foreach (Openssl\ChannelBindingType::cases() as $type) {
59+
$my[$type->value] = openssl_get_channel_binding($client, $type);
6060
}
6161
6262
$peer = [];
@@ -70,7 +70,8 @@ $clientCode = <<<'CODE'
7070
$peer[$t] = ($enc === "") ? null : hex2bin($enc);
7171
}
7272
73-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
73+
foreach (Openssl\ChannelBindingType::cases() as $type) {
74+
$t = $type->value;
7475
$c = $my[$t];
7576
$s = $peer[$t];
7677
$lc = is_string($c) ? strlen($c) : "null";

‎ext/openssl/tests/openssl_get_channel_binding_tls13.phpt‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ $serverCode = <<<'CODE'
2727
echo "SERVER_EXCEPTION accept failed\n";
2828
exit(1);
2929
}
30-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
31-
$v = openssl_get_channel_binding($conn, $t);
32-
fwrite($conn, $t . "=" . (is_string($v) ? bin2hex($v) : "") . "\n");
30+
foreach (Openssl\ChannelBindingType::cases() as $type) {
31+
$v = openssl_get_channel_binding($conn, $type);
32+
fwrite($conn, $type->value . "=" . (is_string($v) ? bin2hex($v) : "") . "\n");
3333
}
3434
phpt_wait();
3535
fclose($conn);
@@ -50,8 +50,8 @@ $clientCode = <<<'CODE'
5050
}
5151
5252
$my = [];
53-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
54-
$my[$t] = openssl_get_channel_binding($client, $t);
53+
foreach (Openssl\ChannelBindingType::cases() as $type) {
54+
$my[$type->value] = openssl_get_channel_binding($client, $type);
5555
}
5656
5757
$peer = [];
@@ -65,7 +65,8 @@ $clientCode = <<<'CODE'
6565
$peer[$t] = ($enc === "") ? null : hex2bin($enc);
6666
}
6767
68-
foreach (["tls-unique", "tls-server-end-point", "tls-exporter"] as $t) {
68+
foreach (Openssl\ChannelBindingType::cases() as $type) {
69+
$t = $type->value;
6970
$c = $my[$t];
7071
$s = $peer[$t];
7172
$lc = is_string($c) ? strlen($c) : "null";

‎ext/openssl/xp_ssl.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3976,7 +3976,7 @@ static int php_openssl_get_cert_signature_md_nid(const X509 *cert) /* {{{ */
39763976
* PHP_OPENSSL_CHANNEL_BINDING_RESULT_ERROR is returned; in both of these cases *out is set to NULL.
39773977
*/
39783978
php_openssl_channel_binding_result php_openssl_netstream_get_channel_binding( /* {{{ */
3979-
php_stream *stream, php_openssl_channel_binding_type type, zend_string **out)
3979+
php_stream *stream, zend_enum_Openssl_ChannelBindingType type, zend_string **out)
39803980
{
39813981
unsigned char buf[EVP_MAX_MD_SIZE];
39823982
size_t len = 0;
@@ -3995,7 +3995,7 @@ php_openssl_channel_binding_result php_openssl_netstream_get_channel_binding( /*
39953995
ssl = sslsock->ssl_handle;
39963996

39973997
switch (type) {
3998-
case PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_UNIQUE:
3998+
case ZEND_ENUM_Openssl_ChannelBindingType_TlsUnique:
39993999
/* RFC 5929 section 3: tls-unique is not defined for TLS 1.3. */
40004000
if (SSL_version(ssl) >= TLS1_3_VERSION) {
40014001
return PHP_OPENSSL_CHANNEL_BINDING_RESULT_NOT_APPLICABLE;
@@ -4020,7 +4020,7 @@ php_openssl_channel_binding_result php_openssl_netstream_get_channel_binding( /*
40204020
*out = zend_string_init((char *)buf, len, 0);
40214021
return *out != NULL ? PHP_OPENSSL_CHANNEL_BINDING_RESULT_OK : PHP_OPENSSL_CHANNEL_BINDING_RESULT_ERROR;
40224022

4023-
case PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_SERVER_ENDPOINT:
4023+
case ZEND_ENUM_Openssl_ChannelBindingType_TlsServerEndPoint:
40244024
{
40254025
X509 *cert = sslsock->is_client ?
40264026
SSL_get_peer_certificate(ssl) : SSL_get_certificate(ssl);
@@ -4062,7 +4062,7 @@ php_openssl_channel_binding_result php_openssl_netstream_get_channel_binding( /*
40624062
return *out != NULL ? PHP_OPENSSL_CHANNEL_BINDING_RESULT_OK : PHP_OPENSSL_CHANNEL_BINDING_RESULT_ERROR;
40634063
}
40644064

4065-
case PHP_OPENSSL_CHANNEL_BINDING_TYPE_TLS_EXPORTER:
4065+
case ZEND_ENUM_Openssl_ChannelBindingType_TlsExporter:
40664066
/*
40674067
* RFC 9266 section 4 / RFC 5705: 32 octets, label
40684068
* "EXPORTER-Channel-Binding", empty context. For an empty context the

0 commit comments

Comments
 (0)