Skip to content

[QUIC] Implement 0-RTT session ticket storage and restoration #402

Description

@kcenon

Summary

Implement complete 0-RTT (Zero Round Trip Time) session resumption support including session ticket storage, restoration, and early data handling.

Current State

  • Configuration option exists: quic_client_config::enable_early_data
  • Packet-level 0-RTT support exists: packet_type::zero_rtt
  • Missing: Session ticket persistence and restoration mechanism

Current config:

struct quic_client_config {
    bool enable_early_data{false};
    std::optional<std::vector<uint8_t>> session_ticket;  // Not used
};

RFC Requirements

RFC 9001 Section 4.6: 0-RTT

  • Client saves session ticket from previous connection
  • Client sends early data in 0-RTT packets
  • Server validates ticket and accepts/rejects early data
  • Replay protection must be considered

Proposed Implementation

1. Session Ticket Storage

class session_ticket_store {
public:
    struct ticket_info {
        std::vector<uint8_t> ticket_data;
        std::chrono::system_clock::time_point expiry;
        std::string server_name;  // For SNI matching
        transport_parameters saved_params;
    };
    
    auto store(const std::string& server, const ticket_info& ticket) -> void;
    auto retrieve(const std::string& server) -> std::optional<ticket_info>;
    auto remove(const std::string& server) -> void;
    auto cleanup_expired() -> void;
    
private:
    std::unordered_map<std::string, ticket_info> tickets_;
    std::mutex mutex_;
};

2. Client-side 0-RTT Flow

auto quic_client::connect_with_0rtt(const std::string& host) -> VoidResult {
    // 1. Check for stored session ticket
    auto ticket = ticket_store_.retrieve(host);
    if (!ticket) {
        return connect_1rtt(host);  // Fallback to 1-RTT
    }
    
    // 2. Validate ticket expiry
    if (ticket->expiry < std::chrono::system_clock::now()) {
        ticket_store_.remove(host);
        return connect_1rtt(host);
    }
    
    // 3. Setup early data encryption
    auto keys = derive_0rtt_keys(ticket->ticket_data);
    
    // 4. Send early data
    if (early_data_callback_) {
        auto early_data = early_data_callback_();
        send_0rtt_data(early_data);
    }
    
    // 5. Complete handshake
    return complete_handshake_with_0rtt();
}

3. Server-side Acceptance

auto quic_server::handle_0rtt_packet(const packet& pkt) -> VoidResult {
    // 1. Validate session ticket
    auto ticket = validate_ticket(pkt.dcid);
    if (!ticket) {
        return reject_0rtt();
    }
    
    // 2. Check replay protection
    if (replay_filter_.check(pkt)) {
        return reject_0rtt();
    }
    
    // 3. Accept early data
    accept_0rtt(ticket);
    
    return common::ok();
}

4. Callbacks for Early Data

class messaging_quic_client {
public:
    using early_data_callback_t = std::function<std::vector<uint8_t>()>;
    using early_data_accepted_callback_t = std::function<void(bool)>;
    
    void set_early_data_callback(early_data_callback_t cb);
    void set_early_data_accepted_callback(early_data_accepted_callback_t cb);
};

Security Considerations

  • Implement replay protection for 0-RTT data
  • Limit what data can be sent in 0-RTT (idempotent operations only)
  • Consider anti-replay mechanisms (token-based, time-based)

Tasks

  • Implement session_ticket_store class
  • Add session ticket capture from TLS handshake
  • Implement 0-RTT key derivation
  • Add early data sending in client
  • Implement server-side ticket validation
  • Add replay protection mechanism
  • Implement early data callbacks
  • Add persistent ticket storage option (file-based)
  • Unit tests for session ticket management
  • E2E tests for 0-RTT resumption

Acceptance Criteria

  • Session tickets saved after successful handshake
  • Subsequent connections use 0-RTT when ticket available
  • Early data sent and received correctly
  • Fallback to 1-RTT when ticket expired/invalid
  • Replay protection prevents replay attacks
  • Performance improvement measurable (latency reduction)

Files to Create/Modify

  • New: include/kcenon/network/protocols/quic/session_ticket_store.h
  • New: src/protocols/quic/session_ticket_store.cpp
  • Modify: src/core/messaging_quic_client.cpp
  • Modify: src/core/messaging_quic_server.cpp
  • Modify: src/protocols/quic/crypto.cpp
  • New: tests/test_quic_0rtt.cpp

Related

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions