diff options
author | Jake Champlin <jake@gnu.space> | 2017-06-09 17:54:32 +0000 |
---|---|---|
committer | Jake Champlin <jake@gnu.space> | 2017-06-09 17:54:32 +0000 |
commit | 9b12e4fe6f3c95986f1f3ec791636c58ca7e7583 (patch) | |
tree | 38f5f12bec0e488a12f0459a7356e6b7de7d8f84 /vendor/golang.org/x/crypto/ssh/kex.go | |
parent | cec3de8a3bcaffd21dedd1bf42da4b490cae7e16 (diff) | |
download | terraform-provider-statuscake-9b12e4fe6f3c95986f1f3ec791636c58ca7e7583.tar.gz terraform-provider-statuscake-9b12e4fe6f3c95986f1f3ec791636c58ca7e7583.tar.zst terraform-provider-statuscake-9b12e4fe6f3c95986f1f3ec791636c58ca7e7583.zip |
Transfer of provider code
Diffstat (limited to 'vendor/golang.org/x/crypto/ssh/kex.go')
-rw-r--r-- | vendor/golang.org/x/crypto/ssh/kex.go | 540 |
1 files changed, 0 insertions, 540 deletions
diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go deleted file mode 100644 index c87fbeb..0000000 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ /dev/null | |||
@@ -1,540 +0,0 @@ | |||
1 | // Copyright 2013 The Go Authors. All rights reserved. | ||
2 | // Use of this source code is governed by a BSD-style | ||
3 | // license that can be found in the LICENSE file. | ||
4 | |||
5 | package ssh | ||
6 | |||
7 | import ( | ||
8 | "crypto" | ||
9 | "crypto/ecdsa" | ||
10 | "crypto/elliptic" | ||
11 | "crypto/rand" | ||
12 | "crypto/subtle" | ||
13 | "errors" | ||
14 | "io" | ||
15 | "math/big" | ||
16 | |||
17 | "golang.org/x/crypto/curve25519" | ||
18 | ) | ||
19 | |||
20 | const ( | ||
21 | kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1" | ||
22 | kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1" | ||
23 | kexAlgoECDH256 = "ecdh-sha2-nistp256" | ||
24 | kexAlgoECDH384 = "ecdh-sha2-nistp384" | ||
25 | kexAlgoECDH521 = "ecdh-sha2-nistp521" | ||
26 | kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org" | ||
27 | ) | ||
28 | |||
29 | // kexResult captures the outcome of a key exchange. | ||
30 | type kexResult struct { | ||
31 | // Session hash. See also RFC 4253, section 8. | ||
32 | H []byte | ||
33 | |||
34 | // Shared secret. See also RFC 4253, section 8. | ||
35 | K []byte | ||
36 | |||
37 | // Host key as hashed into H. | ||
38 | HostKey []byte | ||
39 | |||
40 | // Signature of H. | ||
41 | Signature []byte | ||
42 | |||
43 | // A cryptographic hash function that matches the security | ||
44 | // level of the key exchange algorithm. It is used for | ||
45 | // calculating H, and for deriving keys from H and K. | ||
46 | Hash crypto.Hash | ||
47 | |||
48 | // The session ID, which is the first H computed. This is used | ||
49 | // to derive key material inside the transport. | ||
50 | SessionID []byte | ||
51 | } | ||
52 | |||
53 | // handshakeMagics contains data that is always included in the | ||
54 | // session hash. | ||
55 | type handshakeMagics struct { | ||
56 | clientVersion, serverVersion []byte | ||
57 | clientKexInit, serverKexInit []byte | ||
58 | } | ||
59 | |||
60 | func (m *handshakeMagics) write(w io.Writer) { | ||
61 | writeString(w, m.clientVersion) | ||
62 | writeString(w, m.serverVersion) | ||
63 | writeString(w, m.clientKexInit) | ||
64 | writeString(w, m.serverKexInit) | ||
65 | } | ||
66 | |||
67 | // kexAlgorithm abstracts different key exchange algorithms. | ||
68 | type kexAlgorithm interface { | ||
69 | // Server runs server-side key agreement, signing the result | ||
70 | // with a hostkey. | ||
71 | Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error) | ||
72 | |||
73 | // Client runs the client-side key agreement. Caller is | ||
74 | // responsible for verifying the host key signature. | ||
75 | Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) | ||
76 | } | ||
77 | |||
78 | // dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement. | ||
79 | type dhGroup struct { | ||
80 | g, p, pMinus1 *big.Int | ||
81 | } | ||
82 | |||
83 | func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) { | ||
84 | if theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 { | ||
85 | return nil, errors.New("ssh: DH parameter out of bounds") | ||
86 | } | ||
87 | return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil | ||
88 | } | ||
89 | |||
90 | func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) { | ||
91 | hashFunc := crypto.SHA1 | ||
92 | |||
93 | var x *big.Int | ||
94 | for { | ||
95 | var err error | ||
96 | if x, err = rand.Int(randSource, group.pMinus1); err != nil { | ||
97 | return nil, err | ||
98 | } | ||
99 | if x.Sign() > 0 { | ||
100 | break | ||
101 | } | ||
102 | } | ||
103 | |||
104 | X := new(big.Int).Exp(group.g, x, group.p) | ||
105 | kexDHInit := kexDHInitMsg{ | ||
106 | X: X, | ||
107 | } | ||
108 | if err := c.writePacket(Marshal(&kexDHInit)); err != nil { | ||
109 | return nil, err | ||
110 | } | ||
111 | |||
112 | packet, err := c.readPacket() | ||
113 | if err != nil { | ||
114 | return nil, err | ||
115 | } | ||
116 | |||
117 | var kexDHReply kexDHReplyMsg | ||
118 | if err = Unmarshal(packet, &kexDHReply); err != nil { | ||
119 | return nil, err | ||
120 | } | ||
121 | |||
122 | kInt, err := group.diffieHellman(kexDHReply.Y, x) | ||
123 | if err != nil { | ||
124 | return nil, err | ||
125 | } | ||
126 | |||
127 | h := hashFunc.New() | ||
128 | magics.write(h) | ||
129 | writeString(h, kexDHReply.HostKey) | ||
130 | writeInt(h, X) | ||
131 | writeInt(h, kexDHReply.Y) | ||
132 | K := make([]byte, intLength(kInt)) | ||
133 | marshalInt(K, kInt) | ||
134 | h.Write(K) | ||
135 | |||
136 | return &kexResult{ | ||
137 | H: h.Sum(nil), | ||
138 | K: K, | ||
139 | HostKey: kexDHReply.HostKey, | ||
140 | Signature: kexDHReply.Signature, | ||
141 | Hash: crypto.SHA1, | ||
142 | }, nil | ||
143 | } | ||
144 | |||
145 | func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { | ||
146 | hashFunc := crypto.SHA1 | ||
147 | packet, err := c.readPacket() | ||
148 | if err != nil { | ||
149 | return | ||
150 | } | ||
151 | var kexDHInit kexDHInitMsg | ||
152 | if err = Unmarshal(packet, &kexDHInit); err != nil { | ||
153 | return | ||
154 | } | ||
155 | |||
156 | var y *big.Int | ||
157 | for { | ||
158 | if y, err = rand.Int(randSource, group.pMinus1); err != nil { | ||
159 | return | ||
160 | } | ||
161 | if y.Sign() > 0 { | ||
162 | break | ||
163 | } | ||
164 | } | ||
165 | |||
166 | Y := new(big.Int).Exp(group.g, y, group.p) | ||
167 | kInt, err := group.diffieHellman(kexDHInit.X, y) | ||
168 | if err != nil { | ||
169 | return nil, err | ||
170 | } | ||
171 | |||
172 | hostKeyBytes := priv.PublicKey().Marshal() | ||
173 | |||
174 | h := hashFunc.New() | ||
175 | magics.write(h) | ||
176 | writeString(h, hostKeyBytes) | ||
177 | writeInt(h, kexDHInit.X) | ||
178 | writeInt(h, Y) | ||
179 | |||
180 | K := make([]byte, intLength(kInt)) | ||
181 | marshalInt(K, kInt) | ||
182 | h.Write(K) | ||
183 | |||
184 | H := h.Sum(nil) | ||
185 | |||
186 | // H is already a hash, but the hostkey signing will apply its | ||
187 | // own key-specific hash algorithm. | ||
188 | sig, err := signAndMarshal(priv, randSource, H) | ||
189 | if err != nil { | ||
190 | return nil, err | ||
191 | } | ||
192 | |||
193 | kexDHReply := kexDHReplyMsg{ | ||
194 | HostKey: hostKeyBytes, | ||
195 | Y: Y, | ||
196 | Signature: sig, | ||
197 | } | ||
198 | packet = Marshal(&kexDHReply) | ||
199 | |||
200 | err = c.writePacket(packet) | ||
201 | return &kexResult{ | ||
202 | H: H, | ||
203 | K: K, | ||
204 | HostKey: hostKeyBytes, | ||
205 | Signature: sig, | ||
206 | Hash: crypto.SHA1, | ||
207 | }, nil | ||
208 | } | ||
209 | |||
210 | // ecdh performs Elliptic Curve Diffie-Hellman key exchange as | ||
211 | // described in RFC 5656, section 4. | ||
212 | type ecdh struct { | ||
213 | curve elliptic.Curve | ||
214 | } | ||
215 | |||
216 | func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { | ||
217 | ephKey, err := ecdsa.GenerateKey(kex.curve, rand) | ||
218 | if err != nil { | ||
219 | return nil, err | ||
220 | } | ||
221 | |||
222 | kexInit := kexECDHInitMsg{ | ||
223 | ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y), | ||
224 | } | ||
225 | |||
226 | serialized := Marshal(&kexInit) | ||
227 | if err := c.writePacket(serialized); err != nil { | ||
228 | return nil, err | ||
229 | } | ||
230 | |||
231 | packet, err := c.readPacket() | ||
232 | if err != nil { | ||
233 | return nil, err | ||
234 | } | ||
235 | |||
236 | var reply kexECDHReplyMsg | ||
237 | if err = Unmarshal(packet, &reply); err != nil { | ||
238 | return nil, err | ||
239 | } | ||
240 | |||
241 | x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey) | ||
242 | if err != nil { | ||
243 | return nil, err | ||
244 | } | ||
245 | |||
246 | // generate shared secret | ||
247 | secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes()) | ||
248 | |||
249 | h := ecHash(kex.curve).New() | ||
250 | magics.write(h) | ||
251 | writeString(h, reply.HostKey) | ||
252 | writeString(h, kexInit.ClientPubKey) | ||
253 | writeString(h, reply.EphemeralPubKey) | ||
254 | K := make([]byte, intLength(secret)) | ||
255 | marshalInt(K, secret) | ||
256 | h.Write(K) | ||
257 | |||
258 | return &kexResult{ | ||
259 | H: h.Sum(nil), | ||
260 | K: K, | ||
261 | HostKey: reply.HostKey, | ||
262 | Signature: reply.Signature, | ||
263 | Hash: ecHash(kex.curve), | ||
264 | }, nil | ||
265 | } | ||
266 | |||
267 | // unmarshalECKey parses and checks an EC key. | ||
268 | func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) { | ||
269 | x, y = elliptic.Unmarshal(curve, pubkey) | ||
270 | if x == nil { | ||
271 | return nil, nil, errors.New("ssh: elliptic.Unmarshal failure") | ||
272 | } | ||
273 | if !validateECPublicKey(curve, x, y) { | ||
274 | return nil, nil, errors.New("ssh: public key not on curve") | ||
275 | } | ||
276 | return x, y, nil | ||
277 | } | ||
278 | |||
279 | // validateECPublicKey checks that the point is a valid public key for | ||
280 | // the given curve. See [SEC1], 3.2.2 | ||
281 | func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool { | ||
282 | if x.Sign() == 0 && y.Sign() == 0 { | ||
283 | return false | ||
284 | } | ||
285 | |||
286 | if x.Cmp(curve.Params().P) >= 0 { | ||
287 | return false | ||
288 | } | ||
289 | |||
290 | if y.Cmp(curve.Params().P) >= 0 { | ||
291 | return false | ||
292 | } | ||
293 | |||
294 | if !curve.IsOnCurve(x, y) { | ||
295 | return false | ||
296 | } | ||
297 | |||
298 | // We don't check if N * PubKey == 0, since | ||
299 | // | ||
300 | // - the NIST curves have cofactor = 1, so this is implicit. | ||
301 | // (We don't foresee an implementation that supports non NIST | ||
302 | // curves) | ||
303 | // | ||
304 | // - for ephemeral keys, we don't need to worry about small | ||
305 | // subgroup attacks. | ||
306 | return true | ||
307 | } | ||
308 | |||
309 | func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { | ||
310 | packet, err := c.readPacket() | ||
311 | if err != nil { | ||
312 | return nil, err | ||
313 | } | ||
314 | |||
315 | var kexECDHInit kexECDHInitMsg | ||
316 | if err = Unmarshal(packet, &kexECDHInit); err != nil { | ||
317 | return nil, err | ||
318 | } | ||
319 | |||
320 | clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey) | ||
321 | if err != nil { | ||
322 | return nil, err | ||
323 | } | ||
324 | |||
325 | // We could cache this key across multiple users/multiple | ||
326 | // connection attempts, but the benefit is small. OpenSSH | ||
327 | // generates a new key for each incoming connection. | ||
328 | ephKey, err := ecdsa.GenerateKey(kex.curve, rand) | ||
329 | if err != nil { | ||
330 | return nil, err | ||
331 | } | ||
332 | |||
333 | hostKeyBytes := priv.PublicKey().Marshal() | ||
334 | |||
335 | serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y) | ||
336 | |||
337 | // generate shared secret | ||
338 | secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes()) | ||
339 | |||
340 | h := ecHash(kex.curve).New() | ||
341 | magics.write(h) | ||
342 | writeString(h, hostKeyBytes) | ||
343 | writeString(h, kexECDHInit.ClientPubKey) | ||
344 | writeString(h, serializedEphKey) | ||
345 | |||
346 | K := make([]byte, intLength(secret)) | ||
347 | marshalInt(K, secret) | ||
348 | h.Write(K) | ||
349 | |||
350 | H := h.Sum(nil) | ||
351 | |||
352 | // H is already a hash, but the hostkey signing will apply its | ||
353 | // own key-specific hash algorithm. | ||
354 | sig, err := signAndMarshal(priv, rand, H) | ||
355 | if err != nil { | ||
356 | return nil, err | ||
357 | } | ||
358 | |||
359 | reply := kexECDHReplyMsg{ | ||
360 | EphemeralPubKey: serializedEphKey, | ||
361 | HostKey: hostKeyBytes, | ||
362 | Signature: sig, | ||
363 | } | ||
364 | |||
365 | serialized := Marshal(&reply) | ||
366 | if err := c.writePacket(serialized); err != nil { | ||
367 | return nil, err | ||
368 | } | ||
369 | |||
370 | return &kexResult{ | ||
371 | H: H, | ||
372 | K: K, | ||
373 | HostKey: reply.HostKey, | ||
374 | Signature: sig, | ||
375 | Hash: ecHash(kex.curve), | ||
376 | }, nil | ||
377 | } | ||
378 | |||
379 | var kexAlgoMap = map[string]kexAlgorithm{} | ||
380 | |||
381 | func init() { | ||
382 | // This is the group called diffie-hellman-group1-sha1 in RFC | ||
383 | // 4253 and Oakley Group 2 in RFC 2409. | ||
384 | p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) | ||
385 | kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ | ||
386 | g: new(big.Int).SetInt64(2), | ||
387 | p: p, | ||
388 | pMinus1: new(big.Int).Sub(p, bigOne), | ||
389 | } | ||
390 | |||
391 | // This is the group called diffie-hellman-group14-sha1 in RFC | ||
392 | // 4253 and Oakley Group 14 in RFC 3526. | ||
393 | p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) | ||
394 | |||
395 | kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{ | ||
396 | g: new(big.Int).SetInt64(2), | ||
397 | p: p, | ||
398 | pMinus1: new(big.Int).Sub(p, bigOne), | ||
399 | } | ||
400 | |||
401 | kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()} | ||
402 | kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()} | ||
403 | kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()} | ||
404 | kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{} | ||
405 | } | ||
406 | |||
407 | // curve25519sha256 implements the curve25519-sha256@libssh.org key | ||
408 | // agreement protocol, as described in | ||
409 | // https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt | ||
410 | type curve25519sha256 struct{} | ||
411 | |||
412 | type curve25519KeyPair struct { | ||
413 | priv [32]byte | ||
414 | pub [32]byte | ||
415 | } | ||
416 | |||
417 | func (kp *curve25519KeyPair) generate(rand io.Reader) error { | ||
418 | if _, err := io.ReadFull(rand, kp.priv[:]); err != nil { | ||
419 | return err | ||
420 | } | ||
421 | curve25519.ScalarBaseMult(&kp.pub, &kp.priv) | ||
422 | return nil | ||
423 | } | ||
424 | |||
425 | // curve25519Zeros is just an array of 32 zero bytes so that we have something | ||
426 | // convenient to compare against in order to reject curve25519 points with the | ||
427 | // wrong order. | ||
428 | var curve25519Zeros [32]byte | ||
429 | |||
430 | func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { | ||
431 | var kp curve25519KeyPair | ||
432 | if err := kp.generate(rand); err != nil { | ||
433 | return nil, err | ||
434 | } | ||
435 | if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil { | ||
436 | return nil, err | ||
437 | } | ||
438 | |||
439 | packet, err := c.readPacket() | ||
440 | if err != nil { | ||
441 | return nil, err | ||
442 | } | ||
443 | |||
444 | var reply kexECDHReplyMsg | ||
445 | if err = Unmarshal(packet, &reply); err != nil { | ||
446 | return nil, err | ||
447 | } | ||
448 | if len(reply.EphemeralPubKey) != 32 { | ||
449 | return nil, errors.New("ssh: peer's curve25519 public value has wrong length") | ||
450 | } | ||
451 | |||
452 | var servPub, secret [32]byte | ||
453 | copy(servPub[:], reply.EphemeralPubKey) | ||
454 | curve25519.ScalarMult(&secret, &kp.priv, &servPub) | ||
455 | if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 { | ||
456 | return nil, errors.New("ssh: peer's curve25519 public value has wrong order") | ||
457 | } | ||
458 | |||
459 | h := crypto.SHA256.New() | ||
460 | magics.write(h) | ||
461 | writeString(h, reply.HostKey) | ||
462 | writeString(h, kp.pub[:]) | ||
463 | writeString(h, reply.EphemeralPubKey) | ||
464 | |||
465 | kInt := new(big.Int).SetBytes(secret[:]) | ||
466 | K := make([]byte, intLength(kInt)) | ||
467 | marshalInt(K, kInt) | ||
468 | h.Write(K) | ||
469 | |||
470 | return &kexResult{ | ||
471 | H: h.Sum(nil), | ||
472 | K: K, | ||
473 | HostKey: reply.HostKey, | ||
474 | Signature: reply.Signature, | ||
475 | Hash: crypto.SHA256, | ||
476 | }, nil | ||
477 | } | ||
478 | |||
479 | func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) { | ||
480 | packet, err := c.readPacket() | ||
481 | if err != nil { | ||
482 | return | ||
483 | } | ||
484 | var kexInit kexECDHInitMsg | ||
485 | if err = Unmarshal(packet, &kexInit); err != nil { | ||
486 | return | ||
487 | } | ||
488 | |||
489 | if len(kexInit.ClientPubKey) != 32 { | ||
490 | return nil, errors.New("ssh: peer's curve25519 public value has wrong length") | ||
491 | } | ||
492 | |||
493 | var kp curve25519KeyPair | ||
494 | if err := kp.generate(rand); err != nil { | ||
495 | return nil, err | ||
496 | } | ||
497 | |||
498 | var clientPub, secret [32]byte | ||
499 | copy(clientPub[:], kexInit.ClientPubKey) | ||
500 | curve25519.ScalarMult(&secret, &kp.priv, &clientPub) | ||
501 | if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 { | ||
502 | return nil, errors.New("ssh: peer's curve25519 public value has wrong order") | ||
503 | } | ||
504 | |||
505 | hostKeyBytes := priv.PublicKey().Marshal() | ||
506 | |||
507 | h := crypto.SHA256.New() | ||
508 | magics.write(h) | ||
509 | writeString(h, hostKeyBytes) | ||
510 | writeString(h, kexInit.ClientPubKey) | ||
511 | writeString(h, kp.pub[:]) | ||
512 | |||
513 | kInt := new(big.Int).SetBytes(secret[:]) | ||
514 | K := make([]byte, intLength(kInt)) | ||
515 | marshalInt(K, kInt) | ||
516 | h.Write(K) | ||
517 | |||
518 | H := h.Sum(nil) | ||
519 | |||
520 | sig, err := signAndMarshal(priv, rand, H) | ||
521 | if err != nil { | ||
522 | return nil, err | ||
523 | } | ||
524 | |||
525 | reply := kexECDHReplyMsg{ | ||
526 | EphemeralPubKey: kp.pub[:], | ||
527 | HostKey: hostKeyBytes, | ||
528 | Signature: sig, | ||
529 | } | ||
530 | if err := c.writePacket(Marshal(&reply)); err != nil { | ||
531 | return nil, err | ||
532 | } | ||
533 | return &kexResult{ | ||
534 | H: H, | ||
535 | K: K, | ||
536 | HostKey: hostKeyBytes, | ||
537 | Signature: sig, | ||
538 | Hash: crypto.SHA256, | ||
539 | }, nil | ||
540 | } | ||