ClientDeferred initiates a control client handshake, returning the initial message to send to the server and a continuation to finalize the handshake. ClientDeferred is split in this way for RTT reduction: we run this protocol after negotiating a protocol switch from HTTP/HTTPS. If we completely se
(machineKey key.MachinePrivate, controlKey key.MachinePublic, protocolVersion uint16)
| 66 | // message and a continuation, we can embed the handshake initiation |
| 67 | // into the HTTP protocol switching request and avoid a bit of delay. |
| 68 | func ClientDeferred(machineKey key.MachinePrivate, controlKey key.MachinePublic, protocolVersion uint16) (initialHandshake []byte, continueHandshake HandshakeContinuation, err error) { |
| 69 | var s symmetricState |
| 70 | s.Initialize() |
| 71 | |
| 72 | // prologue |
| 73 | s.MixHash(protocolVersionPrologue(protocolVersion)) |
| 74 | |
| 75 | // <- s |
| 76 | // ... |
| 77 | s.MixHash(controlKey.UntypedBytes()) |
| 78 | |
| 79 | // -> e, es, s, ss |
| 80 | init := mkInitiationMessage(protocolVersion) |
| 81 | machineEphemeral := key.NewMachine() |
| 82 | machineEphemeralPub := machineEphemeral.Public() |
| 83 | copy(init.EphemeralPub(), machineEphemeralPub.UntypedBytes()) |
| 84 | s.MixHash(machineEphemeralPub.UntypedBytes()) |
| 85 | cipher, err := s.MixDH(machineEphemeral, controlKey) |
| 86 | if err != nil { |
| 87 | return nil, nil, fmt.Errorf("computing es: %w", err) |
| 88 | } |
| 89 | machineKeyPub := machineKey.Public() |
| 90 | s.EncryptAndHash(cipher, init.MachinePub(), machineKeyPub.UntypedBytes()) |
| 91 | cipher, err = s.MixDH(machineKey, controlKey) |
| 92 | if err != nil { |
| 93 | return nil, nil, fmt.Errorf("computing ss: %w", err) |
| 94 | } |
| 95 | s.EncryptAndHash(cipher, init.Tag(), nil) // empty message payload |
| 96 | |
| 97 | cont := func(ctx context.Context, conn net.Conn) (*Conn, error) { |
| 98 | return continueClientHandshake(ctx, conn, &s, machineKey, machineEphemeral, controlKey, protocolVersion) |
| 99 | } |
| 100 | return init[:], cont, nil |
| 101 | } |
| 102 | |
| 103 | // Client wraps ClientDeferred and immediately invokes the returned |
| 104 | // continuation with conn. |
no test coverage detected
searching dependent graphs…