Skip to content

Commit

Permalink
fix(httpauth): each request gets its own hmac
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoPolo committed Dec 18, 2024
1 parent e2df0f0 commit d3f96df
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
17 changes: 6 additions & 11 deletions p2p/http/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ package httppeeridauth

import (
"bytes"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/tls"
"hash"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -172,14 +169,12 @@ func TestMutualAuth(t *testing.T) {

t.Run("Tokens Invalidated", func(t *testing.T) {
// Clear the auth token on the server side
server.Hmac = func() hash.Hash {
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
panic(err)
}
return hmac.New(sha256.New, key)
}()
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
panic(err)
}
server.hmacPool = newHmacPool(key)

req, err := http.NewRequest("POST", ts.URL, nil)
req.GetBody = func() (io.ReadCloser, error) {
Expand Down
38 changes: 33 additions & 5 deletions p2p/http/auth/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,29 @@ import (
"github.com/libp2p/go-libp2p/p2p/http/auth/internal/handshake"
)

type hmacPool struct {
p sync.Pool
}

func newHmacPool(key []byte) *hmacPool {
return &hmacPool{
p: sync.Pool{
New: func() any {
return hmac.New(sha256.New, key)
},
},
}
}

func (p *hmacPool) Get() hash.Hash {
return p.p.Get().(hash.Hash)
}

func (p *hmacPool) Put(h hash.Hash) {
h.Reset()
p.p.Put(h)
}

type ServerPeerIDAuth struct {
PrivKey crypto.PrivKey
TokenTTL time.Duration
Expand All @@ -26,8 +49,9 @@ type ServerPeerIDAuth struct {
// which the Host header returns true.
ValidHostnameFn func(hostname string) bool

Hmac hash.Hash
HmacKey []byte
initHmac sync.Once
hmacPool *hmacPool
}

// ServeHTTP implements the http.Handler interface for PeerIDAuth. It will
Expand All @@ -36,14 +60,15 @@ type ServerPeerIDAuth struct {
// requests.
func (a *ServerPeerIDAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
a.initHmac.Do(func() {
if a.Hmac == nil {
if a.HmacKey == nil {
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
panic(err)
}
a.Hmac = hmac.New(sha256.New, key)
a.HmacKey = key
}
a.hmacPool = newHmacPool(a.HmacKey)
})

hostname := r.Host
Expand Down Expand Up @@ -76,11 +101,13 @@ func (a *ServerPeerIDAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}

hmac := a.hmacPool.Get()
defer a.hmacPool.Put(hmac)
hs := handshake.PeerIDAuthHandshakeServer{
Hostname: hostname,
PrivKey: a.PrivKey,
TokenTTL: a.TokenTTL,
Hmac: a.Hmac,
Hmac: hmac,
}
err := hs.ParseHeaderVal([]byte(r.Header.Get("Authorization")))
if err != nil {
Expand All @@ -95,11 +122,12 @@ func (a *ServerPeerIDAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
errors.Is(err, handshake.ErrExpiredChallenge),
errors.Is(err, handshake.ErrExpiredToken):

hmac.Reset()
hs := handshake.PeerIDAuthHandshakeServer{
Hostname: hostname,
PrivKey: a.PrivKey,
TokenTTL: a.TokenTTL,
Hmac: a.Hmac,
Hmac: hmac,
}
hs.Run()
hs.SetHeader(w.Header())
Expand Down

0 comments on commit d3f96df

Please sign in to comment.