Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / test / runner / handshake_messages.go
index 1c633bb..136360d 100644 (file)
@@ -8,9 +8,11 @@ import "bytes"
 
 type clientHelloMsg struct {
        raw                 []byte
+       isDTLS              bool
        vers                uint16
        random              []byte
        sessionId           []byte
+       cookie              []byte
        cipherSuites        []uint16
        compressionMethods  []uint8
        nextProtoNeg        bool
@@ -22,7 +24,10 @@ type clientHelloMsg struct {
        sessionTicket       []uint8
        signatureAndHashes  []signatureAndHash
        secureRenegotiation bool
+       alpnProtocols       []string
        duplicateExtension  bool
+       channelIDSupported  bool
+       npnLast             bool
 }
 
 func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -32,9 +37,11 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
        }
 
        return bytes.Equal(m.raw, m1.raw) &&
+               m.isDTLS == m1.isDTLS &&
                m.vers == m1.vers &&
                bytes.Equal(m.random, m1.random) &&
                bytes.Equal(m.sessionId, m1.sessionId) &&
+               bytes.Equal(m.cookie, m1.cookie) &&
                eqUint16s(m.cipherSuites, m1.cipherSuites) &&
                bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
                m.nextProtoNeg == m1.nextProtoNeg &&
@@ -45,7 +52,11 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
                m.ticketSupported == m1.ticketSupported &&
                bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
                eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
