-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.go
94 lines (82 loc) · 2.18 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"fmt"
"io"
)
func main() {
get("jvns.ca")
}
func get(domain string) {
session := connect()
session.connect(domain)
req := fmt.Sprintf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", domain)
session.SendData([]byte(req))
session.ReceiveData() // ignore the session ticket
resp := session.ReceiveHTTPResponse()
fmt.Println(string(resp))
}
func (session *Session) ReceiveHTTPResponse() []byte {
var response []byte
for {
pt := session.ReceiveData()
if string(pt) == string([]byte{48, 13, 10, 13, 10, 23}) {
break
}
response = append(response, pt...)
}
return response
}
func (session *Session) connect(domainName string) {
session.SendClientHello(domainName)
session.GetServerHello()
session.MakeHandshakeKeys()
session.ParseServerHandshake()
session.ClientChangeCipherSpec()
session.ClientHandshakeFinished()
}
type Session struct {
Conn io.ReadWriteCloser
ServerHello ServerHello
Messages Messages
Keys Keys
RecordsSent uint8
RecordsReceived uint8
}
func (session *Session) SendClientHello(domain string) {
// send client hello
conn := session.Conn
session.Keys = KeyPair()
clientHello := ClientHello(domain, session.Keys)
session.Messages.ClientHello = clientHello
send(conn, clientHello)
}
func (session *Session) GetServerHello() {
conn := session.Conn
record := readRecord(conn)
if record.Type() != 0x16 {
panic("expected server hello")
}
session.Messages.ServerHello = record
session.ServerHello = parseServerHello(record.Contents())
// ignore change cipher spec
record = readRecord(conn)
if record.Type() != 0x14 {
panic("expected change cipher spec")
}
}
func (session *Session) ParseServerHandshake() {
record := readRecord(session.Conn)
if record.Type() != 0x17 {
panic("expected wrapper")
}
session.Messages.ServerHandshake = decrypt(session.Keys.ServerHandshakeKey, session.Keys.ServerHandshakeIV, record)
session.MakeApplicationKeys()
}
func (session *Session) ClientChangeCipherSpec() {
conn := session.Conn
send(conn, []byte{0x14, 0x03, 0x03, 0x00, 0x01, 0x01})
}
func (session *Session) ClientHandshakeFinished() {
conn := session.Conn
send(conn, session.ClientHandshakeFinishedMsg())
}