Skip to content

Commit 3754621

Browse files
authored
TlsContext: allow disabling verify peer name (#112)
1 parent 58e0422 commit 3754621

4 files changed

Lines changed: 126 additions & 2 deletions

File tree

src/ClientTlsContext.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ final class ClientTlsContext
2222

2323
private bool $verifyPeer = true;
2424

25+
private bool $verifyPeerName = true;
26+
2527
private int $verifyDepth = 10;
2628

2729
private ?array $peerFingerprint = null;
@@ -127,6 +129,8 @@ public function withoutPeerVerification(): self
127129
{
128130
$clone = clone $this;
129131
$clone->verifyPeer = false;
132+
// This is for compatibility with the former behaviour:
133+
$clone->verifyPeerName = false;
130134

131135
return $clone;
132136
}
@@ -139,6 +143,40 @@ public function hasPeerVerification(): bool
139143
return $this->verifyPeer;
140144
}
141145

146+
/**
147+
* Enable peer name verification, this is the default with verifyPeer enabled.
148+
*
149+
* @return self Cloned, modified instance.
150+
*/
151+
public function withPeerNameVerification(): self
152+
{
153+
$clone = clone $this;
154+
$clone->verifyPeerName = true;
155+
156+
return $clone;
157+
}
158+
159+
/**
160+
* Disable peer name verification.
161+
*
162+
* @return self Cloned, modified instance.
163+
*/
164+
public function withoutPeerNameVerification(): self
165+
{
166+
$clone = clone $this;
167+
$clone->verifyPeerName = false;
168+
169+
return $clone;
170+
}
171+
172+
/**
173+
* @return bool Whether peer verification is enabled.
174+
*/
175+
public function hasPeerNameVerification(): bool
176+
{
177+
return $this->verifyPeerName;
178+
}
179+
142180
/**
143181
* Maximum chain length the peer might present including the certificates in the local trust store.
144182
*
@@ -452,7 +490,7 @@ public function toStreamContextArray(): array
452490
'crypto_method' => $this->toStreamCryptoMethod(),
453491
'peer_name' => $this->peerName,
454492
'verify_peer' => $this->verifyPeer,
455-
'verify_peer_name' => $this->verifyPeer,
493+
'verify_peer_name' => $this->verifyPeerName,
456494
'verify_depth' => $this->verifyDepth,
457495
'ciphers' => $this->ciphers ?? \OPENSSL_DEFAULT_STREAM_CIPHERS,
458496
'capture_peer_cert' => $this->capturePeer,

src/ServerTlsContext.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public static function fromServerResource($socket): ?self
5858

5959
private bool $verifyPeer = false;
6060

61+
private bool $verifyPeerName = true;
62+
6163
private int $verifyDepth = 10;
6264

6365
private ?string $ciphers = null;
@@ -166,6 +168,40 @@ public function hasPeerVerification(): bool
166168
return $this->verifyPeer;
167169
}
168170

171+
/**
172+
* Enable peer name verification, this is the default with verifyPeer enabled.
173+
*
174+
* @return self Cloned, modified instance.
175+
*/
176+
public function withPeerNameVerification(): self
177+
{
178+
$clone = clone $this;
179+
$clone->verifyPeerName = true;
180+
181+
return $clone;
182+
}
183+
184+
/**
185+
* Disable peer name verification.
186+
*
187+
* @return self Cloned, modified instance.
188+
*/
189+
public function withoutPeerNameVerification(): self
190+
{
191+
$clone = clone $this;
192+
$clone->verifyPeerName = false;
193+
194+
return $clone;
195+
}
196+
197+
/**
198+
* @return bool Whether peer verification is enabled.
199+
*/
200+
public function hasPeerNameVerification(): bool
201+
{
202+
return $this->verifyPeer && $this->verifyPeerName;
203+
}
204+
169205
/**
170206
* Maximum chain length the peer might present including the certificates in the local trust store.
171207
*
@@ -437,7 +473,7 @@ public function toStreamContextArray(): array
437473
'crypto_method' => $this->toStreamCryptoMethod(),
438474
'peer_name' => $this->peerName,
439475
'verify_peer' => $this->verifyPeer,
440-
'verify_peer_name' => $this->verifyPeer,
476+
'verify_peer_name' => $this->verifyPeer && $this->verifyPeerName,
441477
'verify_depth' => $this->verifyDepth,
442478
'ciphers' => $this->ciphers ?? \OPENSSL_DEFAULT_STREAM_CIPHERS,
443479
'honor_cipher_order' => true,

test/ClientTlsContextTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,31 @@ public function testWithoutPeerVerification(): void
8585
self::assertFalse($clonedContext->hasPeerVerification());
8686
}
8787

88+
public function testDefaultPeerNameVerification(): void
89+
{
90+
$context = new ClientTlsContext;
91+
self::assertTrue($context->hasPeerNameVerification());
92+
}
93+
94+
public function testWithoutPeerNameVerification(): void
95+
{
96+
$context = new ClientTlsContext;
97+
$clonedContext = $context->withPeerVerification()->withoutPeerNameVerification();
98+
99+
self::assertTrue($clonedContext->hasPeerVerification());
100+
self::assertFalse($clonedContext->hasPeerNameVerification());
101+
}
102+
103+
public function testContextOptionsWithoutPeerNameVerification(): void
104+
{
105+
$context = new ClientTlsContext;
106+
$clonedContext = $context->withPeerVerification()->withoutPeerNameVerification();
107+
$options = $clonedContext->toStreamContextArray()['ssl'];
108+
109+
self::assertTrue($options['verify_peer']);
110+
self::assertFalse($options['verify_peer_name']);
111+
}
112+
88113
public function certificateDataProvider(): array
89114
{
90115
return [

test/ServerTlsContextTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,31 @@ public function testWithoutPeerVerification(): void
8585
self::assertFalse($clonedContext->hasPeerVerification());
8686
}
8787

88+
public function testDefaultPeerNameVerification(): void
89+
{
90+
$context = new ServerTlsContext;
91+
self::assertFalse($context->hasPeerNameVerification());
92+
}
93+
94+
public function testWithoutPeerNameVerification(): void
95+
{
96+
$context = new ServerTlsContext;
97+
$clonedContext = $context->withPeerVerification()->withoutPeerNameVerification();
98+
99+
self::assertTrue($clonedContext->hasPeerVerification());
100+
self::assertFalse($clonedContext->hasPeerNameVerification());
101+
}
102+
103+
public function testContextOptionsWithoutPeerNameVerification(): void
104+
{
105+
$context = new ServerTlsContext;
106+
$clonedContext = $context->withPeerVerification()->withoutPeerNameVerification();
107+
$options = $clonedContext->toStreamContextArray()['ssl'];
108+
109+
self::assertTrue($options['verify_peer']);
110+
self::assertFalse($options['verify_peer_name']);
111+
}
112+
88113
public function verifyDepthDataProvider(): array
89114
{
90115
return [

0 commit comments

Comments
 (0)