Skip to content
File

Blob: acme/solver.go

go60 lines
1package acme
2 
3import (
4 "context"
5 "fmt"
6 "slices"
7 
8 acmeSpec "go.miragespace.co/specter/spec/acme"
9 "go.miragespace.co/specter/spec/chord"
10 "go.miragespace.co/specter/spec/tun"
11 
12 "github.com/mholt/acmez/v3"
13 "github.com/mholt/acmez/v3/acme"
14)
15 
16type ChordSolver struct {
17 KV chord.KV
18 ManagedDomains []string
19}
20 
21var _ acmez.Solver = (*ChordSolver)(nil)
22 
23func (s *ChordSolver) isManaged(zone string) bool {
24 return slices.Contains(s.ManagedDomains, zone)
25}
26 
27func (s *ChordSolver) getSubdomain(ctx context.Context, zone string) (string, error) {
28 if s.isManaged(zone) {
29 return acmeSpec.ManagedDelegation, nil
30 }
31 bundle, err := tun.FindCustomHostname(ctx, s.KV, zone)
32 if err != nil {
33 return "", err
34 }
35 token := bundle.GetClientToken().GetToken()
36 return acmeSpec.EncodeClientToken(token), nil
37}
38 
39func (s *ChordSolver) Present(ctx context.Context, chal acme.Challenge) error {
40 if chal.Identifier.Type != "dns" {
41 return fmt.Errorf("dns: unexpected challenge type: %s", chal.Identifier.Type)
42 }
43 subdomain, err := s.getSubdomain(ctx, chal.Identifier.Value)
44 if err != nil {
45 return err
46 }
47 return s.KV.PrefixAppend(ctx, []byte(dnsKeyName(subdomain)), []byte(chal.DNS01KeyAuthorization()))
48}
49 
50func (s *ChordSolver) CleanUp(ctx context.Context, chal acme.Challenge) error {
51 if chal.Identifier.Type != "dns" {
52 return fmt.Errorf("dns: unexpected challenge type: %s", chal.Identifier.Type)
53 }
54 subdomain, err := s.getSubdomain(ctx, chal.Identifier.Value)
55 if err != nil {
56 return err
57 }
58 return s.KV.PrefixRemove(ctx, []byte(dnsKeyName(subdomain)), []byte(chal.DNS01KeyAuthorization()))
59}