Crypt-Bear
view release on metacpan or search on metacpan
src/ssl/ssl_engine.c view on Meta::CPAN
* in the server-specific code, not here.
*/
rc->record_type_in = rc->ibuf[0];
version = br_dec16be(rc->ibuf + 1);
if ((version >> 8) != 3) {
br_ssl_engine_fail(rc, BR_ERR_UNSUPPORTED_VERSION);
return;
}
/*
* We ensure that successive records have the same
* version. The handshake code must check and adjust the
* variables when necessary to accommodate the protocol
* negotiation details.
*/
if (rc->version_in != 0 && rc->version_in != version) {
br_ssl_engine_fail(rc, BR_ERR_BAD_VERSION);
return;
}
rc->version_in = version;
/*
* Decode record length. We must check that the length
* is valid (relatively to the current encryption mode)
* and also (if encryption is active) that the record
* will fit in our buffer.
*
* When no encryption is active, we can process records
* by chunks, and thus accept any record up to the
* maximum allowed plaintext length (16384 bytes).
*/
rlen = br_dec16be(rc->ibuf + 3);
if (rc->incrypt) {
if (!rc->in.vtable->check_length(
&rc->in.vtable, rlen))
{
br_ssl_engine_fail(rc, BR_ERR_BAD_LENGTH);
return;
}
if (rlen > (rc->ibuf_len - 5)) {
br_ssl_engine_fail(rc, BR_ERR_TOO_LARGE);
return;
}
} else {
if (rlen > 16384) {
br_ssl_engine_fail(rc, BR_ERR_BAD_LENGTH);
return;
}
}
/*
* If the record is completely empty then we must switch
* to a new record. Note that, in that case, we
* completely ignore the record type, which is fitting
* since we received no actual data of that type.
*
* A completely empty record is technically allowed as
* long as encryption/MAC is not active, i.e. before
* completion of the first handshake. It it still weird;
* it might conceptually be useful as a heartbeat or
* keep-alive mechanism while some lengthy operation is
* going on, e.g. interaction with a human user.
*/
if (rlen == 0) {
make_ready_in(rc);
} else {
rc->ixa = rc->ixb = 5;
rc->ixc = rlen;
}
return;
}
/*
* If there is no active encryption, then the data can be read
* right away. Note that we do not receive bytes from the
* transport medium when we still have payload bytes to be
* acknowledged.
*/
if (!rc->incrypt) {
rc->ixa = 5;
return;
}
/*
* Since encryption is active, we must wait for a full record
* before processing it.
*/
if (rc->ixc != 0) {
return;
}
/*
* We got the full record. Decrypt it.
*/
pbuf_len = rc->ixa - 5;
pbuf = rc->in.vtable->decrypt(&rc->in.vtable,
rc->record_type_in, rc->version_in, rc->ibuf + 5, &pbuf_len);
if (pbuf == 0) {
br_ssl_engine_fail(rc, BR_ERR_BAD_MAC);
return;
}
rc->ixa = (size_t)(pbuf - rc->ibuf);
rc->ixb = rc->ixa + pbuf_len;
/*
* Decryption may have yielded an empty record, in which case
* we get back to "ready" state immediately.
*/
if (rc->ixa == rc->ixb) {
make_ready_in(rc);
}
}
/* see inner.h */
int
br_ssl_engine_recvrec_finished(const br_ssl_engine_context *rc)
{
switch (rc->iomode) {
case BR_IO_IN:
case BR_IO_INOUT:
return rc->ixc == 0 || rc->ixa < 5;
( run in 1.131 second using v1.01-cache-2.11-cpan-39bf76dae61 )