forked from quic-go/quic-go
update mint, and adapt to the new use of the extension handler
This commit is contained in:
37
vendor/github.com/bifurcation/mint/record-layer.go
generated
vendored
37
vendor/github.com/bifurcation/mint/record-layer.go
generated
vendored
@@ -119,6 +119,15 @@ func (r *RecordLayer) Rekey(epoch Epoch, factory aeadFactory, key []byte, iv []b
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *cipherState) formatSeq(datagram bool) []byte {
|
||||
seq := append([]byte{}, c.seq...)
|
||||
if datagram {
|
||||
seq[0] = byte(c.epoch >> 8)
|
||||
seq[1] = byte(c.epoch & 0xff)
|
||||
}
|
||||
return seq
|
||||
}
|
||||
|
||||
func (c *cipherState) computeNonce(seq []byte) []byte {
|
||||
nonce := make([]byte, len(c.iv))
|
||||
copy(nonce, c.iv)
|
||||
@@ -143,9 +152,9 @@ func (c *cipherState) incrementSequenceNumber() {
|
||||
if i < 0 {
|
||||
// Not allowed to let sequence number wrap.
|
||||
// Instead, must renegotiate before it does.
|
||||
// Not likely enough to bothec.
|
||||
// Not likely enough to bother.
|
||||
// TODO(ekr@rtfm.com): Check for DTLS here
|
||||
// because the limit is soonec.
|
||||
// because the limit is sooner.
|
||||
panic("TLS: sequence number wraparound")
|
||||
}
|
||||
}
|
||||
@@ -157,7 +166,8 @@ func (c *cipherState) overhead() int {
|
||||
return c.cipher.Overhead()
|
||||
}
|
||||
|
||||
func (r *RecordLayer) encrypt(cipher *cipherState, pt *TLSPlaintext, padLen int) *TLSPlaintext {
|
||||
func (r *RecordLayer) encrypt(cipher *cipherState, seq []byte, pt *TLSPlaintext, padLen int) *TLSPlaintext {
|
||||
logf(logTypeIO, "Encrypt seq=[%x]", seq)
|
||||
// Expand the fragment to hold contentType, padding, and overhead
|
||||
originalLen := len(pt.fragment)
|
||||
plaintextLen := originalLen + 1 + padLen
|
||||
@@ -165,6 +175,7 @@ func (r *RecordLayer) encrypt(cipher *cipherState, pt *TLSPlaintext, padLen int)
|
||||
|
||||
// Assemble the revised plaintext
|
||||
out := &TLSPlaintext{
|
||||
|
||||
contentType: RecordTypeApplicationData,
|
||||
fragment: make([]byte, ciphertextLen),
|
||||
}
|
||||
@@ -176,11 +187,12 @@ func (r *RecordLayer) encrypt(cipher *cipherState, pt *TLSPlaintext, padLen int)
|
||||
|
||||
// Encrypt the fragment
|
||||
payload := out.fragment[:plaintextLen]
|
||||
cipher.cipher.Seal(payload[:0], cipher.computeNonce(cipher.seq), payload, nil)
|
||||
cipher.cipher.Seal(payload[:0], cipher.computeNonce(seq), payload, nil)
|
||||
return out
|
||||
}
|
||||
|
||||
func (r *RecordLayer) decrypt(pt *TLSPlaintext, seq []byte) (*TLSPlaintext, int, error) {
|
||||
logf(logTypeIO, "Decrypt seq=[%x]", seq)
|
||||
if len(pt.fragment) < r.cipher.overhead() {
|
||||
msg := fmt.Sprintf("tls.record.decrypt: Record too short [%d] < [%d]", len(pt.fragment), r.cipher.overhead())
|
||||
return nil, 0, DecryptError(msg)
|
||||
@@ -312,6 +324,8 @@ func (r *RecordLayer) nextRecord() (*TLSPlaintext, error) {
|
||||
if r.datagram {
|
||||
seq = header[3:11]
|
||||
}
|
||||
// TODO(ekr@rtfm.com): Handle the wrong epoch.
|
||||
// TODO(ekr@rtfm.com): Handle duplicates.
|
||||
logf(logTypeIO, "RecordLayer.ReadRecord epoch=[%s] seq=[%x] [%d] ciphertext=[%x]", cipher.epoch.label(), seq, pt.contentType, pt.fragment)
|
||||
pt, _, err = r.decrypt(pt, seq)
|
||||
if err != nil {
|
||||
@@ -341,9 +355,11 @@ func (r *RecordLayer) WriteRecordWithPadding(pt *TLSPlaintext, padLen int) error
|
||||
}
|
||||
|
||||
func (r *RecordLayer) writeRecordWithPadding(pt *TLSPlaintext, cipher *cipherState, padLen int) error {
|
||||
seq := cipher.formatSeq(r.datagram)
|
||||
|
||||
if cipher.cipher != nil {
|
||||
logf(logTypeIO, "RecordLayer.WriteRecord epoch=[%s] seq=[%x] [%d] plaintext=[%x]", cipher.epoch.label(), cipher.seq, pt.contentType, pt.fragment)
|
||||
pt = r.encrypt(cipher, pt, padLen)
|
||||
pt = r.encrypt(cipher, seq, pt, padLen)
|
||||
} else if padLen > 0 {
|
||||
return fmt.Errorf("tls.record: Padding can only be done on encrypted records")
|
||||
}
|
||||
@@ -354,16 +370,17 @@ func (r *RecordLayer) writeRecordWithPadding(pt *TLSPlaintext, cipher *cipherSta
|
||||
|
||||
length := len(pt.fragment)
|
||||
var header []byte
|
||||
|
||||
if !r.datagram {
|
||||
header = []byte{byte(pt.contentType),
|
||||
byte(r.version >> 8), byte(r.version & 0xff),
|
||||
byte(length >> 8), byte(length)}
|
||||
} else {
|
||||
// TODO(ekr@rtfm.com): Double check version
|
||||
seq := cipher.seq
|
||||
header = []byte{byte(pt.contentType), 0xfe, 0xff,
|
||||
0x00, 0x00, // TODO(ekr@rtfm.com): double-check epoch
|
||||
seq[2], seq[3], seq[4], seq[5], seq[6], seq[7],
|
||||
version := dtlsConvertVersion(r.version)
|
||||
header = []byte{byte(pt.contentType),
|
||||
byte(version >> 8), byte(version & 0xff),
|
||||
seq[0], seq[1], seq[2], seq[3],
|
||||
seq[4], seq[5], seq[6], seq[7],
|
||||
byte(length >> 8), byte(length)}
|
||||
}
|
||||
record := append(header, pt.fragment...)
|
||||
|
||||
Reference in New Issue
Block a user