// controlFrameCommonProcessing performs checks identical between // all control frames. This includes the control bit, the version // number, the type byte (which is checked against the byte // provided), and the flags (which are checked against the bitwise // OR of valid flags provided). func controlFrameCommonProcessing(data []byte, frameType uint16, flags byte) error { // Check it's a control frame. if data[0] != 128 { return common.IncorrectFrame(_DATA_FRAME, int(frameType), 2) } // Check version. version := (uint16(data[0]&0x7f) << 8) + uint16(data[1]) if version != 2 { return common.UnsupportedVersion(version) } // Check its type. realType := common.BytesToUint16(data[2:]) if realType != frameType { return common.IncorrectFrame(int(realType), int(frameType), 2) } // Check the flags. if data[4] & ^flags != 0 { return common.InvalidField("flags", int(data[4]), int(flags)) } return nil }
func (frame *CREDENTIAL) ReadFrom(reader io.Reader) (int64, error) { c := common.ReadCounter{R: reader} data, err := common.ReadExactly(&c, 18) if err != nil { return c.N, err } err = controlFrameCommonProcessing(data[:5], _CREDENTIAL, 0) if err != nil { return c.N, err } // Get and check length. length := int(common.BytesToUint24(data[5:8])) if length < 6 { return c.N, common.IncorrectDataLength(length, 6) } else if length > common.MAX_FRAME_SIZE-8 { return c.N, common.FrameTooLarge } // Read in data. certs, err := common.ReadExactly(&c, length-10) if err != nil { return c.N, err } frame.Slot = common.BytesToUint16(data[8:10]) proofLen := int(common.BytesToUint32(data[10:14])) if proofLen > 0 { frame.Proof = data[14 : 14+proofLen] } else { frame.Proof = []byte{} } numCerts := 0 for offset := 0; offset < length-10; { offset += int(common.BytesToUint32(certs[offset:offset+4])) + 4 numCerts++ } frame.Certificates = make([]*x509.Certificate, numCerts) for i, offset := 0, 0; offset < length-10; i++ { length := int(common.BytesToUint32(certs[offset : offset+4])) rawCert := certs[offset+4 : offset+4+length] frame.Certificates[i], err = x509.ParseCertificate(rawCert) if err != nil { return c.N, err } offset += length + 4 } return c.N, nil }
// ReadFrame reads and parses a frame from reader. func ReadFrame(reader *bufio.Reader, subversion int) (frame common.Frame, err error) { start, err := reader.Peek(4) if err != nil { return nil, err } if start[0] != 128 { frame = new(DATA) _, err = frame.ReadFrom(reader) return frame, err } switch common.BytesToUint16(start[2:4]) { case _SYN_STREAM: switch subversion { case 0: frame = new(SYN_STREAM) case 1: frame = new(SYN_STREAMV3_1) default: return nil, fmt.Errorf("Error: Given subversion %d is unrecognised.", subversion) } case _SYN_REPLY: frame = new(SYN_REPLY) case _RST_STREAM: frame = new(RST_STREAM) case _SETTINGS: frame = new(SETTINGS) case _PING: frame = new(PING) case _GOAWAY: frame = new(GOAWAY) case _HEADERS: frame = new(HEADERS) case _WINDOW_UPDATE: frame = &WINDOW_UPDATE{subversion: subversion} case _CREDENTIAL: frame = new(CREDENTIAL) default: return nil, errors.New("Error Failed to parse frame type.") } _, err = frame.ReadFrom(reader) return frame, err }
// ReadFrame reads and parses a frame from reader. func ReadFrame(reader *bufio.Reader) (frame common.Frame, err error) { start, err := reader.Peek(4) if err != nil { return nil, err } if start[0] != 128 { frame = new(DATA) _, err = frame.ReadFrom(reader) return frame, err } switch common.BytesToUint16(start[2:4]) { case _SYN_STREAM: frame = new(SYN_STREAM) case _SYN_REPLY: frame = new(SYN_REPLY) case _RST_STREAM: frame = new(RST_STREAM) case _SETTINGS: frame = new(SETTINGS) case _NOOP: frame = new(NOOP) case _PING: frame = new(PING) case _GOAWAY: frame = new(GOAWAY) case _HEADERS: frame = new(HEADERS) case _WINDOW_UPDATE: frame = new(WINDOW_UPDATE) default: return nil, errors.New("Error Failed to parse frame type.") } _, err = frame.ReadFrom(reader) return frame, err }