Skip to content

Commit

Permalink
Remove delayed closing of yubikey connection to prevent the connectio…
Browse files Browse the repository at this point in the history
…n from leaking after program execution. (#48549)
  • Loading branch information
Joerger authored Nov 7, 2024
1 parent 6a84965 commit cf9def7
Showing 1 changed file with 11 additions and 19 deletions.
30 changes: 11 additions & 19 deletions api/utils/keys/yubikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ import (
const (
// PIVCardTypeYubiKey is the PIV card type assigned to yubiKeys.
PIVCardTypeYubiKey = "yubikey"

// PIV connections are closed after a short delay so that the program
// has a chance to reclaim the connection before it is closed completely.
releaseConnectionDelay = 5 * time.Second
)

// Cache keys to prevent reconnecting to PIV module to discover a known key.
Expand Down Expand Up @@ -333,8 +329,8 @@ func (y *YubiKeyPrivateKey) sign(ctx context.Context, rand io.Reader, digest []b
defer y.signMux.Unlock()
ctx, cancel := context.WithCancelCause(ctx)

// Lock the connection for the entire duration of the sign process.
// Without this, the connection will be released after releaseConnectionDelay,
// Lock the connection for the entire duration of the sign
// process. Without this, the connection will be released,
// leading to a failure when providing PIN or touch input:
// "verify pin: transmitting request: the supplied handle was invalid".
release, err := y.connect()
Expand Down Expand Up @@ -706,18 +702,14 @@ func (c *sharedPIVConnection) connect() (func(), error) {
defer c.mu.Unlock()

release := func() {
go func() {
time.Sleep(releaseConnectionDelay)

c.mu.Lock()
defer c.mu.Unlock()
c.mu.Lock()
defer c.mu.Unlock()

c.activeConnections--
if c.activeConnections == 0 {
c.conn.Close()
c.conn = nil
}
}()
c.activeConnections--
if c.activeConnections == 0 {
c.conn.Close()
c.conn = nil
}
}

if c.conn != nil {
Expand All @@ -740,8 +732,8 @@ func (c *sharedPIVConnection) connect() (func(), error) {
return nil, trace.Wrap(err)
}

// Backoff and retry for a time slightly greater than releaseConnectionDelay.
retryCtx, cancel := context.WithTimeout(context.Background(), releaseConnectionDelay+100*time.Millisecond)
// Backoff and retry for up to 1 second.
retryCtx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

err = linearRetry.For(retryCtx, func() error {
Expand Down

0 comments on commit cf9def7

Please sign in to comment.