11package kamune
22
33import (
4- "crypto/subtle"
54 "fmt"
65 "log/slog"
76 "net"
87 "runtime/debug"
98 "time"
109
1110 "github.com/xtaci/kcp-go/v5"
12- "google.golang.org/protobuf/proto"
1311
14- "github.com/kamune-org/kamune/internal/box/pb"
1512 "github.com/kamune-org/kamune/pkg/attest"
1613 "github.com/kamune-org/kamune/pkg/fingerprint"
1714)
@@ -239,146 +236,22 @@ func (d *Dialer) attemptResumption(state *SessionState) (*Transport, error) {
239236 d .conn = c
240237 }
241238
242- // Generate a challenge for the server to prove it has the shared secret
243- challenge := randomBytes (resumeChallengeSize )
244-
245- // Create and send reconnect request
246- req := & pb.ReconnectRequest {
247- SessionId : state .SessionID ,
248- LastPhase : state .Phase .ToProto (),
249- LastSendSequence : state .SendSequence ,
250- LastRecvSequence : state .RecvSequence ,
251- RemotePublicKey : d .attester .PublicKey ().Marshal (),
252- ResumeChallenge : challenge ,
253- }
254- if err := d .sendSignedMessage (req , RouteReconnect ); err != nil {
255- return nil , fmt .Errorf ("sending reconnect request: %w" , err )
256- }
257-
258- // Receive response
259- respPayload , err := d .conn .ReadBytes ()
260- if err != nil {
261- return nil , fmt .Errorf ("reading reconnect response: %w" , err )
262- }
263-
264- var respST pb.SignedTransport
265- if err := proto .Unmarshal (respPayload , & respST ); err != nil {
266- return nil , fmt .Errorf ("unmarshaling response transport: %w" , err )
267- }
268-
269- // Verify signature from the server
270- remoteKey , err := d .storage .algorithm .Identitfier ().ParsePublicKey (
271- state .RemotePublicKey ,
272- )
273- if err != nil {
274- return nil , fmt .Errorf ("parsing remote public key: %w" , err )
275- }
276-
277- if ! d .storage .algorithm .Identitfier ().Verify (
278- remoteKey , respST .Data , respST .Signature ,
279- ) {
280- return nil , ErrInvalidSignature
281- }
282-
283- var resp pb.ReconnectResponse
284- if err := proto .Unmarshal (respST .Data , & resp ); err != nil {
285- return nil , fmt .Errorf ("unmarshaling response: %w" , err )
286- }
287-
288- if ! resp .Accepted {
289- return nil , fmt .Errorf ("%w: %s" , ErrResumptionFailed , resp .ErrorMessage )
290- }
291-
292- // Verify the server's challenge response
239+ // Delegate the entire challenge-response protocol to SessionResumer.
293240 resumer := NewSessionResumer (
294241 d .storage ,
295242 d .sessionManager ,
296243 d .attester ,
297244 d .resumptionConfig .MaxSessionAge ,
298245 )
299- expectedResponse , err := resumer .computeChallengeResponse (
300- challenge , state .SharedSecret ,
301- )
302- if err != nil {
303- return nil , fmt .Errorf ("compute expected challenge response: %w" , err )
304- }
305- if subtle .ConstantTimeCompare (resp .ChallengeResponse , expectedResponse ) != 1 {
306- return nil , ErrChallengeVerifyFailed
307- }
308-
309- // Compute our response to the server's challenge
310- clientChallengeResponse , err := resumer .computeChallengeResponse (
311- resp .ServerChallenge , state .SharedSecret ,
312- )
313- if err != nil {
314- return nil , fmt .Errorf ("compute client challenge response: %w" , err )
315- }
316-
317- // Determine the sequence numbers to use
318- resumeSendSeq , resumeRecvSeq := resumer .reconcileSequences (
319- state .SendSequence ,
320- state .RecvSequence ,
321- resp .ServerRecvSequence ,
322- resp .ServerSendSequence ,
323- )
324246
325- // Send verification
326- verify := & pb.ReconnectVerify {
327- ChallengeResponse : clientChallengeResponse ,
328- Verified : true ,
329- }
330- if err := d .sendSignedMessage (verify , RouteReconnect ); err != nil {
331- return nil , fmt .Errorf ("sending verification: %w" , err )
332- }
333-
334- // Receive completion
335- completePayload , err := d .conn .ReadBytes ()
247+ transport , err := resumer .InitiateResumption (d .conn , state )
336248 if err != nil {
337- return nil , fmt .Errorf ("reading completion: %w" , err )
338- }
339-
340- var completeST pb.SignedTransport
341- if err := proto .Unmarshal (completePayload , & completeST ); err != nil {
342- return nil , fmt .Errorf ("unmarshaling completion transport: %w" , err )
343- }
344-
345- if ! d .storage .algorithm .Identitfier ().Verify (
346- remoteKey , completeST .Data , completeST .Signature ,
347- ) {
348- return nil , ErrInvalidSignature
349- }
350-
351- var complete pb.ReconnectComplete
352- if err := proto .Unmarshal (completeST .Data , & complete ); err != nil {
353- return nil , fmt .Errorf ("unmarshaling completion: %w" , err )
354- }
355-
356- if ! complete .Success {
357- return nil , fmt .Errorf (
358- "%w: %s" , ErrResumptionFailed , complete .ErrorMessage ,
359- )
360- }
361-
362- // Use the agreed-upon sequence numbers
363- if complete .ResumeSendSequence > 0 {
364- resumeSendSeq = complete .ResumeSendSequence
365- }
366- if complete .ResumeRecvSequence > 0 {
367- resumeRecvSeq = complete .ResumeRecvSequence
368- }
369-
370- // Restore the transport
371- transport , err := resumer .restoreTransport (
372- d .conn , state , resumeSendSeq , resumeRecvSeq ,
373- )
374- if err != nil {
375- return nil , fmt .Errorf ("restoring transport: %w" , err )
249+ return nil , fmt .Errorf ("initiating resumption: %w" , err )
376250 }
377251
378252 // Update session state
379253 if d .resumptionConfig .PersistSessions {
380- err := SaveSessionForResumption (transport , d .sessionManager )
381- if err != nil {
254+ if err := SaveSessionForResumption (transport , d .sessionManager ); err != nil {
382255 slog .Warn (
383256 "failed to update session after resumption" ,
384257 slog .Any ("error" , err ),
@@ -389,32 +262,6 @@ func (d *Dialer) attemptResumption(state *SessionState) (*Transport, error) {
389262 return transport , nil
390263}
391264
392- func (d * Dialer ) sendSignedMessage (msg Transferable , route Route ) error {
393- data , err := proto .Marshal (msg )
394- if err != nil {
395- return fmt .Errorf ("marshaling message: %w" , err )
396- }
397-
398- sig , err := d .attester .Sign (data )
399- if err != nil {
400- return fmt .Errorf ("signing message: %w" , err )
401- }
402-
403- st := & pb.SignedTransport {
404- Data : data ,
405- Signature : sig ,
406- Padding : padding (maxPadding ),
407- Route : route .ToProto (),
408- }
409-
410- payload , err := proto .Marshal (st )
411- if err != nil {
412- return fmt .Errorf ("marshaling transport: %w" , err )
413- }
414-
415- return d .conn .WriteBytes (payload )
416- }
417-
418265// PublicKey returns the dialer's public key.
419266func (d * Dialer ) PublicKey () PublicKey {
420267 return d .attester .PublicKey ()
0 commit comments