Crypt-Bear
view release on metacpan or search on metacpan
src/ssl/ssl_hs_common.t0 view on Meta::CPAN
\ are pushed; that output length contains how many bytes could not be
\ read. If there is no available byte for reading, the address and
\ length are unchanged.
\ If the current record type is "handshake" then the read bytes are
\ injected in the multi-hasher.
cc: read-chunk-native ( addr len -- addr len ) {
size_t clen = ENG->hlen_in;
if (clen > 0) {
uint32_t addr, len;
len = T0_POP();
addr = T0_POP();
if ((size_t)len < clen) {
clen = (size_t)len;
}
memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen);
if (ENG->record_type_in == BR_SSL_HANDSHAKE) {
br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen);
}
T0_PUSH(addr + (uint32_t)clen);
T0_PUSH(len - (uint32_t)clen);
ENG->hbuf_in += clen;
ENG->hlen_in -= clen;
}
}
\ Process available alert bytes. If a fatal alert is received, then the
\ context is terminated; otherwise, this returns either true (-1) if a
\ close_notify was received, false (0) otherwise.
: process-alerts ( -- bool )
0
begin has-input? while read8-native process-alert-byte or repeat
dup if 1 addr-shutdown_recv set8 then ;
\ Process an alert byte. Returned value is non-zero if this is a close_notify,
\ zero otherwise.
: process-alert-byte ( x -- bool )
addr-alert get8 case
0 of
\ 'alert' field is 0, so this byte shall be a level.
\ Levels shall be 1 (warning) or 2 (fatal); we convert
\ all other values to "fatal".
dup 1 <> if drop 2 then
addr-alert set8 0
endof
1 of
0 addr-alert set8
\ close_notify has value 0.
\ no_renegotiation has value 100, and we treat it
\ as a fatal alert.
dup 100 = if 256 + fail then
0=
endof
\ Fatal alert implies context termination.
drop 256 + fail
endcase ;
\ In general we only deal with handshake data here. Alerts are processed
\ in specific code right when they are received, and ChangeCipherSpec has
\ its own handling code. So we need to check that the data is "handshake"
\ only when returning from a coroutine call.
\ Yield control to the engine. Alerts are processed; if incoming data is
\ neither handshake or alert, then an error is triggered.
: wait-for-handshake ( -- )
wait-co 0x07 and 0x01 > if ERR_UNEXPECTED fail then ;
\ Flush outgoing data (if any), then wait for the output buffer to be
\ clear; when this is done, set the output record type to the specified
\ value.
: wait-rectype-out ( rectype -- )
{ rectype }
flush-record
begin
can-output? if rectype addr-record_type_out set8 ret then
wait-co drop
again ;
\ Read one byte of handshake data. Block until that byte is available.
\ This does not check any length.
: read8-nc ( -- x )
begin
read8-native dup 0< ifnot ret then
drop wait-for-handshake
again ;
\ Test whether there are some more bytes in the current record. These
\ bytes have not necessarily been received yet (processing of unencrypted
\ records may begin before all bytes are received).
cc: more-incoming-bytes? ( -- bool ) {
T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG));
}
\ For reading functions, the TOS is supposed to contain the number of bytes
\ that can still be read (from encapsulating structure header), and it is
\ updated.
: check-len ( lim len -- lim )
- dup 0< if ERR_BAD_PARAM fail then ;
\ Read one byte of handshake data. This pushes an integer in the 0..255 range.
: read8 ( lim -- lim x )
1 check-len read8-nc ;
\ Read a 16-bit value (in the 0..65535 range)
: read16 ( lim -- lim n )
2 check-len read8-nc 8 << read8-nc + ;
\ Read a 24-bit value (in the 0..16777215 range)
: read24 ( lim -- lim n )
3 check-len read8-nc 8 << read8-nc + 8 << read8-nc + ;
\ Read some bytes. The "address" is an offset within the context
\ structure.
: read-blob ( lim addr len -- lim )
{ addr len }
len check-len
addr len
begin
read-chunk-native
dup 0 = if 2drop ret then
( run in 2.004 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )