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 )