summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/tls/record_write.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/crypto/tls/record_write.go')
-rw-r--r--src/pkg/crypto/tls/record_write.go170
1 files changed, 0 insertions, 170 deletions
diff --git a/src/pkg/crypto/tls/record_write.go b/src/pkg/crypto/tls/record_write.go
deleted file mode 100644
index 5f3fb5b16..000000000
--- a/src/pkg/crypto/tls/record_write.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
- "fmt"
- "hash"
- "io"
-)
-
-// writerEnableApplicationData is a message which instructs recordWriter to
-// start reading and transmitting data from the application data channel.
-type writerEnableApplicationData struct{}
-
-// writerChangeCipherSpec updates the encryption and MAC functions and resets
-// the sequence count.
-type writerChangeCipherSpec struct {
- encryptor encryptor
- mac hash.Hash
-}
-
-// writerSetVersion sets the version number bytes that we included in the
-// record header for future records.
-type writerSetVersion struct {
- major, minor uint8
-}
-
-// A recordWriter accepts messages from the handshake processor and
-// application data. It writes them to the outgoing connection and blocks on
-// writing. It doesn't read from the application data channel until the
-// handshake processor has signaled that the handshake is complete.
-type recordWriter struct {
- writer io.Writer
- encryptor encryptor
- mac hash.Hash
- seqNum uint64
- major, minor uint8
- shutdown bool
- appChan <-chan []byte
- controlChan <-chan interface{}
- header [13]byte
-}
-
-func (w *recordWriter) loop(writer io.Writer, appChan <-chan []byte, controlChan <-chan interface{}) {
- w.writer = writer
- w.encryptor = nop{}
- w.mac = nop{}
- w.appChan = appChan
- w.controlChan = controlChan
-
- for !w.shutdown {
- msg := <-controlChan
- if _, ok := msg.(writerEnableApplicationData); ok {
- break
- }
- w.processControlMessage(msg)
- }
-
- for !w.shutdown {
- // Always process control messages first.
- if controlMsg, ok := <-controlChan; ok {
- w.processControlMessage(controlMsg)
- continue
- }
-
- select {
- case controlMsg := <-controlChan:
- w.processControlMessage(controlMsg)
- case appMsg := <-appChan:
- w.processAppMessage(appMsg)
- }
- }
-
- if !closed(appChan) {
- go func() {
- for _ = range appChan {
- }
- }()
- }
- if !closed(controlChan) {
- go func() {
- for _ = range controlChan {
- }
- }()
- }
-}
-
-// fillMACHeader generates a MAC header. See RFC 4346, section 6.2.3.1.
-func fillMACHeader(header *[13]byte, seqNum uint64, length int, r *record) {
- header[0] = uint8(seqNum >> 56)
- header[1] = uint8(seqNum >> 48)
- header[2] = uint8(seqNum >> 40)
- header[3] = uint8(seqNum >> 32)
- header[4] = uint8(seqNum >> 24)
- header[5] = uint8(seqNum >> 16)
- header[6] = uint8(seqNum >> 8)
- header[7] = uint8(seqNum)
- header[8] = uint8(r.contentType)
- header[9] = r.major
- header[10] = r.minor
- header[11] = uint8(length >> 8)
- header[12] = uint8(length)
-}
-
-func (w *recordWriter) writeRecord(r *record) {
- w.mac.Reset()
-
- fillMACHeader(&w.header, w.seqNum, len(r.payload), r)
-
- w.mac.Write(w.header[0:13])
- w.mac.Write(r.payload)
- macBytes := w.mac.Sum()
-
- w.encryptor.XORKeyStream(r.payload)
- w.encryptor.XORKeyStream(macBytes)
-
- length := len(r.payload) + len(macBytes)
- w.header[11] = uint8(length >> 8)
- w.header[12] = uint8(length)
- w.writer.Write(w.header[8:13])
- w.writer.Write(r.payload)
- w.writer.Write(macBytes)
-
- w.seqNum++
-}
-
-func (w *recordWriter) processControlMessage(controlMsg interface{}) {
- if controlMsg == nil {
- w.shutdown = true
- return
- }
-
- switch msg := controlMsg.(type) {
- case writerChangeCipherSpec:
- w.writeRecord(&record{recordTypeChangeCipherSpec, w.major, w.minor, []byte{0x01}})
- w.encryptor = msg.encryptor
- w.mac = msg.mac
- w.seqNum = 0
- case writerSetVersion:
- w.major = msg.major
- w.minor = msg.minor
- case alert:
- w.writeRecord(&record{recordTypeAlert, w.major, w.minor, []byte{byte(msg.level), byte(msg.error)}})
- case handshakeMessage:
- // TODO(agl): marshal may return a slice too large for a single record.
- w.writeRecord(&record{recordTypeHandshake, w.major, w.minor, msg.marshal()})
- default:
- fmt.Printf("processControlMessage: unknown %#v\n", msg)
- }
-}
-
-func (w *recordWriter) processAppMessage(appMsg []byte) {
- if closed(w.appChan) {
- w.writeRecord(&record{recordTypeApplicationData, w.major, w.minor, []byte{byte(alertCloseNotify)}})
- w.shutdown = true
- return
- }
-
- var done int
- for done < len(appMsg) {
- todo := len(appMsg)
- if todo > maxTLSPlaintext {
- todo = maxTLSPlaintext
- }
- w.writeRecord(&record{recordTypeApplicationData, w.major, w.minor, appMsg[done : done+todo]})
- done += todo
- }
-}