...
1 package acme
2
3 import (
4 "errors"
5 "fmt"
6 mrand "math/rand"
7 "strings"
8
9 "github.com/letsencrypt/boulder/core"
10 )
11
12
13
14 type ChallengeStrategy interface {
15 PickChallenge(*core.Authorization) (*core.Challenge, error)
16 }
17
18 const (
19
20
21 RandomChallengeStrategy = "RANDOM"
22
23
24 HTTP01ChallengeStrategy = "HTTP-01"
25 DNS01ChallengeStrategy = "DNS-01"
26 TLSALPN01ChallengeStrategy = "TLS-ALPN-01"
27 )
28
29
30
31 func NewChallengeStrategy(rawName string) (ChallengeStrategy, error) {
32 var preferredType core.AcmeChallenge
33 switch name := strings.ToUpper(rawName); name {
34 case RandomChallengeStrategy:
35 return &randomChallengeStrategy{}, nil
36 case HTTP01ChallengeStrategy:
37 preferredType = core.ChallengeTypeHTTP01
38 case DNS01ChallengeStrategy:
39 preferredType = core.ChallengeTypeDNS01
40 case TLSALPN01ChallengeStrategy:
41 preferredType = core.ChallengeTypeTLSALPN01
42 default:
43 return nil, fmt.Errorf("ChallengeStrategy %q unknown", name)
44 }
45
46 return &preferredTypeChallengeStrategy{
47 preferredType: preferredType,
48 }, nil
49 }
50
51 var (
52 ErrPickChallengeNilAuthz = errors.New("PickChallenge: provided authorization can not be nil")
53 ErrPickChallengeAuthzMissingChallenges = errors.New("PickChallenge: provided authorization had no challenges")
54 )
55
56
57
58 type randomChallengeStrategy struct {
59 }
60
61
62
63 func (strategy randomChallengeStrategy) PickChallenge(authz *core.Authorization) (*core.Challenge, error) {
64 if authz == nil {
65 return nil, ErrPickChallengeNilAuthz
66 }
67 if len(authz.Challenges) == 0 {
68 return nil, ErrPickChallengeAuthzMissingChallenges
69 }
70 return &authz.Challenges[mrand.Intn(len(authz.Challenges))], nil
71 }
72
73
74
75
76 type preferredTypeChallengeStrategy struct {
77 preferredType core.AcmeChallenge
78 }
79
80
81
82
83 func (strategy preferredTypeChallengeStrategy) PickChallenge(authz *core.Authorization) (*core.Challenge, error) {
84 if authz == nil {
85 return nil, ErrPickChallengeNilAuthz
86 }
87 if len(authz.Challenges) == 0 {
88 return nil, ErrPickChallengeAuthzMissingChallenges
89 }
90 for _, chall := range authz.Challenges {
91 if chall.Type == strategy.preferredType {
92 return &chall, nil
93 }
94 }
95 return nil, fmt.Errorf("authorization (ID %q) had no %q type challenge",
96 authz.ID,
97 strategy.preferredType)
98 }
99
View as plain text