1
2
3
4
5 package tls
6
7 import (
8 "crypto"
9 "crypto/rsa"
10 "crypto/subtle"
11 "crypto/x509"
12 "io"
13 "os"
14 )
15
16 func (c *Conn) serverHandshake() os.Error {
17 config := c.config
18 msg, err := c.readHandshake()
19 if err != nil {
20 return err
21 }
22 clientHello, ok := msg.(*clientHelloMsg)
23 if !ok {
24 return c.sendAlert(alertUnexpectedMessage)
25 }
26 vers, ok := mutualVersion(clientHello.vers)
27 if !ok {
28 return c.sendAlert(alertProtocolVersion)
29 }
30 c.vers = vers
31 c.haveVers = true
32
33 finishedHash := newFinishedHash()
34 finishedHash.Write(clientHello.marshal())
35
36 hello := new(serverHelloMsg)
37
38 supportedCurve := false
39 Curves:
40 for _, curve := range clientHello.supportedCurves {
41 switch curve {
42 case curveP256, curveP384, curveP521:
43 supportedCurve = true
44 break Curves
45 }
46 }
47
48 supportedPointFormat := false
49 for _, pointFormat := range clientHello.supportedPoints {
50 if pointFormat == pointFormatUncompressed {
51 supportedPointFormat = true
52 break
53 }
54 }
55
56 ellipticOk := supportedCurve && supportedPointFormat
57
58 var suite *cipherSuite
59 var suiteId uint16
60 FindCipherSuite:
61 for _, id := range clientHello.cipherSuites {
62 for _, supported := range config.cipherSuites() {
63 if id == supported {
64 suite = cipherSuites[id]
65
66
67 if suite.elliptic && !ellipticOk {
68 continue
69 }
70 suiteId = id
71 break FindCipherSuite
72 }
73 }
74 }
75
76 foundCompression := false
77
78 for _, compression := range clientHello.compressionMethods {
79 if compression == compressionNone {
80 foundCompression = true
81 break
82 }
83 }
84
85 if suite == nil || !foundCompression {
86 return c.sendAlert(alertHandshakeFailure)
87 }
88
89 hello.vers = vers
90 hello.cipherSuite = suiteId
91 t := uint32(config.time())
92 hello.random = make([]byte, 32)
93 hello.random[0] = byte(t >> 24)
94 hello.random[1] = byte(t >> 16)
95 hello.random[2] = byte(t >> 8)
96 hello.random[3] = byte(t)
97 _, err = io.ReadFull(config.rand(), hello.random[4:])
98 if err != nil {
99 return c.sendAlert(alertInternalError)
100 }
101 hello.compressionMethod = compressionNone
102 if clientHello.nextProtoNeg {
103 hello.nextProtoNeg = true
104 hello.nextProtos = config.NextProtos
105 }
106 if clientHello.ocspStapling && len(config.Certificates[0].OCSPStaple) > 0 {
107 hello.ocspStapling = true
108 }
109
110 finishedHash.Write(hello.marshal())
111 c.writeRecord(recordTypeHandshake, hello.marshal())
112
113 if len(config.Certificates) == 0 {
114 return c.sendAlert(alertInternalError)
115 }
116
117 certMsg := new(certificateMsg)
118 certMsg.certificates = config.Certificates[0].Certificate
119 finishedHash.Write(certMsg.marshal())
120 c.writeRecord(recordTypeHandshake, certMsg.marshal())
121
122 if hello.ocspStapling {
123 certStatus := new(certificateStatusMsg)
124 certStatus.statusType = statusTypeOCSP
125 certStatus.response = config.Certificates[0].OCSPStaple
126 finishedHash.Write(certStatus.marshal())
127 c.writeRecord(recordTypeHandshake, certStatus.marshal())
128 }
129
130 keyAgreement := suite.ka()
131
132 skx, err := keyAgreement.generateServerKeyExchange(config, clientHello, hello)
133 if err != nil {
134 c.sendAlert(alertHandshakeFailure)
135 return err
136 }
137 if skx != nil {
138 finishedHash.Write(skx.marshal())
139 c.writeRecord(recordTypeHandshake, skx.marshal())
140 }
141
142 if config.AuthenticateClient {
143
144 certReq := new(certificateRequestMsg)
145 certReq.certificateTypes = []byte{certTypeRSASign}
146
147
148
149
150 finishedHash.Write(certReq.marshal())
151 c.writeRecord(recordTypeHandshake, certReq.marshal())
152 }
153
154 helloDone := new(serverHelloDoneMsg)
155 finishedHash.Write(helloDone.marshal())
156 c.writeRecord(recordTypeHandshake, helloDone.marshal())
157
158 var pub *rsa.PublicKey
159 if config.AuthenticateClient {
160
161 msg, err = c.readHandshake()
162 if err != nil {
163 return err
164 }
165 certMsg, ok = msg.(*certificateMsg)
166 if !ok {
167 return c.sendAlert(alertUnexpectedMessage)
168 }
169 finishedHash.Write(certMsg.marshal())
170
171 certs := make([]*x509.Certificate, len(certMsg.certificates))
172 for i, asn1Data := range certMsg.certificates {
173 cert, err := x509.ParseCertificate(asn1Data)
174 if err != nil {
175 c.sendAlert(alertBadCertificate)
176 return os.NewError("could not parse client's certificate: " + err.String())
177 }
178 certs[i] = cert
179 }
180
181
182 for i := 1; i < len(certs); i++ {
183 if err := certs[i-1].CheckSignatureFrom(certs[i]); err != nil {
184 c.sendAlert(alertBadCertificate)
185 return os.NewError("could not validate certificate signature: " + err.String())
186 }
187 }
188
189 if len(certs) > 0 {
190 key, ok := certs[0].PublicKey.(*rsa.PublicKey)
191 if !ok {
192 return c.sendAlert(alertUnsupportedCertificate)
193 }
194 pub = key
195 c.peerCertificates = certs
196 }
197 }
198
199
200 msg, err = c.readHandshake()
201 if err != nil {
202 return err
203 }
204 ckx, ok := msg.(*clientKeyExchangeMsg)
205 if !ok {
206 return c.sendAlert(alertUnexpectedMessage)
207 }
208 finishedHash.Write(ckx.marshal())
209
210
211
212
213
214
215
216 if len(c.peerCertificates) > 0 {
217 msg, err = c.readHandshake()
218 if err != nil {
219 return err
220 }
221 certVerify, ok := msg.(*certificateVerifyMsg)
222 if !ok {
223 return c.sendAlert(alertUnexpectedMessage)
224 }
225
226 digest := make([]byte, 36)
227 copy(digest[0:16], finishedHash.serverMD5.Sum())
228 copy(digest[16:36], finishedHash.serverSHA1.Sum())
229 err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature)
230 if err != nil {
231 c.sendAlert(alertBadCertificate)
232 return os.NewError("could not validate signature of connection nonces: " + err.String())
233 }
234
235 finishedHash.Write(certVerify.marshal())
236 }
237
238 preMasterSecret, err := keyAgreement.processClientKeyExchange(config, ckx)
239 if err != nil {
240 c.sendAlert(alertHandshakeFailure)
241 return err
242 }
243
244 masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
245 keysFromPreMasterSecret10(preMasterSecret, clientHello.random, hello.random, suite.macLen, suite.keyLen, suite.ivLen)
246
247 clientCipher := suite.cipher(clientKey, clientIV, true )
248 clientHash := suite.mac(clientMAC)
249 c.in.prepareCipherSpec(clientCipher, clientHash)
250 c.readRecord(recordTypeChangeCipherSpec)
251 if err := c.error(); err != nil {
252 return err
253 }
254
255 if hello.nextProtoNeg {
256 msg, err = c.readHandshake()
257 if err != nil {
258 return err
259 }
260 nextProto, ok := msg.(*nextProtoMsg)
261 if !ok {
262 return c.sendAlert(alertUnexpectedMessage)
263 }
264 finishedHash.Write(nextProto.marshal())
265 c.clientProtocol = nextProto.proto
266 }
267
268 msg, err = c.readHandshake()
269 if err != nil {
270 return err
271 }
272 clientFinished, ok := msg.(*finishedMsg)
273 if !ok {
274 return c.sendAlert(alertUnexpectedMessage)
275 }
276
277 verify := finishedHash.clientSum(masterSecret)
278 if len(verify) != len(clientFinished.verifyData) ||
279 subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
280 return c.sendAlert(alertHandshakeFailure)
281 }
282
283 finishedHash.Write(clientFinished.marshal())
284
285 serverCipher := suite.cipher(serverKey, serverIV, false )
286 serverHash := suite.mac(serverMAC)
287 c.out.prepareCipherSpec(serverCipher, serverHash)
288 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
289
290 finished := new(finishedMsg)
291 finished.verifyData = finishedHash.serverSum(masterSecret)
292 c.writeRecord(recordTypeHandshake, finished.marshal())
293
294 c.handshakeComplete = true
295 c.cipherSuite = suiteId
296
297 return nil
298 }