Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/FreeDSx/Socket/HasSocketOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ trait HasSocketOptions

private bool $sslValidateCert = true;

private bool $sslCapturePeerCert = true;

private ?bool $sslVerifyPeerName = null;

private ?bool $sslAllowSelfSigned = null;
Expand Down Expand Up @@ -136,6 +138,23 @@ public function isSslValidateCert(): bool
return $this->sslValidateCert;
}

/**
* Whether to ask the handshake for the peer's certificate.
*
* Mostly to satisfy Swoole, which does not support this.
*/
public function setSslCapturePeerCert(bool $sslCapturePeerCert): self
{
$this->sslCapturePeerCert = $sslCapturePeerCert;

return $this;
}

public function isSslCapturePeerCert(): bool
{
return $this->sslCapturePeerCert;
}

/**
* Whether to verify the peer's name (hostname). Null follows the validate-cert setting.
*
Expand Down Expand Up @@ -301,12 +320,14 @@ public function toStreamContextSslOptions(): array
'allow_self_signed' => $this->sslAllowSelfSigned ?? false,
'verify_peer' => $this->sslValidateCert,
'verify_peer_name' => $this->sslVerifyPeerName ?? $this->sslValidateCert,
'capture_peer_cert' => true,
'capture_peer_cert_chain' => true,
'crypto_method' => $this->sslCryptoMethod,
'ciphers' => $this->sslCiphers,
];

if ($this->sslCapturePeerCert) {
$opts['capture_peer_cert'] = true;
}
if ($this->sslCaCert !== null) {
$opts['cafile'] = $this->sslCaCert;
}
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/SocketOptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ public function test_it_should_carry_the_validate_cert_flag_when_enabled(): void
self::assertFalse($ctx['allow_self_signed']);
}

public function test_it_should_capture_the_peer_cert_by_default(): void
{
$ctx = (new SocketOptions())->toStreamContextSslOptions();

self::assertTrue($ctx['capture_peer_cert']);
}

public function test_it_should_omit_the_peer_cert_capture_when_suppressed(): void
{
$ctx = (new SocketOptions())
->setSslCapturePeerCert(false)
->toStreamContextSslOptions();

self::assertArrayNotHasKey('capture_peer_cert', $ctx);
}

public function test_it_can_verify_the_peer_without_verifying_its_name(): void
{
$ctx = (new SocketOptions())
Expand Down
Loading