Browse Source

move extraction of certificate hashes to a separate function

pull/1737/head
Marten Seemann 2 years ago
parent
commit
3b13c8342d
  1. 26
      p2p/transport/webtransport/multiaddr.go
  2. 47
      p2p/transport/webtransport/multiaddr_test.go
  3. 22
      p2p/transport/webtransport/transport.go
  4. 6
      p2p/transport/webtransport/transport_test.go

26
p2p/transport/webtransport/multiaddr.go

@ -2,12 +2,15 @@ package libp2pwebtransport
import (
"errors"
"fmt"
"net"
"strconv"
ma "github.com/multiformats/go-multiaddr"
mafmt "github.com/multiformats/go-multiaddr-fmt"
manet "github.com/multiformats/go-multiaddr/net"
"github.com/multiformats/go-multibase"
"github.com/multiformats/go-multihash"
)
var webtransportMA = ma.StringCast("/quic/webtransport")
@ -40,3 +43,26 @@ func stringToWebtransportMultiaddr(str string) (ma.Multiaddr, error) {
}
return toWebtransportMultiaddr(&net.UDPAddr{IP: ip, Port: int(port)})
}
func extractCertHashes(addr ma.Multiaddr) ([]multihash.DecodedMultihash, error) {
certHashesStr := make([]string, 0, 2)
ma.ForEach(addr, func(c ma.Component) bool {
if c.Protocol().Code == ma.P_CERTHASH {
certHashesStr = append(certHashesStr, c.Value())
}
return true
})
certHashes := make([]multihash.DecodedMultihash, 0, len(certHashesStr))
for _, s := range certHashesStr {
_, ch, err := multibase.Decode(s)
if err != nil {
return nil, fmt.Errorf("failed to multibase-decode certificate hash: %w", err)
}
dh, err := multihash.Decode(ch)
if err != nil {
return nil, fmt.Errorf("failed to multihash-decode certificate hash: %w", err)
}
certHashes = append(certHashes, *dh)
}
return certHashes, nil
}

47
p2p/transport/webtransport/multiaddr_test.go

@ -1,9 +1,13 @@
package libp2pwebtransport
import (
"fmt"
"net"
"testing"
ma "github.com/multiformats/go-multiaddr"
"github.com/multiformats/go-multibase"
"github.com/multiformats/go-multihash"
"github.com/stretchr/testify/require"
)
@ -39,3 +43,46 @@ func TestWebtransportMultiaddrFromString(t *testing.T) {
}
})
}
func encodeCertHash(t *testing.T, b []byte, mh uint64, mb multibase.Encoding) string {
t.Helper()
h, err := multihash.Encode(b, mh)
require.NoError(t, err)
str, err := multibase.Encode(mb, h)
require.NoError(t, err)
return str
}
func TestExtractCertHashes(t *testing.T) {
fooHash := encodeCertHash(t, []byte("foo"), multihash.SHA2_256, multibase.Base58BTC)
barHash := encodeCertHash(t, []byte("bar"), multihash.BLAKE2B_MAX, multibase.Base32)
// valid cases
for _, tc := range [...]struct {
addr string
hashes []string
}{
{addr: "/ip4/127.0.0.1/udp/1234/quic/webtransport"},
{addr: fmt.Sprintf("/ip4/127.0.0.1/udp/1234/quic/webtransport/certhash/%s", fooHash), hashes: []string{"foo"}},
{addr: fmt.Sprintf("/ip4/127.0.0.1/udp/1234/quic/webtransport/certhash/%s/certhash/%s", fooHash, barHash), hashes: []string{"foo", "bar"}},
} {
ch, err := extractCertHashes(ma.StringCast(tc.addr))
require.NoError(t, err)
require.Len(t, ch, len(tc.hashes))
for i, h := range tc.hashes {
require.Equal(t, h, string(ch[i].Digest))
}
}
// invalid cases
for _, tc := range [...]struct {
addr string
err string
}{
{addr: fmt.Sprintf("/ip4/127.0.0.1/udp/1234/quic/webtransport/certhash/%s", fooHash[:len(fooHash)-1]), err: "failed to multihash-decode certificate hash"},
} {
_, err := extractCertHashes(ma.StringCast(tc.addr))
require.Error(t, err)
require.Contains(t, err.Error(), tc.err)
}
}

22
p2p/transport/webtransport/transport.go

@ -22,7 +22,6 @@ import (
"github.com/marten-seemann/webtransport-go"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
"github.com/multiformats/go-multibase"
"github.com/multiformats/go-multihash"
)
@ -99,24 +98,9 @@ func (t *transport) dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tp
return nil, err
}
url := fmt.Sprintf("https://%s%s", addr, webtransportHTTPEndpoint)
certHashesStr := make([]string, 0, 2)
ma.ForEach(raddr, func(c ma.Component) bool {
if c.Protocol().Code == ma.P_CERTHASH {
certHashesStr = append(certHashesStr, c.Value())
}
return true
})
var certHashes []multihash.DecodedMultihash
for _, s := range certHashesStr {
_, ch, err := multibase.Decode(s)
if err != nil {
return nil, fmt.Errorf("failed to multibase-decode certificate hash: %w", err)
}
dh, err := multihash.Decode(ch)
if err != nil {
return nil, fmt.Errorf("failed to multihash-decode certificate hash: %w", err)
}
certHashes = append(certHashes, *dh)
certHashes, err := extractCertHashes(raddr)
if err != nil {
return nil, err
}
rsp, wconn, err := t.dialer.Dial(ctx, url, nil)
if err != nil {

6
p2p/transport/webtransport/transport_test.go

@ -42,7 +42,7 @@ func randomMultihash(t *testing.T) string {
return s
}
func extractCertHashes(t *testing.T, addr ma.Multiaddr) []string {
func extractCertHashes(addr ma.Multiaddr) []string {
var certHashesStr []string
ma.ForEach(addr, func(c ma.Component) bool {
if c.Protocol().Code == ma.P_CERTHASH {
@ -208,9 +208,9 @@ func TestListenerAddrs(t *testing.T) {
require.NoError(t, err)
ln2, err := tr.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic/webtransport"))
require.NoError(t, err)
hashes1 := extractCertHashes(t, ln1.Multiaddr())
hashes1 := extractCertHashes(ln1.Multiaddr())
require.Len(t, hashes1, 1)
hashes2 := extractCertHashes(t, ln2.Multiaddr())
hashes2 := extractCertHashes(ln2.Multiaddr())
require.Equal(t, hashes1, hashes2)
}

Loading…
Cancel
Save