1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
// package dns checks if a domain name is aware of a hashed public key. A
// look-up is performed if the specified domain name matches "^_sigsum_v0.*".
package dns
import (
"context"
"fmt"
"net"
"strings"
"git.sigsum.org/sigsum-go/pkg/hex"
"git.sigsum.org/sigsum-go/pkg/types"
)
const (
prefix = "_sigsum_v0."
)
// Verifier can verify that a domain name is aware of a public key
type Verifier interface {
Verify(ctx context.Context, name string, key *types.PublicKey) error
}
// DefaultResolver implements the Verifier interface with Go's default resolver
type DefaultResolver struct {
resolver net.Resolver
}
func NewDefaultResolver() Verifier {
return &DefaultResolver{}
}
func (dr *DefaultResolver) Verify(ctx context.Context, name string, pub *types.PublicKey) error {
if err := validPrefix(name); err != nil {
return fmt.Errorf("dns: %s", err)
}
rsps, err := dr.resolver.LookupTXT(ctx, name)
if err != nil {
return fmt.Errorf("dns: look-up failed: %s", name)
}
if err := validResponse(pub, rsps); err != nil {
return fmt.Errorf("dns: %s", err)
}
return nil
}
func validResponse(pub *types.PublicKey, rsps []string) error {
keyHash := hex.Serialize(types.HashFn(pub[:])[:])
for _, rsp := range rsps {
if rsp == keyHash {
return nil
}
}
return fmt.Errorf("unknown key hash %s", keyHash)
}
func validPrefix(name string) error {
if !strings.HasPrefix(name, prefix) {
return fmt.Errorf("domain name prefix must be %s", prefix)
}
return nil
}
|