diff options
author | Rasmus Dahlberg <rasmus@mullvad.net> | 2022-03-26 15:52:05 +0100 |
---|---|---|
committer | Linus Nordberg <linus@nordberg.se> | 2022-03-28 16:33:08 +0200 |
commit | 50564595a70f2c2ea0ad4a9b4b96e33bab6b3633 (patch) | |
tree | 9adcad91c3d46a305f16191ce66472131db1b2fb /pkg/dns/dns.go | |
parent | 93542012e45cfa53964a7160969db30fc36229b2 (diff) |
add dns package
Mostly imported from sigsum-log-go. Added strict domain hint parsing,
two tests, and an example. This should be part of the sigsum-go lib
because some client tooling may also want to check domain hints.
Diffstat (limited to 'pkg/dns/dns.go')
-rw-r--r-- | pkg/dns/dns.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/pkg/dns/dns.go b/pkg/dns/dns.go new file mode 100644 index 0000000..3bc0583 --- /dev/null +++ b/pkg/dns/dns.go @@ -0,0 +1,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-lib-go/pkg/hex" + "git.sigsum.org/sigsum-lib-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 +} |