cboden/Ratchet — pull request #66 by cballou (2013-01-03 13:04:58+00:00)
Title: RFC6455 Handshake verifier may fail under certain circumstances.

If a user has the PHP module `mbstring`, it's possible that it's ini
settings will erroneously mess up the `strlen()` calculation. A check
should be included in `verifyKey` to see if `mb_strlen` function exists,
and use that if so. RFC6455 defines all request/response payloads as being
in UTF-8, so we use that character encoding to avoid issues. I tested against
a variety of possible outcomes with only the UTF-8 encoded version of mb_strlen
functioning as intended:

```php
$this->log((string) $val); // 13
$this->log(base64_decode((string) $val)); // 13
$this->log('Key length: ' . strlen(base64_decode((string) $val))); // 13
$this->log('Key length 2: ' . mb_strlen(base64_decode((string) $val))); // 13
$this->log('Key length 3: ' . mb_strlen(base64_decode((string) $val), mb_internal_encoding())); // 13
$this->log('Key length 4: ' . mb_strlen(base64_decode((string) $val), 'ISO-8859-1')); // 16
$this->log('Key length 5: ' . mb_strlen(base64_decode((string) $val), 'UTF-8')); // 13
```

This bug is likely a pretty rare case, but it affected myself. In regards to
your documentation question on whether to simply check for a length of 24, I would say no,
as it isn't readily mentioned:

> The request MUST include a header field with the name
> |Sec-WebSocket-Key|. The value of this header field MUST be a
> nonce consisting of a randomly selected 16-byte value that has
> been base64-encoded (see Section 4 of [RFC4648]). The nonce
> MUST be selected randomly for each connection.

**Copied from http://tools.ietf.org/html/rfc6455#section-4.1**