mirror of
https://github.com/warmbly/warmbly.git
synced 2026-10-03 16:02:02 +00:00
50 lines
1.6 KiB
Go
50 lines
1.6 KiB
Go
// Package domainproof derives the DNS TXT value a workspace publishes to prove
|
|
// it controls a domain. The value is keyed by the instance secret and bound to
|
|
// one workspace and one domain, so it cannot be copied from someone else's
|
|
// public DNS or carried to another workspace in an archive.
|
|
package domainproof
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// Label is where the record lives, under the domain.
|
|
const Label = "_warmbly"
|
|
|
|
// Prover derives proof values from the instance secret.
|
|
type Prover struct{ key []byte }
|
|
|
|
// New keys a prover from the instance secret; the secret is never used directly.
|
|
func New(secret string) *Prover {
|
|
sum := sha256.Sum256([]byte("warmbly-domain-proof\x00" + secret))
|
|
return &Prover{key: sum[:]}
|
|
}
|
|
|
|
// Name is the TXT record's host name for a domain.
|
|
func Name(domain string) string {
|
|
return Label + "." + strings.ToLower(strings.TrimSuffix(domain, "."))
|
|
}
|
|
|
|
// Value is the TXT record's content for one workspace and domain.
|
|
func (p *Prover) Value(orgID uuid.UUID, domain string) string {
|
|
mac := hmac.New(sha256.New, p.key)
|
|
mac.Write([]byte(orgID.String() + "|" + strings.ToLower(strings.TrimSuffix(domain, "."))))
|
|
return "warmbly-verify=" + hex.EncodeToString(mac.Sum(nil)[:16])
|
|
}
|
|
|
|
// Matches reports whether any published TXT string is this workspace's proof for the domain.
|
|
func (p *Prover) Matches(txts []string, orgID uuid.UUID, domain string) bool {
|
|
want := p.Value(orgID, domain)
|
|
for _, t := range txts {
|
|
if hmac.Equal([]byte(strings.TrimSpace(t)), []byte(want)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|