• Martin Thomson's avatar
    Bug 1543874 - Use an external clock for SSL functions, r=ekr,kevinjacobs · 7de04fb4
    Martin Thomson authored
    Summary:
    This adds a new (experimental) API that allows users of libssl to provide their
    own clock function.  This is primarily of use in testing, but it also enables
    our QUIC implementation, which also runs off an external clock.
    
    SSL Sockets (and session IDs, when they are in memory) now have a "now()"
    function and void* arg attached to them.  By default, this is a function that
    calls PR_Now().  These values are copied from the socket to any session ID that
    is created from the socket, and to any session ID that is restored from the
    session cache.
    
    The ssl_Time() and ssl_TimeUsec() functions have been removed.
    
    As part of this, the experimental SSL_SetupAntiReplay() function had to be
    modified to take an external clock (PR_Now() suffices generally).  That function
    relies on knowing the time, and it doesn't have a socket to work from.  To avoid
    problems arising from the change in the signature, SSL_SetupAntiReplay is now
    removed.
    
    There are now three uses of time in the library:
    
    * The primary source of time runs of these newly added functions.  This governs
      session expiry, 0-RTT checks, and related functions.
    
    * The session cache uses a separate time to manage its locking.  This is of type
      PRUint32 in seconds (rather than PRTime in microseconds).  In investigating
      this, I found several places where this time in seconds was leaking across to
      the main functions via the lastAccessTime property.  That was fixed.  The
      cache functions that use time now all call ssl_CacheNow() to get time.
    
    * DTLS timers run using PRIntervalTime.  This is a little annoying and these
      could be made to use the main time source, but that would result in
      conversions between PRTime and PRIntervalTime at the DTLS API.  PRIntervalTime
      has a different epoch to PRTime, so this would be a little awkward.
    
    Only the first of these can be controlled using the new API.
    
    Bugs found:
    
    * Expiration time of resumption tokens was based on the sid->expirationTime,
      which didn't account for the lifetime provided by the server.  These are now
      capped by the minimum of ssl_ticket_lifetime and the value the server
      indicates.
    
      I removed ssl3_sid_timeout, the old limit, because inconsistent lifetimes
      between client and server messed with tests.  The client would have a lower
      cap than the server, which prevented testing of the enforcement of server
      limits without jumping through hoops.
    
    * There was a missing time conversion in tls13_InWindow which made the window
      checks too lenient.
    
    * lastAccessTime was being set to seconds-since-epoch instead of
      microseconds-since-epoch in a few places.
    
    Reviewers: ekr, KevinJacobs
    
    Reviewed By: KevinJacobs
    
    Subscribers: cjpatton
    
    Bug #: 1543874
    
    Differential Revision: https://phabricator.services.mozilla.com/D27238
    
    --HG--
    extra : rebase_source : 3317ecc00f37fc09f0e7c36e947dcd162d1d258a
    extra : amend_source : cf2bfb90a05911e0a0cc76bd377d99ccca8e1900
    7de04fb4