...
1 package va
2
3 import (
4 "context"
5 "crypto/sha256"
6 "crypto/subtle"
7 "encoding/base64"
8 "fmt"
9 "net"
10
11 "github.com/letsencrypt/boulder/core"
12 berrors "github.com/letsencrypt/boulder/errors"
13 "github.com/letsencrypt/boulder/identifier"
14 "github.com/letsencrypt/boulder/probs"
15 )
16
17
18
19
20
21
22
23 func (va ValidationAuthorityImpl) getAddrs(ctx context.Context, hostname string) ([]net.IP, error) {
24 addrs, err := va.dnsClient.LookupHost(ctx, hostname)
25 if err != nil {
26 return nil, berrors.DNSError("%v", err)
27 }
28
29 if len(addrs) == 0 {
30
31
32 return nil, berrors.DNSError("No valid IP addresses found for %s", hostname)
33 }
34 va.log.Debugf("Resolved addresses for %s: %s", hostname, addrs)
35 return addrs, nil
36 }
37
38
39
40 func availableAddresses(allAddrs []net.IP) (v4 []net.IP, v6 []net.IP) {
41 for _, addr := range allAddrs {
42 if addr.To4() != nil {
43 v4 = append(v4, addr)
44 } else {
45 v6 = append(v6, addr)
46 }
47 }
48 return
49 }
50
51 func (va *ValidationAuthorityImpl) validateDNS01(ctx context.Context, ident identifier.ACMEIdentifier, challenge core.Challenge) ([]core.ValidationRecord, *probs.ProblemDetails) {
52 if ident.Type != identifier.DNS {
53 va.log.Infof("Identifier type for DNS challenge was not DNS: %s", ident)
54 return nil, probs.Malformed("Identifier type for DNS was not itself DNS")
55 }
56
57
58 h := sha256.New()
59 h.Write([]byte(challenge.ProvidedKeyAuthorization))
60 authorizedKeysDigest := base64.RawURLEncoding.EncodeToString(h.Sum(nil))
61
62
63 challengeSubdomain := fmt.Sprintf("%s.%s", core.DNSPrefix, ident.Value)
64 txts, err := va.dnsClient.LookupTXT(ctx, challengeSubdomain)
65 if err != nil {
66 return nil, probs.DNS(err.Error())
67 }
68
69
70
71
72 if len(txts) == 0 {
73 return nil, probs.Unauthorized(fmt.Sprintf("No TXT record found at %s", challengeSubdomain))
74 }
75
76 for _, element := range txts {
77 if subtle.ConstantTimeCompare([]byte(element), []byte(authorizedKeysDigest)) == 1 {
78
79 return []core.ValidationRecord{{Hostname: ident.Value}}, nil
80 }
81 }
82
83 invalidRecord := txts[0]
84 if len(invalidRecord) > 100 {
85 invalidRecord = invalidRecord[0:100] + "..."
86 }
87 var andMore string
88 if len(txts) > 1 {
89 andMore = fmt.Sprintf(" (and %d more)", len(txts)-1)
90 }
91 return nil, probs.Unauthorized(fmt.Sprintf("Incorrect TXT record %q%s found at %s",
92 invalidRecord, andMore, challengeSubdomain))
93 }
94
View as plain text