-               m.secureRenegotiation == m1.secureRenegotiation
+               m.secureRenegotiation == m1.secureRenegotiation &&
+               eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
+               m.duplicateExtension == m1.duplicateExtension &&
+               m.channelIDSupported == m1.channelIDSupported &&
+               m.npnLast == m1.npnLast
 }
 
 func (m *clientHelloMsg) marshal() []byte {
@@ -54,6 +65,9 @@ func (m *clientHelloMsg) marshal() []byte {
        }
 
        length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
+       if m.isDTLS {
+               length += 1 + len(m.cookie)
+       }
        numExtensions := 0
        extensionsLength := 0
        if m.nextProtoNeg {
@@ -90,6 +104,20 @@ func (m *clientHelloMsg) marshal() []byte {
        if m.duplicateExtension {
                numExtensions += 2
        }
+       if m.channelIDSupported {
+               numExtensions++
+       }
+       if len(m.alpnProtocols) > 0 {
+               extensionsLength += 2
+               for _, s := range m.alpnProtocols {
+                       if l := len(s); l == 0 || l > 255 {
+                               panic("invalid ALPN protocol")
+                       }
+                       extensionsLength++
+                       extensionsLength += len(s)
+               }
+               numExtensions++
+       }
        if numExtensions > 0 {
                extensionsLength += 4 * numExtensions
                length += 2 + extensionsLength
@@ -100,12 +128,18 @@ func (m *clientHelloMsg) marshal() []byte {
        x[1] = uint8(length >> 16)
        x[2] = uint8(length >> 8)
        x[3] = uint8(length)
-       x[4] = uint8(m.vers >> 8)
-       x[5] = uint8(m.vers)
+       vers := versionToWire(m.vers, m.isDTLS)
+       x[4] = uint8(vers >> 8)
+       x[5] = uint8(vers)
        copy(x[6:38], m.random)
        x[38] = uint8(len(m.sessionId))
        copy(x[39:39+len(m.sessionId)], m.sessionId)
        y := x[39+len(m.sessionId):]
+       if m.isDTLS {
+               y[0] = uint8(len(m.cookie))
+               copy(y[1:], m.cookie)
+               y = y[1+len(m.cookie):]
+       }
        y[0] = uint8(len(m.cipherSuites) >> 7)
        y[1] = uint8(len(m.cipherSuites) << 1)
        for i, suite := range m.cipherSuites {
@@ -128,7 +162,7 @@ func (m *clientHelloMsg) marshal() []byte {
                z[1] = 0xff
                z = z[4:]
        }
-       if m.nextProtoNeg {
+       if m.nextProtoNeg && !m.npnLast {
                z[0] = byte(extensionNextProtoNeg >> 8)
                z[1] = byte(extensionNextProtoNeg & 0xff)
                // The length is always 0
@@ -247,6 +281,38 @@ func (m *clientHelloMsg) marshal() []byte {
                z[3] = 1
                z = z[5:]
        }
+       if len(m.alpnProtocols) > 0 {
+               z[0] = byte(extensionALPN >> 8)
+               z[1] = byte(extensionALPN & 0xff)
+               lengths := z[2:]
+               z = z[6:]
+
+               stringsLength := 0
+               for _, s := range m.alpnProtocols {
+                       l := len(s)
+                       z[0] = byte(l)
+                       copy(z[1:], s)
+                       z = z[1+l:]
+                       stringsLength += 1 + l
+               }
+
+               lengths[2] = byte(stringsLength >> 8)
+               lengths[3] = byte(stringsLength)
+               stringsLength += 2
+               lengths[0] = byte(stringsLength >> 8)
+               lengths[1] = byte(stringsLength)
+       }
+       if m.channelIDSupported {
+               z[0] = byte(extensionChannelID >> 8)
+               z[1] = byte(extensionChannelID & 0xff)
+               z = z[4:]
+       }
+       if m.nextProtoNeg && m.npnLast {
+               z[0] = byte(extensionNextProtoNeg >> 8)
+               z[1] = byte(extensionNextProtoNeg & 0xff)
+               // The length is always 0
+               z = z[4:]
+       }
        if m.duplicateExtension {
                // Add a duplicate bogus extension at the beginning and end.
                z[0] = 0xff
@@ -264,7 +330,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
                return false
        }
        m.raw = data
-       m.vers = uint16(data[4])<<8 | uint16(data[5])
+       m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
        m.random = data[6:38]
        sessionIdLen := int(data[38])
        if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
@@ -272,6 +338,17 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
        }
        m.sessionId = data[39 : 39+sessionIdLen]
        data = data[39+sessionIdLen:]
+       if m.isDTLS {
+               if len(data) < 1 {
+                       return false
+               }
+               cookieLen := int(data[0])
+               if cookieLen > 32 || len(data) < 1+cookieLen {
+                       return false
+               }
+               m.cookie = data[1 : 1+cookieLen]
+               data = data[1+cookieLen:]
+       }
        if len(data) < 2 {
                return false
        }
@@ -307,6 +384,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
        m.ticketSupported = false
        m.sessionTicket = nil
        m.signatureAndHashes = nil
+       m.alpnProtocols = nil
 
        if len(data) == 0 {
                // ClientHello is optionally followed by extension data
@@ -416,6 +494,29 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
                                return false
                        }
                        m.secureRenegotiation = true
+               case extensionALPN:
+                       if length < 2 {
+                               return false
+                       }
+                       l := int(data[0])<<8 | int(data[1])
+                       if l != length-2 {
+                               return false
+                       }
+                       d := data[2:length]
+                       for len(d) != 0 {
+                               stringLen := int(d[0])
+                               d = d[1:]
+                               if stringLen == 0 || stringLen > len(d) {
+                                       return false
+                               }
+                               m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
+                               d = d[stringLen:]
+                       }
+               case extensionChannelID:
+                       if length > 0 {
+                               return false
+                       }
+                       m.channelIDSupported = true
                }
                data = data[length:]
        }
@@ -425,6 +526,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
 
 type serverHelloMsg struct {
        raw                 []byte
+       isDTLS              bool
        vers                uint16
        random              []byte
        sessionId           []byte
@@ -435,7 +537,9 @@ type serverHelloMsg struct {
        ocspStapling        bool
        ticketSupported     bool
        secureRenegotiation bool
+       alpnProtocol        string
        duplicateExtension  bool
+       channelIDRequested  bool
 }
 
 func (m *serverHelloMsg) equal(i interface{}) bool {
@@ -445,6 +549,7 @@ func (m *serverHelloMsg) equal(i interface{}) bool {
        }
 
        return bytes.Equal(m.raw, m1.raw) &&
+               m.isDTLS == m1.isDTLS &&
                m.vers == m1.vers &&
                bytes.Equal(m.random, m1.random) &&
                bytes.Equal(m.sessionId, m1.sessionId) &&
@@ -454,7 +559,10 @@ func (m *serverHelloMsg) equal(i interface{}) bool {
                eqStrings(m.nextProtos, m1.nextProtos) &&
                m.ocspStapling == m1.ocspStapling &&
                m.ticketSupported == m1.ticketSupported &&
-               m.secureRenegotiation == m1.secureRenegotiation
+               m.secureRenegotiation == m1.secureRenegotiation &&
+               m.alpnProtocol == m1.alpnProtocol &&
+               m.duplicateExtension == m1.duplicateExtension &&
+               m.channelIDRequested == m1.channelIDRequested
 }
 
 func (m *serverHelloMsg) marshal() []byte {
@@ -488,6 +596,17 @@ func (m *serverHelloMsg) marshal() []byte {
        if m.duplicateExtension {
                numExtensions += 2
        }
+       if m.channelIDRequested {
+               numExtensions++
+       }
+       if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+               if alpnLen >= 256 {
+                       panic("invalid ALPN protocol")
+               }
+               extensionsLength += 2 + 1 + alpnLen
+               numExtensions++
+       }
+
        if numExtensions > 0 {
                extensionsLength += 4 * numExtensions
                length += 2 + extensionsLength
@@ -498,8 +617,9 @@ func (m *serverHelloMsg) marshal() []byte {
        x[1] = uint8(length >> 16)
        x[2] = uint8(length >> 8)
        x[3] = uint8(length)
-       x[4] = uint8(m.vers >> 8)
-       x[5] = uint8(m.vers)
+       vers := versionToWire(m.vers, m.isDTLS)
+       x[4] = uint8(vers >> 8)
+       x[5] = uint8(vers)
        copy(x[6:38], m.random)
        x[38] = uint8(len(m.sessionId))
        copy(x[39:39+len(m.sessionId)], m.sessionId)
@@ -554,6 +674,25 @@ func (m *serverHelloMsg) marshal() []byte {
                z[3] = 1
                z = z[5:]
        }
+       if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+               z[0] = byte(extensionALPN >> 8)
+               z[1] = byte(extensionALPN & 0xff)
+               l := 2 + 1 + alpnLen
+               z[2] = byte(l >> 8)
+               z[3] = byte(l)
+               l -= 2
+               z[4] = byte(l >> 8)
+               z[5] = byte(l)
+               l -= 1
+               z[6] = byte(l)
+               copy(z[7:], []byte(m.alpnProtocol))
+               z = z[7+alpnLen:]
+       }
+       if m.channelIDRequested {
+               z[0] = byte(extensionChannelID >> 8)
+               z[1] = byte(extensionChannelID & 0xff)
+               z = z[4:]
+       }
        if m.duplicateExtension {
                // Add a duplicate bogus extension at the beginning and end.
                z[0] = 0xff
@@ -571,7 +710,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
                return false
        }
        m.raw = data
-       m.vers = uint16(data[4])<<8 | uint16(data[5])
+       m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
        m.random = data[6:38]
        sessionIdLen := int(data[38])
        if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
@@ -590,6 +729,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
        m.nextProtos = nil
        m.ocspStapling = false
        m.ticketSupported = false
+       m.alpnProtocol = ""
 
        if len(data) == 0 {
                // ServerHello is optionally followed by extension data
@@ -644,6 +784,27 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
                                return false
                        }
                        m.secureRenegotiation = true
+               case extensionALPN:
+                       d := data[:length]
+                       if len(d) < 3 {
+                               return false
+                       }
+                       l := int(d[0])<<8 | int(d[1])
+                       if l != len(d)-2 {
+                               return false
+                       }
+                       d = d[2:]
+                       l = int(d[0])
+                       if l != len(d)-1 {
+                               return false
+                       }
+                       d = d[1:]
+                       m.alpnProtocol = string(d)
+               case extensionChannelID:
+                       if length > 0 {
+                               return false
+                       }
+                       m.channelIDRequested = true
                }
                data = data[length:]
        }
@@ -1368,6 +1529,111 @@ func (m *v2ClientHelloMsg) marshal() []byte {
        return x
 }
 
+type helloVerifyRequestMsg struct {
+       raw    []byte
+       vers   uint16
+       cookie []byte
+}
+
+func (m *helloVerifyRequestMsg) equal(i interface{}) bool {
+       m1, ok := i.(*helloVerifyRequestMsg)
+       if !ok {
+               return false
+       }
+
+       return bytes.Equal(m.raw, m1.raw) &&
+               m.vers == m1.vers &&
+               bytes.Equal(m.cookie, m1.cookie)
+}
+
+func (m *helloVerifyRequestMsg) marshal() []byte {
+       if m.raw != nil {
+               return m.raw
+       }
+
+       length := 2 + 1 + len(m.cookie)
+
+       x := make([]byte, 4+length)
+       x[0] = typeHelloVerifyRequest
+       x[1] = uint8(length >> 16)
+       x[2] = uint8(length >> 8)
+       x[3] = uint8(length)
+       vers := versionToWire(m.vers, true)
+       x[4] = uint8(vers >> 8)
+       x[5] = uint8(vers)
+       x[6] = uint8(len(m.cookie))
+       copy(x[7:7+len(m.cookie)], m.cookie)
+
+       return x
+}
+
+func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
+       if len(data) < 4+2+1 {
+               return false
+       }
+       m.raw = data
+       m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
+       cookieLen := int(data[6])
+       if cookieLen > 32 || len(data) != 7+cookieLen {
+               return false
+       }
+       m.cookie = data[7 : 7+cookieLen]
+
+       return true
+}
+
+type encryptedExtensionsMsg struct {
+       raw       []byte
+       channelID []byte
+}
+
+func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
+       m1, ok := i.(*encryptedExtensionsMsg)
+       if !ok {
+               return false
+       }
+
+       return bytes.Equal(m.raw, m1.raw) &&
+               bytes.Equal(m.channelID, m1.channelID)
+}
+
+func (m *encryptedExtensionsMsg) marshal() []byte {
+       if m.raw != nil {
+               return m.raw
+       }
+
+       length := 2 + 2 + len(m.channelID)
+
+       x := make([]byte, 4+length)
+       x[0] = typeEncryptedExtensions
+       x[1] = uint8(length >> 16)
+       x[2] = uint8(length >> 8)
+       x[3] = uint8(length)
+       x[4] = uint8(extensionChannelID >> 8)
+       x[5] = uint8(extensionChannelID & 0xff)
+       x[6] = uint8(len(m.channelID) >> 8)
+       x[7] = uint8(len(m.channelID) & 0xff)
+       copy(x[8:], m.channelID)
+
+       return x
+}
+
+func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
+       if len(data) != 4+2+2+128 {
+               return false
+       }
+       m.raw = data
+       if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
+               return false
+       }
+       if int(data[6])<<8|int(data[7]) != 128 {
+               return false
+       }
+       m.channelID = data[4+2+2:]
+
+       return true
+}
+
 func eqUint16s(x, y []uint16) bool {
        if len(x) != len(y) {
                return false