in src/tlsconnection.js [95:135]
async recv(data) {
assertIsBytes(data);
return await this._synchronized(async () => {
// Decrypt the data using the record layer.
// We expect to receive precisely one record at a time.
const [type, bytes] = await this._recordlayer.recv(data);
// Dispatch based on the type of the record.
switch (type) {
case RECORD_TYPE.CHANGE_CIPHER_SPEC:
await this._state.recvChangeCipherSpec(bytes);
return null;
case RECORD_TYPE.ALERT:
await this._state.recvAlertMessage(TLSAlert.fromBytes(bytes));
return null;
case RECORD_TYPE.APPLICATION_DATA:
return await this._state.recvApplicationData(bytes);
case RECORD_TYPE.HANDSHAKE:
// Multiple handshake messages may be coalesced into a single record.
// Store the in-progress record buffer on `this` so that we can guard
// against handshake messages that span a change in keys.
this._handshakeRecvBuffer = new BufferReader(bytes);
if (! this._handshakeRecvBuffer.hasMoreBytes()) {
throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
}
do {
// Each handshake messages has a type and length prefix, per
// https://tools.ietf.org/html/rfc8446#appendix-B.3
this._handshakeRecvBuffer.incr(1);
const mlength = this._handshakeRecvBuffer.readUint24();
this._handshakeRecvBuffer.incr(-4);
const messageBytes = this._handshakeRecvBuffer.readBytes(mlength + 4);
this._keyschedule.addToTranscript(messageBytes);
await this._state.recvHandshakeMessage(HandshakeMessage.fromBytes(messageBytes));
} while (this._handshakeRecvBuffer.hasMoreBytes());
this._handshakeRecvBuffer = null;
return null;
default:
throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
}
});
}