1 package ra
2
3 import (
4 "context"
5 "crypto"
6 "crypto/x509"
7 "encoding/json"
8 "errors"
9 "fmt"
10 "math/big"
11 "net"
12 "net/url"
13 "os"
14 "slices"
15 "sort"
16 "strconv"
17 "strings"
18 "sync"
19 "time"
20
21 "github.com/jmhodges/clock"
22 "github.com/prometheus/client_golang/prometheus"
23 "github.com/weppos/publicsuffix-go/publicsuffix"
24 "golang.org/x/crypto/ocsp"
25 "google.golang.org/grpc"
26 "google.golang.org/protobuf/proto"
27 "google.golang.org/protobuf/types/known/durationpb"
28 "google.golang.org/protobuf/types/known/emptypb"
29 "google.golang.org/protobuf/types/known/timestamppb"
30 "gopkg.in/go-jose/go-jose.v2"
31
32 "github.com/letsencrypt/boulder/akamai"
33 akamaipb "github.com/letsencrypt/boulder/akamai/proto"
34 capb "github.com/letsencrypt/boulder/ca/proto"
35 "github.com/letsencrypt/boulder/core"
36 corepb "github.com/letsencrypt/boulder/core/proto"
37 csrlib "github.com/letsencrypt/boulder/csr"
38 "github.com/letsencrypt/boulder/ctpolicy"
39 berrors "github.com/letsencrypt/boulder/errors"
40 "github.com/letsencrypt/boulder/features"
41 "github.com/letsencrypt/boulder/goodkey"
42 bgrpc "github.com/letsencrypt/boulder/grpc"
43 "github.com/letsencrypt/boulder/identifier"
44 "github.com/letsencrypt/boulder/issuance"
45 blog "github.com/letsencrypt/boulder/log"
46 "github.com/letsencrypt/boulder/metrics"
47 "github.com/letsencrypt/boulder/policy"
48 "github.com/letsencrypt/boulder/probs"
49 pubpb "github.com/letsencrypt/boulder/publisher/proto"
50 rapb "github.com/letsencrypt/boulder/ra/proto"
51 "github.com/letsencrypt/boulder/ratelimit"
52 "github.com/letsencrypt/boulder/ratelimits"
53 "github.com/letsencrypt/boulder/revocation"
54 sapb "github.com/letsencrypt/boulder/sa/proto"
55 vapb "github.com/letsencrypt/boulder/va/proto"
56 "github.com/letsencrypt/boulder/web"
57 )
58
59 var (
60 errIncompleteGRPCRequest = errors.New("incomplete gRPC request message")
61 errIncompleteGRPCResponse = errors.New("incomplete gRPC response message")
62
63
64
65
66
67 caaRecheckDuration = -7 * time.Hour
68 )
69
70 type caaChecker interface {
71 IsCAAValid(
72 ctx context.Context,
73 in *vapb.IsCAAValidRequest,
74 opts ...grpc.CallOption,
75 ) (*vapb.IsCAAValidResponse, error)
76 }
77
78
79
80
81
82 type RegistrationAuthorityImpl struct {
83 rapb.UnimplementedRegistrationAuthorityServer
84 CA capb.CertificateAuthorityClient
85 OCSP capb.OCSPGeneratorClient
86 VA vapb.VAClient
87 SA sapb.StorageAuthorityClient
88 PA core.PolicyAuthority
89 publisher pubpb.PublisherClient
90 caa caaChecker
91
92 clk clock.Clock
93 log blog.Logger
94 keyPolicy goodkey.KeyPolicy
95
96 authorizationLifetime time.Duration
97 pendingAuthorizationLifetime time.Duration
98 rlPolicies ratelimit.Limits
99 maxContactsPerReg int
100 maxNames int
101 orderLifetime time.Duration
102 finalizeTimeout time.Duration
103 finalizeWG sync.WaitGroup
104
105 issuersByNameID map[issuance.IssuerNameID]*issuance.Certificate
106 issuersByID map[issuance.IssuerID]*issuance.Certificate
107 purger akamaipb.AkamaiPurgerClient
108
109 ctpolicy *ctpolicy.CTPolicy
110
111 ctpolicyResults *prometheus.HistogramVec
112 revocationReasonCounter *prometheus.CounterVec
113 namesPerCert *prometheus.HistogramVec
114 rlCheckLatency *prometheus.HistogramVec
115 rlOverrideUsageGauge *prometheus.GaugeVec
116 newRegCounter prometheus.Counter
117 recheckCAACounter prometheus.Counter
118 newCertCounter prometheus.Counter
119 recheckCAAUsedAuthzLifetime prometheus.Counter
120 authzAges *prometheus.HistogramVec
121 orderAges *prometheus.HistogramVec
122 inflightFinalizes prometheus.Gauge
123 }
124
125
126 func NewRegistrationAuthorityImpl(
127 clk clock.Clock,
128 logger blog.Logger,
129 stats prometheus.Registerer,
130 maxContactsPerReg int,
131 keyPolicy goodkey.KeyPolicy,
132 maxNames int,
133 authorizationLifetime time.Duration,
134 pendingAuthorizationLifetime time.Duration,
135 pubc pubpb.PublisherClient,
136 caaClient caaChecker,
137 orderLifetime time.Duration,
138 finalizeTimeout time.Duration,
139 ctp *ctpolicy.CTPolicy,
140 purger akamaipb.AkamaiPurgerClient,
141 issuers []*issuance.Certificate,
142 ) *RegistrationAuthorityImpl {
143 ctpolicyResults := prometheus.NewHistogramVec(
144 prometheus.HistogramOpts{
145 Name: "ctpolicy_results",
146 Help: "Histogram of latencies of ctpolicy.GetSCTs calls with success/failure/deadlineExceeded labels",
147 Buckets: metrics.InternetFacingBuckets,
148 },
149 []string{"result"},
150 )
151 stats.MustRegister(ctpolicyResults)
152
153 namesPerCert := prometheus.NewHistogramVec(
154 prometheus.HistogramOpts{
155 Name: "names_per_cert",
156 Help: "Histogram of the number of SANs in requested and issued certificates",
157
158
159 Buckets: []float64{1, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100},
160 },
161
162 []string{"type"},
163 )
164 stats.MustRegister(namesPerCert)
165
166 rlCheckLatency := prometheus.NewHistogramVec(prometheus.HistogramOpts{
167 Name: "ratelimitsv1_check_latency_seconds",
168 Help: fmt.Sprintf("Latency of ratelimit checks labeled by limit=[name] and decision=[%s|%s], in seconds", ratelimits.Allowed, ratelimits.Denied),
169 }, []string{"limit", "decision"})
170 stats.MustRegister(rlCheckLatency)
171
172 overrideUsageGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
173 Name: "ratelimitsv1_override_usage",
174 Help: "Proportion of override limit used, by limit name and client identifier.",
175 }, []string{"limit", "override_key"})
176 stats.MustRegister(overrideUsageGauge)
177
178 newRegCounter := prometheus.NewCounter(prometheus.CounterOpts{
179 Name: "new_registrations",
180 Help: "A counter of new registrations",
181 })
182 stats.MustRegister(newRegCounter)
183
184 recheckCAACounter := prometheus.NewCounter(prometheus.CounterOpts{
185 Name: "recheck_caa",
186 Help: "A counter of CAA rechecks",
187 })
188 stats.MustRegister(recheckCAACounter)
189
190 recheckCAAUsedAuthzLifetime := prometheus.NewCounter(prometheus.CounterOpts{
191 Name: "recheck_caa_used_authz_lifetime",
192 Help: "A counter times the old codepath was used for CAA recheck time",
193 })
194 stats.MustRegister(recheckCAAUsedAuthzLifetime)
195
196 newCertCounter := prometheus.NewCounter(prometheus.CounterOpts{
197 Name: "new_certificates",
198 Help: "A counter of new certificates",
199 })
200 stats.MustRegister(newCertCounter)
201
202 revocationReasonCounter := prometheus.NewCounterVec(prometheus.CounterOpts{
203 Name: "revocation_reason",
204 Help: "A counter of certificate revocation reasons",
205 }, []string{"reason"})
206 stats.MustRegister(revocationReasonCounter)
207
208 authzAges := prometheus.NewHistogramVec(prometheus.HistogramOpts{
209 Name: "authz_ages",
210 Help: "Histogram of ages, in seconds, of Authorization objects, labelled by method and type",
211
212
213
214
215
216
217
218 Buckets: []float64{0.000000001, 1, 60, 3600, 25200, 86400, 172800, 604800, 2592000, 7776000},
219 }, []string{"method", "type"})
220 stats.MustRegister(authzAges)
221
222 orderAges := prometheus.NewHistogramVec(prometheus.HistogramOpts{
223 Name: "order_ages",
224 Help: "Histogram of ages, in seconds, of Order objects when they're reused and finalized, labelled by method",
225
226
227
228 Buckets: []float64{0.000000001, 1, 10, 60, 600, 3600, 25200, 86400, 172800, 604800},
229 }, []string{"method"})
230 stats.MustRegister(orderAges)
231
232 inflightFinalizes := prometheus.NewGauge(prometheus.GaugeOpts{
233 Name: "inflight_finalizes",
234 Help: "Gauge of the number of current asynchronous finalize goroutines",
235 })
236 stats.MustRegister(inflightFinalizes)
237
238 issuersByNameID := make(map[issuance.IssuerNameID]*issuance.Certificate)
239 issuersByID := make(map[issuance.IssuerID]*issuance.Certificate)
240 for _, issuer := range issuers {
241 issuersByNameID[issuer.NameID()] = issuer
242 issuersByID[issuer.ID()] = issuer
243 }
244
245 ra := &RegistrationAuthorityImpl{
246 clk: clk,
247 log: logger,
248 authorizationLifetime: authorizationLifetime,
249 pendingAuthorizationLifetime: pendingAuthorizationLifetime,
250 rlPolicies: ratelimit.New(),
251 maxContactsPerReg: maxContactsPerReg,
252 keyPolicy: keyPolicy,
253 maxNames: maxNames,
254 publisher: pubc,
255 caa: caaClient,
256 orderLifetime: orderLifetime,
257 finalizeTimeout: finalizeTimeout,
258 ctpolicy: ctp,
259 ctpolicyResults: ctpolicyResults,
260 purger: purger,
261 issuersByNameID: issuersByNameID,
262 issuersByID: issuersByID,
263 namesPerCert: namesPerCert,
264 rlCheckLatency: rlCheckLatency,
265 rlOverrideUsageGauge: overrideUsageGauge,
266 newRegCounter: newRegCounter,
267 recheckCAACounter: recheckCAACounter,
268 newCertCounter: newCertCounter,
269 revocationReasonCounter: revocationReasonCounter,
270 recheckCAAUsedAuthzLifetime: recheckCAAUsedAuthzLifetime,
271 authzAges: authzAges,
272 orderAges: orderAges,
273 inflightFinalizes: inflightFinalizes,
274 }
275 return ra
276 }
277
278 func (ra *RegistrationAuthorityImpl) LoadRateLimitPoliciesFile(filename string) error {
279 configBytes, err := os.ReadFile(filename)
280 if err != nil {
281 return err
282 }
283 err = ra.rlPolicies.LoadPolicies(configBytes)
284 if err != nil {
285 return err
286 }
287
288 return nil
289 }
290
291
292
293
294
295
296 type certificateRequestAuthz struct {
297 ID string
298 ChallengeType core.AcmeChallenge
299 }
300
301
302
303 type certificateRequestEvent struct {
304 ID string `json:",omitempty"`
305
306 Requester int64 `json:",omitempty"`
307
308 OrderID int64 `json:",omitempty"`
309
310
311 SerialNumber string `json:",omitempty"`
312
313
314 VerifiedFields []string `json:",omitempty"`
315
316 CommonName string `json:",omitempty"`
317
318 Names []string `json:",omitempty"`
319
320 NotBefore time.Time `json:",omitempty"`
321
322 NotAfter time.Time `json:",omitempty"`
323
324 RequestTime time.Time `json:",omitempty"`
325 ResponseTime time.Time `json:",omitempty"`
326
327 Error string `json:",omitempty"`
328
329
330
331 Authorizations map[string]certificateRequestAuthz
332 }
333
334
335
336 type certificateRevocationEvent struct {
337 ID string `json:",omitempty"`
338
339
340 SerialNumber string `json:",omitempty"`
341
342 Reason int64 `json:",omitempty"`
343
344
345 Method string `json:",omitempty"`
346
347
348 RequesterID int64 `json:",omitempty"`
349
350
351 AdminName string `json:",omitempty"`
352
353 Error string `json:",omitempty"`
354 }
355
356
357
358
359 type finalizationCAACheckEvent struct {
360
361 Requester int64 `json:",omitempty"`
362
363
364 Reused int `json:",omitempty"`
365
366
367 Rechecked int `json:",omitempty"`
368 }
369
370
371
372 const noRegistrationID = -1
373
374
375
376 type registrationCounter func(context.Context, *sapb.CountRegistrationsByIPRequest, ...grpc.CallOption) (*sapb.Count, error)
377
378
379
380
381 func (ra *RegistrationAuthorityImpl) checkRegistrationIPLimit(ctx context.Context, limit ratelimit.RateLimitPolicy, ip net.IP, counter registrationCounter) error {
382 now := ra.clk.Now()
383 count, err := counter(ctx, &sapb.CountRegistrationsByIPRequest{
384 Ip: ip,
385 Range: &sapb.Range{
386 EarliestNS: limit.WindowBegin(now).UnixNano(),
387 Earliest: timestamppb.New(limit.WindowBegin(now)),
388 LatestNS: now.UnixNano(),
389 Latest: timestamppb.New(now),
390 },
391 })
392 if err != nil {
393 return err
394 }
395
396 threshold, overrideKey := limit.GetThreshold(ip.String(), noRegistrationID)
397 if overrideKey != "" {
398
399 utilization := float64(count.Count) / float64(threshold)
400 ra.rlOverrideUsageGauge.WithLabelValues(ratelimit.RegistrationsPerIP, overrideKey).Set(utilization)
401 }
402
403 if count.Count >= threshold {
404 return berrors.RegistrationsPerIPError(0, "too many registrations for this IP")
405 }
406
407 return nil
408 }
409
410
411
412 func (ra *RegistrationAuthorityImpl) checkRegistrationLimits(ctx context.Context, ip net.IP) error {
413
414
415 exactRegLimit := ra.rlPolicies.RegistrationsPerIP()
416 if exactRegLimit.Enabled() {
417 started := ra.clk.Now()
418 err := ra.checkRegistrationIPLimit(ctx, exactRegLimit, ip, ra.SA.CountRegistrationsByIP)
419 elapsed := ra.clk.Since(started)
420 if err != nil {
421 if errors.Is(err, berrors.RateLimit) {
422 ra.rlCheckLatency.WithLabelValues(ratelimit.RegistrationsPerIP, ratelimits.Denied).Observe(elapsed.Seconds())
423 ra.log.Infof("Rate limit exceeded, RegistrationsPerIP, by IP: %q", ip)
424 }
425 return err
426 }
427 ra.rlCheckLatency.WithLabelValues(ratelimit.RegistrationsPerIP, ratelimits.Allowed).Observe(elapsed.Seconds())
428 }
429
430
431
432
433 if ip.To4() != nil {
434 return nil
435 }
436
437
438
439
440 fuzzyRegLimit := ra.rlPolicies.RegistrationsPerIPRange()
441 if fuzzyRegLimit.Enabled() {
442 started := ra.clk.Now()
443 err := ra.checkRegistrationIPLimit(ctx, fuzzyRegLimit, ip, ra.SA.CountRegistrationsByIPRange)
444 elapsed := ra.clk.Since(started)
445 if err != nil {
446 if errors.Is(err, berrors.RateLimit) {
447 ra.rlCheckLatency.WithLabelValues(ratelimit.RegistrationsPerIPRange, ratelimits.Denied).Observe(elapsed.Seconds())
448 ra.log.Infof("Rate limit exceeded, RegistrationsByIPRange, IP: %q", ip)
449
450
451
452 return berrors.RateLimitError(0, "too many registrations for this IP range")
453 }
454 return err
455 }
456 ra.rlCheckLatency.WithLabelValues(ratelimit.RegistrationsPerIPRange, ratelimits.Allowed).Observe(elapsed.Seconds())
457 }
458
459 return nil
460 }
461
462
463 func (ra *RegistrationAuthorityImpl) NewRegistration(ctx context.Context, request *corepb.Registration) (*corepb.Registration, error) {
464
465 if request == nil || len(request.Key) == 0 || len(request.InitialIP) == 0 {
466 return nil, errIncompleteGRPCRequest
467 }
468
469
470 var key jose.JSONWebKey
471 err := key.UnmarshalJSON(request.Key)
472 if err != nil {
473 return nil, berrors.InternalServerError("failed to unmarshal account key: %s", err.Error())
474 }
475 err = ra.keyPolicy.GoodKey(ctx, key.Key)
476 if err != nil {
477 return nil, berrors.MalformedError("invalid public key: %s", err.Error())
478 }
479
480
481 var ipAddr net.IP
482 err = ipAddr.UnmarshalText(request.InitialIP)
483 if err != nil {
484 return nil, berrors.InternalServerError("failed to unmarshal ip address: %s", err.Error())
485 }
486 err = ra.checkRegistrationLimits(ctx, ipAddr)
487 if err != nil {
488 return nil, err
489 }
490
491
492 err = validateContactsPresent(request.Contact, request.ContactsPresent)
493 if err != nil {
494 return nil, err
495 }
496 err = ra.validateContacts(request.Contact)
497 if err != nil {
498 return nil, err
499 }
500
501
502 req := &corepb.Registration{
503 Key: request.Key,
504 Contact: request.Contact,
505 ContactsPresent: request.ContactsPresent,
506 Agreement: request.Agreement,
507 InitialIP: request.InitialIP,
508 Status: string(core.StatusValid),
509 }
510
511
512 res, err := ra.SA.NewRegistration(ctx, req)
513 if err != nil {
514 return nil, err
515 }
516
517 ra.newRegCounter.Inc()
518 return res, nil
519 }
520
521
522
523
524
525
526
527
528
529
530
531 func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error {
532 if len(contacts) == 0 {
533 return nil
534 }
535 if ra.maxContactsPerReg > 0 && len(contacts) > ra.maxContactsPerReg {
536 return berrors.MalformedError(
537 "too many contacts provided: %d > %d",
538 len(contacts),
539 ra.maxContactsPerReg,
540 )
541 }
542
543 for _, contact := range contacts {
544 if contact == "" {
545 return berrors.InvalidEmailError("empty contact")
546 }
547 parsed, err := url.Parse(contact)
548 if err != nil {
549 return berrors.InvalidEmailError("invalid contact")
550 }
551 if parsed.Scheme != "mailto" {
552 return berrors.UnsupportedContactError("contact method %q is not supported", parsed.Scheme)
553 }
554 if parsed.RawQuery != "" || contact[len(contact)-1] == '?' {
555 return berrors.InvalidEmailError("contact email %q contains a question mark", contact)
556 }
557 if parsed.Fragment != "" || contact[len(contact)-1] == '#' {
558 return berrors.InvalidEmailError("contact email %q contains a '#'", contact)
559 }
560 if !core.IsASCII(contact) {
561 return berrors.InvalidEmailError(
562 "contact email [%q] contains non-ASCII characters",
563 contact,
564 )
565 }
566 err = policy.ValidEmail(parsed.Opaque)
567 if err != nil {
568 return err
569 }
570 }
571
572
573
574
575
576 const maxContactBytes = 191
577 if jsonBytes, err := json.Marshal(contacts); err != nil {
578
579
580
581 return fmt.Errorf("failed to marshal reg.Contact to JSON: %#v", contacts)
582 } else if len(jsonBytes) >= maxContactBytes {
583 return berrors.InvalidEmailError(
584 "too many/too long contact(s). Please use shorter or fewer email addresses")
585 }
586
587 return nil
588 }
589
590 func (ra *RegistrationAuthorityImpl) checkPendingAuthorizationLimit(ctx context.Context, regID int64, limit ratelimit.RateLimitPolicy) error {
591
592
593 threshold, overrideKey := limit.GetThreshold("", regID)
594 if threshold == -1 {
595 return nil
596 }
597 countPB, err := ra.SA.CountPendingAuthorizations2(ctx, &sapb.RegistrationID{
598 Id: regID,
599 })
600 if err != nil {
601 return err
602 }
603 if overrideKey != "" {
604 utilization := float64(countPB.Count) / float64(threshold)
605 ra.rlOverrideUsageGauge.WithLabelValues(ratelimit.PendingAuthorizationsPerAccount, overrideKey).Set(utilization)
606 }
607 if countPB.Count >= threshold {
608 ra.log.Infof("Rate limit exceeded, PendingAuthorizationsByRegID, regID: %d", regID)
609 return berrors.RateLimitError(0, "too many currently pending authorizations: %d", countPB.Count)
610 }
611 return nil
612 }
613
614
615
616 func (ra *RegistrationAuthorityImpl) checkInvalidAuthorizationLimits(ctx context.Context, regID int64, hostnames []string, limits ratelimit.RateLimitPolicy) error {
617 results := make(chan error, len(hostnames))
618 for _, hostname := range hostnames {
619 go func(hostname string) {
620 results <- ra.checkInvalidAuthorizationLimit(ctx, regID, hostname, limits)
621 }(hostname)
622 }
623
624
625
626 for i := 0; i < len(hostnames); i++ {
627 err := <-results
628 if err != nil {
629 return err
630 }
631 }
632 return nil
633 }
634
635 func (ra *RegistrationAuthorityImpl) checkInvalidAuthorizationLimit(ctx context.Context, regID int64, hostname string, limit ratelimit.RateLimitPolicy) error {
636 latest := ra.clk.Now().Add(ra.pendingAuthorizationLifetime)
637 earliest := latest.Add(-limit.Window.Duration)
638 req := &sapb.CountInvalidAuthorizationsRequest{
639 RegistrationID: regID,
640 Hostname: hostname,
641 Range: &sapb.Range{
642 EarliestNS: earliest.UnixNano(),
643 Earliest: timestamppb.New(earliest),
644 LatestNS: latest.UnixNano(),
645 Latest: timestamppb.New(latest),
646 },
647 }
648 count, err := ra.SA.CountInvalidAuthorizations2(ctx, req)
649 if err != nil {
650 return err
651 }
652
653
654 noKey := ""
655 threshold, overrideKey := limit.GetThreshold(noKey, regID)
656 if overrideKey != "" {
657 utilization := float64(count.Count) / float64(threshold)
658 ra.rlOverrideUsageGauge.WithLabelValues(ratelimit.InvalidAuthorizationsPerAccount, overrideKey).Set(utilization)
659 }
660 if count.Count >= threshold {
661 ra.log.Infof("Rate limit exceeded, InvalidAuthorizationsByRegID, regID: %d", regID)
662 return berrors.FailedValidationError(0, "too many failed authorizations recently")
663 }
664 return nil
665 }
666
667
668
669
670 func (ra *RegistrationAuthorityImpl) checkNewOrdersPerAccountLimit(ctx context.Context, acctID int64, limit ratelimit.RateLimitPolicy) error {
671 now := ra.clk.Now()
672 count, err := ra.SA.CountOrders(ctx, &sapb.CountOrdersRequest{
673 AccountID: acctID,
674 Range: &sapb.Range{
675 EarliestNS: now.Add(-limit.Window.Duration).UnixNano(),
676 Earliest: timestamppb.New(now.Add(-limit.Window.Duration)),
677 LatestNS: now.UnixNano(),
678 Latest: timestamppb.New(now),
679 },
680 })
681 if err != nil {
682 return err
683 }
684
685 noKey := ""
686 threshold, overrideKey := limit.GetThreshold(noKey, acctID)
687 if overrideKey != "" {
688 utilization := float64(count.Count) / float64(threshold)
689 ra.rlOverrideUsageGauge.WithLabelValues(ratelimit.NewOrdersPerAccount, overrideKey).Set(utilization)
690 }
691
692 if count.Count >= threshold {
693 return berrors.RateLimitError(0, "too many new orders recently")
694 }
695 return nil
696 }
697
698
699
700
701
702
703
704
705
706
707 func (ra *RegistrationAuthorityImpl) matchesCSR(parsedCertificate *x509.Certificate, csr *x509.CertificateRequest) error {
708 if !core.KeyDigestEquals(parsedCertificate.PublicKey, csr.PublicKey) {
709 return berrors.InternalServerError("generated certificate public key doesn't match CSR public key")
710 }
711
712 csrNames := csrlib.NamesFromCSR(csr)
713 if parsedCertificate.Subject.CommonName != "" {
714
715
716
717 if !slices.Contains(csrNames.SANs, parsedCertificate.Subject.CommonName) {
718 return berrors.InternalServerError("generated certificate CommonName doesn't match any CSR name")
719 }
720 }
721
722 parsedNames := parsedCertificate.DNSNames
723 sort.Strings(parsedNames)
724 if !slices.Equal(parsedNames, csrNames.SANs) {
725 return berrors.InternalServerError("generated certificate DNSNames don't match CSR DNSNames")
726 }
727
728 if !slices.EqualFunc(parsedCertificate.IPAddresses, csr.IPAddresses, func(l, r net.IP) bool { return l.Equal(r) }) {
729 return berrors.InternalServerError("generated certificate IPAddresses don't match CSR IPAddresses")
730 }
731 if !slices.Equal(parsedCertificate.EmailAddresses, csr.EmailAddresses) {
732 return berrors.InternalServerError("generated certificate EmailAddresses don't match CSR EmailAddresses")
733 }
734
735 if len(parsedCertificate.Subject.Country) > 0 || len(parsedCertificate.Subject.Organization) > 0 ||
736 len(parsedCertificate.Subject.OrganizationalUnit) > 0 || len(parsedCertificate.Subject.Locality) > 0 ||
737 len(parsedCertificate.Subject.Province) > 0 || len(parsedCertificate.Subject.StreetAddress) > 0 ||
738 len(parsedCertificate.Subject.PostalCode) > 0 {
739 return berrors.InternalServerError("generated certificate Subject contains fields other than CommonName, or SerialNumber")
740 }
741 now := ra.clk.Now()
742 if now.Sub(parsedCertificate.NotBefore) > time.Hour*24 {
743 return berrors.InternalServerError("generated certificate is back dated %s", now.Sub(parsedCertificate.NotBefore))
744 }
745 if !parsedCertificate.BasicConstraintsValid {
746 return berrors.InternalServerError("generated certificate doesn't have basic constraints set")
747 }
748 if parsedCertificate.IsCA {
749 return berrors.InternalServerError("generated certificate can sign other certificates")
750 }
751 if !slices.Equal(parsedCertificate.ExtKeyUsage, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}) {
752 return berrors.InternalServerError("generated certificate doesn't have correct key usage extensions")
753 }
754
755 return nil
756 }
757
758
759
760
761
762
763 func (ra *RegistrationAuthorityImpl) checkOrderAuthorizations(
764 ctx context.Context,
765 names []string,
766 acctID accountID,
767 orderID orderID) (map[string]*core.Authorization, error) {
768
769 req := &sapb.GetValidOrderAuthorizationsRequest{
770 Id: int64(orderID),
771 AcctID: int64(acctID),
772 }
773 authzMapPB, err := ra.SA.GetValidOrderAuthorizations2(ctx, req)
774 if err != nil {
775 return nil, berrors.InternalServerError("error in GetValidOrderAuthorizations: %s", err)
776 }
777 authzs, err := bgrpc.PBToAuthzMap(authzMapPB)
778 if err != nil {
779 return nil, err
780 }
781
782
783 names = core.UniqueLowerNames(names)
784
785
786 err = ra.checkAuthorizationsCAA(ctx, int64(acctID), names, authzs, ra.clk.Now())
787 if err != nil {
788 return nil, err
789 }
790
791
792 for _, authz := range authzs {
793 err = ra.PA.CheckAuthz(authz)
794 if err != nil {
795 return nil, err
796 }
797 }
798
799 return authzs, nil
800 }
801
802
803
804 func validatedBefore(authz *core.Authorization, caaRecheckTime time.Time) (bool, error) {
805 numChallenges := len(authz.Challenges)
806 if numChallenges != 1 {
807 return false, fmt.Errorf("authorization has incorrect number of challenges. 1 expected, %d found for: id %s", numChallenges, authz.ID)
808 }
809 if authz.Challenges[0].Validated == nil {
810 return false, fmt.Errorf("authorization's challenge has no validated timestamp for: id %s", authz.ID)
811 }
812 return authz.Challenges[0].Validated.Before(caaRecheckTime), nil
813 }
814
815
816
817
818
819
820 func (ra *RegistrationAuthorityImpl) checkAuthorizationsCAA(
821 ctx context.Context,
822 acctID int64,
823 names []string,
824 authzs map[string]*core.Authorization,
825 now time.Time) error {
826
827 var badNames []string
828
829 var recheckAuthzs []*core.Authorization
830
831
832
833
834
835
836
837
838 caaRecheckAfter := now.Add(caaRecheckDuration)
839
840
841
842
843
844
845 caaRecheckTime := now.Add(ra.authorizationLifetime).Add(caaRecheckDuration)
846
847 for _, name := range names {
848 authz := authzs[name]
849 if authz == nil {
850 badNames = append(badNames, name)
851 } else if authz.Expires == nil {
852 return berrors.InternalServerError("found an authorization with a nil Expires field: id %s", authz.ID)
853 } else if authz.Expires.Before(now) {
854 badNames = append(badNames, name)
855 } else if staleCAA, err := validatedBefore(authz, caaRecheckAfter); err != nil {
856 return berrors.InternalServerError(err.Error())
857 } else if staleCAA {
858
859 recheckAuthzs = append(recheckAuthzs, authz)
860 } else if authz.Expires.Before(caaRecheckTime) {
861
862 recheckAuthzs = append(recheckAuthzs, authz)
863
864
865
866 ra.recheckCAAUsedAuthzLifetime.Add(1)
867 }
868 }
869
870 if len(recheckAuthzs) > 0 {
871 err := ra.recheckCAA(ctx, recheckAuthzs)
872 if err != nil {
873 return err
874 }
875 }
876
877 if len(badNames) > 0 {
878 return berrors.UnauthorizedError(
879 "authorizations for these names not found or expired: %s",
880 strings.Join(badNames, ", "),
881 )
882 }
883
884 caaEvent := &finalizationCAACheckEvent{
885 Requester: acctID,
886 Reused: len(authzs) - len(recheckAuthzs),
887 Rechecked: len(recheckAuthzs),
888 }
889 ra.log.InfoObject("FinalizationCaaCheck", caaEvent)
890
891 return nil
892 }
893
894
895
896
897
898 func (ra *RegistrationAuthorityImpl) recheckCAA(ctx context.Context, authzs []*core.Authorization) error {
899 ra.recheckCAACounter.Add(float64(len(authzs)))
900
901 type authzCAAResult struct {
902 authz *core.Authorization
903 err error
904 }
905 ch := make(chan authzCAAResult, len(authzs))
906 for _, authz := range authzs {
907 go func(authz *core.Authorization) {
908 name := authz.Identifier.Value
909
910
911
912
913 var method string
914 for _, challenge := range authz.Challenges {
915 if challenge.Status == core.StatusValid {
916 method = string(challenge.Type)
917 break
918 }
919 }
920 if method == "" {
921 ch <- authzCAAResult{
922 authz: authz,
923 err: berrors.InternalServerError(
924 "Internal error determining validation method for authorization ID %v (%v)",
925 authz.ID, name),
926 }
927 return
928 }
929
930 resp, err := ra.caa.IsCAAValid(ctx, &vapb.IsCAAValidRequest{
931 Domain: name,
932 ValidationMethod: method,
933 AccountURIID: authz.RegistrationID,
934 })
935 if err != nil {
936 ra.log.AuditErrf("Rechecking CAA: %s", err)
937 err = berrors.InternalServerError(
938 "Internal error rechecking CAA for authorization ID %v (%v)",
939 authz.ID, name,
940 )
941 } else if resp.Problem != nil {
942 err = berrors.CAAError(resp.Problem.Detail)
943 }
944 ch <- authzCAAResult{
945 authz: authz,
946 err: err,
947 }
948 }(authz)
949 }
950 var subErrors []berrors.SubBoulderError
951
952 for i := 0; i < len(authzs); i++ {
953 recheckResult := <-ch
954
955
956 err := recheckResult.err
957 if err != nil {
958 var bErr *berrors.BoulderError
959 if errors.As(err, &bErr) && bErr.Type == berrors.CAA {
960 subErrors = append(subErrors, berrors.SubBoulderError{
961 Identifier: recheckResult.authz.Identifier,
962 BoulderError: bErr})
963 } else {
964 return err
965 }
966 }
967 }
968 if len(subErrors) > 0 {
969 var detail string
970
971
972 if len(subErrors) == 1 {
973 return subErrors[0].BoulderError
974 }
975 detail = fmt.Sprintf(
976 "Rechecking CAA for %q and %d more identifiers failed. "+
977 "Refer to sub-problems for more information",
978 subErrors[0].Identifier.Value,
979 len(subErrors)-1)
980 return (&berrors.BoulderError{
981 Type: berrors.CAA,
982 Detail: detail,
983 }).WithSubErrors(subErrors)
984 }
985 return nil
986 }
987
988
989
990
991
992
993 func (ra *RegistrationAuthorityImpl) failOrder(
994 ctx context.Context,
995 order *corepb.Order,
996 prob *probs.ProblemDetails) {
997
998
999
1000 ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 1*time.Second)
1001 defer cancel()
1002
1003
1004 pbProb, err := bgrpc.ProblemDetailsToPB(prob)
1005 if err != nil {
1006 ra.log.AuditErrf("Could not convert order error problem to PB: %q", err)
1007 return
1008 }
1009
1010
1011 order.Error = pbProb
1012 _, err = ra.SA.SetOrderError(ctx, &sapb.SetOrderErrorRequest{
1013 Id: order.Id,
1014 Error: order.Error,
1015 })
1016 if err != nil {
1017 ra.log.AuditErrf("Could not persist order error: %q", err)
1018 }
1019 }
1020
1021
1022
1023
1024 type accountID int64
1025 type orderID int64
1026
1027
1028
1029
1030
1031
1032
1033
1034 func (ra *RegistrationAuthorityImpl) FinalizeOrder(ctx context.Context, req *rapb.FinalizeOrderRequest) (*corepb.Order, error) {
1035
1036 if req == nil || req.Order == nil || len(req.Csr) == 0 {
1037 return nil, errIncompleteGRPCRequest
1038 }
1039
1040 logEvent := certificateRequestEvent{
1041 ID: core.NewToken(),
1042 OrderID: req.Order.Id,
1043 Requester: req.Order.RegistrationID,
1044 RequestTime: ra.clk.Now(),
1045 }
1046 csr, err := ra.validateFinalizeRequest(ctx, req, &logEvent)
1047 if err != nil {
1048 return nil, err
1049 }
1050
1051
1052
1053 ra.orderAges.WithLabelValues("FinalizeOrder").Observe(ra.clk.Since(time.Unix(0, req.Order.CreatedNS)).Seconds())
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066 _, err = ra.SA.SetOrderProcessing(ctx, &sapb.OrderRequest{Id: req.Order.Id})
1067 if err != nil {
1068
1069
1070 ra.failOrder(ctx, req.Order, probs.ServerInternal("Error setting order processing"))
1071 return nil, err
1072 }
1073
1074
1075
1076 order := req.Order
1077 order.Status = string(core.StatusProcessing)
1078
1079
1080
1081 if features.Enabled(features.AsyncFinalize) {
1082
1083
1084
1085
1086
1087
1088
1089
1090 ra.finalizeWG.Add(1)
1091 go func() {
1092 _, err := ra.issueCertificateOuter(ctx, proto.Clone(order).(*corepb.Order), csr, logEvent)
1093 if err != nil {
1094
1095
1096 ra.log.AuditErrf("Asynchronous finalization failed: %s", err.Error())
1097 }
1098 ra.finalizeWG.Done()
1099 }()
1100 return order, nil
1101 } else {
1102 return ra.issueCertificateOuter(ctx, order, csr, logEvent)
1103 }
1104 }
1105
1106
1107
1108 func (ra *RegistrationAuthorityImpl) validateFinalizeRequest(
1109 ctx context.Context,
1110 req *rapb.FinalizeOrderRequest,
1111 logEvent *certificateRequestEvent) (*x509.CertificateRequest, error) {
1112 if req.Order.Id <= 0 {
1113 return nil, berrors.MalformedError("invalid order ID: %d", req.Order.Id)
1114 }
1115
1116 if req.Order.RegistrationID <= 0 {
1117 return nil, berrors.MalformedError("invalid account ID: %d", req.Order.RegistrationID)
1118 }
1119
1120 if core.AcmeStatus(req.Order.Status) != core.StatusReady {
1121 return nil, berrors.OrderNotReadyError(
1122 "Order's status (%q) is not acceptable for finalization",
1123 req.Order.Status)
1124 }
1125
1126
1127
1128
1129 if len(req.Order.Names) == 0 {
1130 return nil, berrors.InternalServerError("Order has no associated names")
1131 }
1132
1133
1134 csr, err := x509.ParseCertificateRequest(req.Csr)
1135 if err != nil {
1136 return nil, berrors.BadCSRError("unable to parse CSR: %s", err.Error())
1137 }
1138
1139 err = csrlib.VerifyCSR(ctx, csr, ra.maxNames, &ra.keyPolicy, ra.PA)
1140 if err != nil {
1141
1142
1143 return nil, err
1144 }
1145
1146
1147
1148 csrNames := csrlib.NamesFromCSR(csr).SANs
1149 orderNames := core.UniqueLowerNames(req.Order.Names)
1150
1151
1152 if len(orderNames) != len(csrNames) {
1153 return nil, berrors.UnauthorizedError("Order includes different number of names than CSR specifies")
1154 }
1155
1156
1157 for i, name := range orderNames {
1158 if name != csrNames[i] {
1159 return nil, berrors.UnauthorizedError("CSR is missing Order domain %q", name)
1160 }
1161 }
1162
1163
1164 regPB, err := ra.SA.GetRegistration(ctx, &sapb.RegistrationID{Id: req.Order.RegistrationID})
1165 if err != nil {
1166 return nil, err
1167 }
1168
1169 account, err := bgrpc.PbToRegistration(regPB)
1170 if err != nil {
1171 return nil, err
1172 }
1173
1174
1175 if core.KeyDigestEquals(csr.PublicKey, account.Key) {
1176 return nil, berrors.MalformedError("certificate public key must be different than account key")
1177 }
1178
1179
1180
1181 authzs, err := ra.checkOrderAuthorizations(ctx, csrNames, accountID(req.Order.RegistrationID), orderID(req.Order.Id))
1182 if err != nil {
1183
1184
1185 return nil, err
1186 }
1187
1188
1189
1190 logEventAuthzs := make(map[string]certificateRequestAuthz, len(csrNames))
1191 for name, authz := range authzs {
1192
1193
1194 solvedByChallengeType, _ := authz.SolvedBy()
1195 logEventAuthzs[name] = certificateRequestAuthz{
1196 ID: authz.ID,
1197 ChallengeType: solvedByChallengeType,
1198 }
1199 authzAge := (ra.authorizationLifetime - authz.Expires.Sub(ra.clk.Now())).Seconds()
1200 ra.authzAges.WithLabelValues("FinalizeOrder", string(authz.Status)).Observe(authzAge)
1201 }
1202 logEvent.Authorizations = logEventAuthzs
1203
1204
1205 logEvent.VerifiedFields = []string{"subject.commonName", "subjectAltName"}
1206
1207 return csr, nil
1208 }
1209
1210
1211
1212
1213
1214 func (ra *RegistrationAuthorityImpl) issueCertificateOuter(
1215 ctx context.Context,
1216 order *corepb.Order,
1217 csr *x509.CertificateRequest,
1218 logEvent certificateRequestEvent,
1219 ) (*corepb.Order, error) {
1220 ra.inflightFinalizes.Inc()
1221 defer ra.inflightFinalizes.Dec()
1222
1223
1224 cert, err := ra.issueCertificateInner(
1225 ctx, csr, accountID(order.RegistrationID), orderID(order.Id))
1226
1227
1228 var result string
1229 if err != nil {
1230
1231
1232
1233
1234
1235
1236 ra.failOrder(ctx, order, web.ProblemDetailsForError(err, "Error finalizing order"))
1237 order.Status = string(core.StatusInvalid)
1238
1239 logEvent.Error = err.Error()
1240 result = "error"
1241 } else {
1242 order.CertificateSerial = core.SerialToString(cert.SerialNumber)
1243 order.Status = string(core.StatusValid)
1244
1245 ra.namesPerCert.With(
1246 prometheus.Labels{"type": "issued"},
1247 ).Observe(float64(len(order.Names)))
1248
1249 ra.newCertCounter.Inc()
1250
1251 logEvent.SerialNumber = core.SerialToString(cert.SerialNumber)
1252 logEvent.CommonName = cert.Subject.CommonName
1253 logEvent.Names = cert.DNSNames
1254 logEvent.NotBefore = cert.NotBefore
1255 logEvent.NotAfter = cert.NotAfter
1256
1257 result = "successful"
1258 }
1259
1260 logEvent.ResponseTime = ra.clk.Now()
1261 ra.log.AuditObject(fmt.Sprintf("Certificate request - %s", result), logEvent)
1262
1263 return order, err
1264 }
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279 func (ra *RegistrationAuthorityImpl) issueCertificateInner(
1280 ctx context.Context,
1281 csr *x509.CertificateRequest,
1282 acctID accountID,
1283 oID orderID) (*x509.Certificate, error) {
1284 if features.Enabled(features.AsyncFinalize) {
1285
1286 var cancel func()
1287 ctx, cancel = context.WithTimeout(context.WithoutCancel(ctx), ra.finalizeTimeout)
1288 defer cancel()
1289 }
1290
1291
1292
1293
1294 wrapError := func(e error, prefix string) error {
1295 if berr, ok := e.(*berrors.BoulderError); ok {
1296 berr.Detail = fmt.Sprintf("%s: %s", prefix, berr.Detail)
1297 return berr
1298 }
1299 return fmt.Errorf("%s: %s", prefix, e)
1300 }
1301
1302 issueReq := &capb.IssueCertificateRequest{
1303 Csr: csr.Raw,
1304 RegistrationID: int64(acctID),
1305 OrderID: int64(oID),
1306 }
1307 precert, err := ra.CA.IssuePrecertificate(ctx, issueReq)
1308 if err != nil {
1309 return nil, wrapError(err, "issuing precertificate")
1310 }
1311
1312 parsedPrecert, err := x509.ParseCertificate(precert.DER)
1313 if err != nil {
1314 return nil, wrapError(err, "parsing precertificate")
1315 }
1316
1317 scts, err := ra.getSCTs(ctx, precert.DER, parsedPrecert.NotAfter)
1318 if err != nil {
1319 return nil, wrapError(err, "getting SCTs")
1320 }
1321
1322 cert, err := ra.CA.IssueCertificateForPrecertificate(ctx, &capb.IssueCertificateForPrecertificateRequest{
1323 DER: precert.DER,
1324 SCTs: scts,
1325 RegistrationID: int64(acctID),
1326 OrderID: int64(oID),
1327 })
1328 if err != nil {
1329 return nil, wrapError(err, "issuing certificate for precertificate")
1330 }
1331
1332 parsedCertificate, err := x509.ParseCertificate(cert.Der)
1333 if err != nil {
1334 return nil, wrapError(err, "parsing final certificate")
1335 }
1336
1337
1338 go ra.ctpolicy.SubmitFinalCert(cert.Der, parsedCertificate.NotAfter)
1339
1340
1341 err = ra.matchesCSR(parsedCertificate, csr)
1342 if err != nil {
1343 return nil, err
1344 }
1345
1346 _, err = ra.SA.FinalizeOrder(ctx, &sapb.FinalizeOrderRequest{
1347 Id: int64(oID),
1348 CertificateSerial: core.SerialToString(parsedCertificate.SerialNumber),
1349 })
1350 if err != nil {
1351 return nil, wrapError(err, "persisting finalized order")
1352 }
1353
1354 return parsedCertificate, nil
1355 }
1356
1357 func (ra *RegistrationAuthorityImpl) getSCTs(ctx context.Context, cert []byte, expiration time.Time) (core.SCTDERs, error) {
1358 started := ra.clk.Now()
1359 scts, err := ra.ctpolicy.GetSCTs(ctx, cert, expiration)
1360 took := ra.clk.Since(started)
1361
1362
1363
1364 if err != nil {
1365 state := "failure"
1366 if err == context.DeadlineExceeded {
1367 state = "deadlineExceeded"
1368
1369
1370 err = berrors.MissingSCTsError(err.Error())
1371 }
1372 ra.log.Warningf("ctpolicy.GetSCTs failed: %s", err)
1373 ra.ctpolicyResults.With(prometheus.Labels{"result": state}).Observe(took.Seconds())
1374 return nil, err
1375 }
1376 ra.ctpolicyResults.With(prometheus.Labels{"result": "success"}).Observe(took.Seconds())
1377 return scts, nil
1378 }
1379
1380
1381
1382
1383 func domainsForRateLimiting(names []string) []string {
1384 var domains []string
1385 for _, name := range names {
1386 domain, err := publicsuffix.Domain(name)
1387 if err != nil {
1388
1389
1390
1391
1392 domains = append(domains, name)
1393 } else {
1394 domains = append(domains, domain)
1395 }
1396 }
1397 return core.UniqueLowerNames(domains)
1398 }
1399
1400
1401
1402
1403
1404 func (ra *RegistrationAuthorityImpl) enforceNameCounts(ctx context.Context, names []string, limit ratelimit.RateLimitPolicy, regID int64) ([]string, time.Time, error) {
1405 now := ra.clk.Now()
1406 req := &sapb.CountCertificatesByNamesRequest{
1407 Names: names,
1408 Range: &sapb.Range{
1409 EarliestNS: limit.WindowBegin(now).UnixNano(),
1410 Earliest: timestamppb.New(limit.WindowBegin(now)),
1411 LatestNS: now.UnixNano(),
1412 Latest: timestamppb.New(now),
1413 },
1414 }
1415
1416 response, err := ra.SA.CountCertificatesByNames(ctx, req)
1417 if err != nil {
1418 return nil, time.Time{}, err
1419 }
1420
1421 if len(response.Counts) == 0 {
1422 return nil, time.Time{}, errIncompleteGRPCResponse
1423 }
1424
1425 var badNames []string
1426
1427
1428
1429 for _, name := range names {
1430 threshold, overrideKey := limit.GetThreshold(name, regID)
1431 if overrideKey != "" {
1432 utilization := float64(response.Counts[name]) / float64(threshold)
1433 ra.rlOverrideUsageGauge.WithLabelValues(ratelimit.CertificatesPerName, overrideKey).Set(utilization)
1434 }
1435 if response.Counts[name] >= threshold {
1436 badNames = append(badNames, name)
1437 }
1438 }
1439 return badNames, response.Earliest.AsTime(), nil
1440 }
1441
1442 func (ra *RegistrationAuthorityImpl) checkCertificatesPerNameLimit(ctx context.Context, names []string, limit ratelimit.RateLimitPolicy, regID int64) error {
1443
1444
1445
1446 exists, err := ra.SA.FQDNSetExists(ctx, &sapb.FQDNSetExistsRequest{Domains: names})
1447 if err != nil {
1448 return fmt.Errorf("checking renewal exemption for %q: %s", names, err)
1449 }
1450 if exists.Exists {
1451 return nil
1452 }
1453
1454 tldNames := domainsForRateLimiting(names)
1455 namesOutOfLimit, earliest, err := ra.enforceNameCounts(ctx, tldNames, limit, regID)
1456 if err != nil {
1457 return fmt.Errorf("checking certificates per name limit for %q: %s",
1458 names, err)
1459 }
1460
1461 if len(namesOutOfLimit) > 0 {
1462
1463
1464 retryAfter := earliest.Add(limit.Window.Duration).Sub(ra.clk.Now())
1465 retryString := earliest.Add(limit.Window.Duration).Format(time.RFC3339)
1466
1467 ra.log.Infof("Rate limit exceeded, CertificatesForDomain, regID: %d, domains: %s", regID, strings.Join(namesOutOfLimit, ", "))
1468 if len(namesOutOfLimit) > 1 {
1469 var subErrors []berrors.SubBoulderError
1470 for _, name := range namesOutOfLimit {
1471 subErrors = append(subErrors, berrors.SubBoulderError{
1472 Identifier: identifier.DNSIdentifier(name),
1473 BoulderError: berrors.RateLimitError(retryAfter, "too many certificates already issued. Retry after %s", retryString).(*berrors.BoulderError),
1474 })
1475 }
1476 return berrors.RateLimitError(retryAfter, "too many certificates already issued for multiple names (%q and %d others). Retry after %s", namesOutOfLimit[0], len(namesOutOfLimit), retryString).(*berrors.BoulderError).WithSubErrors(subErrors)
1477 }
1478 return berrors.RateLimitError(retryAfter, "too many certificates already issued for %q. Retry after %s", namesOutOfLimit[0], retryString)
1479 }
1480
1481 return nil
1482 }
1483
1484 func (ra *RegistrationAuthorityImpl) checkCertificatesPerFQDNSetLimit(ctx context.Context, names []string, limit ratelimit.RateLimitPolicy, regID int64) error {
1485 names = core.UniqueLowerNames(names)
1486 threshold, overrideKey := limit.GetThreshold(strings.Join(names, ","), regID)
1487 if threshold <= 0 {
1488
1489 return nil
1490 }
1491
1492 prevIssuances, err := ra.SA.FQDNSetTimestampsForWindow(ctx, &sapb.CountFQDNSetsRequest{
1493 Domains: names,
1494 WindowNS: limit.Window.Duration.Nanoseconds(),
1495 Window: durationpb.New(limit.Window.Duration),
1496 })
1497 if err != nil {
1498 return fmt.Errorf("checking duplicate certificate limit for %q: %s", names, err)
1499 }
1500
1501 if overrideKey != "" {
1502 utilization := float64(len(prevIssuances.TimestampsNS)) / float64(threshold)
1503 ra.rlOverrideUsageGauge.WithLabelValues(ratelimit.CertificatesPerFQDNSet, overrideKey).Set(utilization)
1504 }
1505
1506 if int64(len(prevIssuances.TimestampsNS)) < threshold {
1507
1508 return nil
1509 } else {
1510
1511
1512
1513 now := ra.clk.Now()
1514 nsPerToken := limit.Window.Nanoseconds() / threshold
1515 for i, timestamp := range prevIssuances.TimestampsNS {
1516 tokensGeneratedSince := now.Add(-time.Duration(int64(i+1) * nsPerToken))
1517 if time.Unix(0, timestamp).Before(tokensGeneratedSince) {
1518
1519
1520
1521 return nil
1522 }
1523 }
1524 retryTime := time.Unix(0, prevIssuances.TimestampsNS[0]).Add(time.Duration(nsPerToken))
1525 retryAfter := retryTime.Sub(now)
1526 return berrors.DuplicateCertificateError(
1527 retryAfter,
1528 "too many certificates (%d) already issued for this exact set of domains in the last %.0f hours: %s, retry after %s",
1529 threshold, limit.Window.Duration.Hours(), strings.Join(names, ","), retryTime.Format(time.RFC3339),
1530 )
1531 }
1532 }
1533
1534 func (ra *RegistrationAuthorityImpl) checkNewOrderLimits(ctx context.Context, names []string, regID int64) error {
1535 newOrdersPerAccountLimits := ra.rlPolicies.NewOrdersPerAccount()
1536 if newOrdersPerAccountLimits.Enabled() {
1537 started := ra.clk.Now()
1538 err := ra.checkNewOrdersPerAccountLimit(ctx, regID, newOrdersPerAccountLimits)
1539 elapsed := ra.clk.Since(started)
1540 if err != nil {
1541 if errors.Is(err, berrors.RateLimit) {
1542 ra.rlCheckLatency.WithLabelValues(ratelimit.NewOrdersPerAccount, ratelimits.Denied).Observe(elapsed.Seconds())
1543 }
1544 return err
1545 }
1546 ra.rlCheckLatency.WithLabelValues(ratelimit.NewOrdersPerAccount, ratelimits.Allowed).Observe(elapsed.Seconds())
1547 }
1548
1549 certNameLimits := ra.rlPolicies.CertificatesPerName()
1550 if certNameLimits.Enabled() {
1551 started := ra.clk.Now()
1552 err := ra.checkCertificatesPerNameLimit(ctx, names, certNameLimits, regID)
1553 elapsed := ra.clk.Since(started)
1554 if err != nil {
1555 if errors.Is(err, berrors.RateLimit) {
1556 ra.rlCheckLatency.WithLabelValues(ratelimit.CertificatesPerName, ratelimits.Denied).Observe(elapsed.Seconds())
1557 }
1558 return err
1559 }
1560 ra.rlCheckLatency.WithLabelValues(ratelimit.CertificatesPerName, ratelimits.Allowed).Observe(elapsed.Seconds())
1561 }
1562
1563 fqdnLimitsFast := ra.rlPolicies.CertificatesPerFQDNSetFast()
1564 if fqdnLimitsFast.Enabled() {
1565 started := ra.clk.Now()
1566 err := ra.checkCertificatesPerFQDNSetLimit(ctx, names, fqdnLimitsFast, regID)
1567 elapsed := ra.clk.Since(started)
1568 if err != nil {
1569 if errors.Is(err, berrors.RateLimit) {
1570 ra.rlCheckLatency.WithLabelValues(ratelimit.CertificatesPerFQDNSetFast, ratelimits.Denied).Observe(elapsed.Seconds())
1571 }
1572 return err
1573 }
1574 ra.rlCheckLatency.WithLabelValues(ratelimit.CertificatesPerFQDNSetFast, ratelimits.Allowed).Observe(elapsed.Seconds())
1575 }
1576
1577 fqdnLimits := ra.rlPolicies.CertificatesPerFQDNSet()
1578 if fqdnLimits.Enabled() {
1579 started := ra.clk.Now()
1580 err := ra.checkCertificatesPerFQDNSetLimit(ctx, names, fqdnLimits, regID)
1581 elapsed := ra.clk.Since(started)
1582 if err != nil {
1583 if errors.Is(err, berrors.RateLimit) {
1584 ra.rlCheckLatency.WithLabelValues(ratelimit.CertificatesPerFQDNSet, ratelimits.Denied).Observe(elapsed.Seconds())
1585 }
1586 return err
1587 }
1588 ra.rlCheckLatency.WithLabelValues(ratelimit.CertificatesPerFQDNSet, ratelimits.Allowed).Observe(elapsed.Seconds())
1589 }
1590
1591 invalidAuthzPerAccountLimits := ra.rlPolicies.InvalidAuthorizationsPerAccount()
1592 if invalidAuthzPerAccountLimits.Enabled() {
1593 started := ra.clk.Now()
1594 err := ra.checkInvalidAuthorizationLimits(ctx, regID, names, invalidAuthzPerAccountLimits)
1595 elapsed := ra.clk.Since(started)
1596 if err != nil {
1597 if errors.Is(err, berrors.RateLimit) {
1598 ra.rlCheckLatency.WithLabelValues(ratelimit.InvalidAuthorizationsPerAccount, ratelimits.Denied).Observe(elapsed.Seconds())
1599 }
1600 return err
1601 }
1602 ra.rlCheckLatency.WithLabelValues(ratelimit.InvalidAuthorizationsPerAccount, ratelimits.Allowed).Observe(elapsed.Seconds())
1603 }
1604
1605 return nil
1606 }
1607
1608
1609
1610
1611
1612 func (ra *RegistrationAuthorityImpl) UpdateRegistration(ctx context.Context, req *rapb.UpdateRegistrationRequest) (*corepb.Registration, error) {
1613
1614 if req.Base == nil || len(req.Base.Key) == 0 || len(req.Base.InitialIP) == 0 || req.Base.Id == 0 {
1615 return nil, errIncompleteGRPCRequest
1616 }
1617
1618 err := validateContactsPresent(req.Base.Contact, req.Base.ContactsPresent)
1619 if err != nil {
1620 return nil, err
1621 }
1622 err = validateContactsPresent(req.Update.Contact, req.Update.ContactsPresent)
1623 if err != nil {
1624 return nil, err
1625 }
1626 err = ra.validateContacts(req.Update.Contact)
1627 if err != nil {
1628 return nil, err
1629 }
1630
1631 update, changed := mergeUpdate(req.Base, req.Update)
1632 if !changed {
1633
1634
1635
1636 return req.Base, nil
1637 }
1638
1639 _, err = ra.SA.UpdateRegistration(ctx, update)
1640 if err != nil {
1641
1642
1643 err = berrors.InternalServerError("Could not update registration: %s", err)
1644 return nil, err
1645 }
1646
1647 return update, nil
1648 }
1649
1650 func contactsEqual(a []string, b []string) bool {
1651 if len(a) != len(b) {
1652 return false
1653 }
1654
1655
1656
1657
1658
1659 sort.Strings(a)
1660 sort.Strings(b)
1661 for i := 0; i < len(b); i++ {
1662
1663
1664 if a[i] != b[i] {
1665 return false
1666 }
1667 }
1668
1669
1670 return true
1671 }
1672
1673
1674
1675
1676
1677
1678 func mergeUpdate(base *corepb.Registration, update *corepb.Registration) (*corepb.Registration, bool) {
1679 var changed bool
1680
1681
1682 res := &corepb.Registration{
1683 Id: base.Id,
1684 Key: base.Key,
1685 Contact: base.Contact,
1686 ContactsPresent: base.ContactsPresent,
1687 Agreement: base.Agreement,
1688 InitialIP: base.InitialIP,
1689 CreatedAtNS: base.CreatedAtNS,
1690 CreatedAt: base.CreatedAt,
1691 Status: base.Status,
1692 }
1693
1694
1695
1696
1697
1698 if update.ContactsPresent && !contactsEqual(base.Contact, update.Contact) {
1699 res.Contact = update.Contact
1700 res.ContactsPresent = update.ContactsPresent
1701 changed = true
1702 }
1703
1704 if len(update.Agreement) > 0 && update.Agreement != base.Agreement {
1705 res.Agreement = update.Agreement
1706 changed = true
1707 }
1708
1709 if len(update.Key) > 0 {
1710 if len(update.Key) != len(base.Key) {
1711 res.Key = update.Key
1712 changed = true
1713 } else {
1714 for i := 0; i < len(base.Key); i++ {
1715 if update.Key[i] != base.Key[i] {
1716 res.Key = update.Key
1717 changed = true
1718 break
1719 }
1720 }
1721 }
1722 }
1723
1724 return res, changed
1725 }
1726
1727
1728
1729 func (ra *RegistrationAuthorityImpl) recordValidation(ctx context.Context, authID string, authExpires *time.Time, challenge *core.Challenge) error {
1730 authzID, err := strconv.ParseInt(authID, 10, 64)
1731 if err != nil {
1732 return err
1733 }
1734 var expires time.Time
1735 if challenge.Status == core.StatusInvalid {
1736 expires = *authExpires
1737 } else {
1738 expires = ra.clk.Now().Add(ra.authorizationLifetime)
1739 }
1740 vr, err := bgrpc.ValidationResultToPB(challenge.ValidationRecord, challenge.Error)
1741 if err != nil {
1742 return err
1743 }
1744 var validatedInt int64 = 0
1745 validatedTS := timestamppb.New(time.Time{})
1746 if challenge.Validated != nil {
1747 validatedInt = challenge.Validated.UTC().UnixNano()
1748 validatedTS = timestamppb.New(*challenge.Validated)
1749 }
1750 _, err = ra.SA.FinalizeAuthorization2(ctx, &sapb.FinalizeAuthorizationRequest{
1751 Id: authzID,
1752 Status: string(challenge.Status),
1753 ExpiresNS: expires.UnixNano(),
1754 Expires: timestamppb.New(expires),
1755 Attempted: string(challenge.Type),
1756 AttemptedAtNS: validatedInt,
1757 AttemptedAt: validatedTS,
1758 ValidationRecords: vr.Records,
1759 ValidationError: vr.Problems,
1760 })
1761 if err != nil {
1762 return err
1763 }
1764 return nil
1765 }
1766
1767
1768
1769
1770 func (ra *RegistrationAuthorityImpl) PerformValidation(
1771 ctx context.Context,
1772 req *rapb.PerformValidationRequest) (*corepb.Authorization, error) {
1773
1774
1775 vStart := ra.clk.Now()
1776
1777 if req.Authz == nil || req.Authz.Id == "" || req.Authz.Identifier == "" || req.Authz.Status == "" || req.Authz.ExpiresNS == 0 {
1778 return nil, errIncompleteGRPCRequest
1779 }
1780
1781 authz, err := bgrpc.PBToAuthz(req.Authz)
1782 if err != nil {
1783 return nil, err
1784 }
1785
1786
1787 if authz.Expires == nil || authz.Expires.Before(ra.clk.Now()) {
1788 return nil, berrors.MalformedError("expired authorization")
1789 }
1790
1791 challIndex := int(req.ChallengeIndex)
1792 if challIndex >= len(authz.Challenges) {
1793 return nil,
1794 berrors.MalformedError("invalid challenge index '%d'", challIndex)
1795 }
1796
1797 ch := &authz.Challenges[challIndex]
1798
1799
1800 if !ra.PA.ChallengeTypeEnabled(ch.Type) {
1801 return nil, berrors.MalformedError("challenge type %q no longer allowed", ch.Type)
1802 }
1803
1804
1805
1806
1807
1808 if authz.Status == core.StatusValid {
1809 return req.Authz, nil
1810 }
1811
1812 if authz.Status != core.StatusPending {
1813 return nil, berrors.MalformedError("authorization must be pending")
1814 }
1815
1816
1817 regPB, err := ra.SA.GetRegistration(ctx, &sapb.RegistrationID{Id: authz.RegistrationID})
1818 if err != nil {
1819 return nil, berrors.InternalServerError(err.Error())
1820 }
1821 reg, err := bgrpc.PbToRegistration(regPB)
1822 if err != nil {
1823 return nil, berrors.InternalServerError(err.Error())
1824 }
1825
1826
1827 expectedKeyAuthorization, err := ch.ExpectedKeyAuthorization(reg.Key)
1828 if err != nil {
1829 return nil, berrors.InternalServerError("could not compute expected key authorization value")
1830 }
1831
1832
1833
1834
1835
1836
1837
1838 ch.ProvidedKeyAuthorization = expectedKeyAuthorization
1839
1840
1841 if cErr := ch.CheckConsistencyForValidation(); cErr != nil {
1842 return nil, berrors.MalformedError(cErr.Error())
1843 }
1844
1845
1846 vaCtx := context.Background()
1847 go func(authz core.Authorization) {
1848
1849
1850
1851 challenges := make([]core.Challenge, len(authz.Challenges))
1852 copy(challenges, authz.Challenges)
1853 authz.Challenges = challenges
1854 chall, _ := bgrpc.ChallengeToPB(authz.Challenges[challIndex])
1855
1856 req := vapb.PerformValidationRequest{
1857 Domain: authz.Identifier.Value,
1858 Challenge: chall,
1859 Authz: &vapb.AuthzMeta{
1860 Id: authz.ID,
1861 RegID: authz.RegistrationID,
1862 },
1863 }
1864 res, err := ra.VA.PerformValidation(vaCtx, &req)
1865
1866 challenge := &authz.Challenges[challIndex]
1867 var prob *probs.ProblemDetails
1868
1869 if err != nil {
1870 prob = probs.ServerInternal("Could not communicate with VA")
1871 ra.log.AuditErrf("Could not communicate with VA: %s", err)
1872 } else {
1873 if res.Problems != nil {
1874 prob, err = bgrpc.PBToProblemDetails(res.Problems)
1875 if err != nil {
1876 prob = probs.ServerInternal("Could not communicate with VA")
1877 ra.log.AuditErrf("Could not communicate with VA: %s", err)
1878 }
1879 }
1880
1881
1882 records := make([]core.ValidationRecord, len(res.Records))
1883 for i, r := range res.Records {
1884 records[i], err = bgrpc.PBToValidationRecord(r)
1885 if err != nil {
1886 prob = probs.ServerInternal("Records for validation corrupt")
1887 }
1888 }
1889 challenge.ValidationRecord = records
1890 }
1891
1892 if !challenge.RecordsSane() && prob == nil {
1893 prob = probs.ServerInternal("Records for validation failed sanity check")
1894 }
1895
1896 if prob != nil {
1897 challenge.Status = core.StatusInvalid
1898 challenge.Error = prob
1899 } else {
1900 challenge.Status = core.StatusValid
1901 }
1902 challenge.Validated = &vStart
1903 authz.Challenges[challIndex] = *challenge
1904
1905 err = ra.recordValidation(vaCtx, authz.ID, authz.Expires, challenge)
1906 if err != nil {
1907 ra.log.AuditErrf("Could not record updated validation: regID=[%d] authzID=[%s] err=[%s]",
1908 authz.RegistrationID, authz.ID, err)
1909 }
1910 }(authz)
1911 return bgrpc.AuthzToPB(authz)
1912 }
1913
1914
1915
1916
1917 func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, serial *big.Int, issuerID int64, reason revocation.Reason) error {
1918 serialString := core.SerialToString(serial)
1919 now := ra.clk.Now()
1920
1921 _, err := ra.SA.RevokeCertificate(ctx, &sapb.RevokeCertificateRequest{
1922 Serial: serialString,
1923 Reason: int64(reason),
1924 DateNS: now.UnixNano(),
1925 Date: timestamppb.New(now),
1926 IssuerID: issuerID,
1927 })
1928 if err != nil {
1929 return err
1930 }
1931
1932 ra.revocationReasonCounter.WithLabelValues(revocation.ReasonToString[reason]).Inc()
1933 return nil
1934 }
1935
1936
1937
1938
1939
1940
1941 func (ra *RegistrationAuthorityImpl) updateRevocationForKeyCompromise(ctx context.Context, serial *big.Int, issuerID int64) error {
1942 serialString := core.SerialToString(serial)
1943 now := ra.clk.Now()
1944
1945 status, err := ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: serialString})
1946 if err != nil {
1947 return berrors.NotFoundError("unable to confirm that serial %q was ever issued: %s", serialString, err)
1948 }
1949
1950 if status.Status != string(core.OCSPStatusRevoked) {
1951
1952
1953 return fmt.Errorf("unable to re-revoke serial %q which is not currently revoked", serialString)
1954 }
1955 if status.RevokedReason == ocsp.KeyCompromise {
1956 return berrors.AlreadyRevokedError("unable to re-revoke serial %q which is already revoked for keyCompromise", serialString)
1957 }
1958
1959 _, err = ra.SA.UpdateRevokedCertificate(ctx, &sapb.RevokeCertificateRequest{
1960 Serial: serialString,
1961 Reason: int64(ocsp.KeyCompromise),
1962 DateNS: now.UnixNano(),
1963 Date: timestamppb.New(now),
1964 BackdateNS: status.RevokedDateNS,
1965 Backdate: timestamppb.New(time.Unix(0, status.RevokedDateNS)),
1966 IssuerID: issuerID,
1967 })
1968 if err != nil {
1969 return err
1970 }
1971
1972 ra.revocationReasonCounter.WithLabelValues(revocation.ReasonToString[ocsp.KeyCompromise]).Inc()
1973 return nil
1974 }
1975
1976
1977
1978
1979 func (ra *RegistrationAuthorityImpl) purgeOCSPCache(ctx context.Context, cert *x509.Certificate, issuerID int64) error {
1980 issuer, ok := ra.issuersByNameID[issuance.IssuerNameID(issuerID)]
1981 if !ok {
1982
1983
1984 issuer, ok = ra.issuersByID[issuance.IssuerID(issuerID)]
1985 if !ok {
1986 return fmt.Errorf("unable to identify issuer of cert with serial %q", core.SerialToString(cert.SerialNumber))
1987 }
1988 }
1989
1990 purgeURLs, err := akamai.GeneratePurgeURLs(cert, issuer.Certificate)
1991 if err != nil {
1992 return err
1993 }
1994
1995 _, err = ra.purger.Purge(ctx, &akamaipb.PurgeRequest{Urls: purgeURLs})
1996 if err != nil {
1997 return err
1998 }
1999
2000 return nil
2001 }
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015 func (ra *RegistrationAuthorityImpl) RevokeCertByApplicant(ctx context.Context, req *rapb.RevokeCertByApplicantRequest) (*emptypb.Empty, error) {
2016 if req == nil || req.Cert == nil || req.RegID == 0 {
2017 return nil, errIncompleteGRPCRequest
2018 }
2019
2020 if _, present := revocation.UserAllowedReasons[revocation.Reason(req.Code)]; !present {
2021 return nil, berrors.BadRevocationReasonError(req.Code)
2022 }
2023
2024 cert, err := x509.ParseCertificate(req.Cert)
2025 if err != nil {
2026 return nil, err
2027 }
2028
2029 serialString := core.SerialToString(cert.SerialNumber)
2030
2031 logEvent := certificateRevocationEvent{
2032 ID: core.NewToken(),
2033 SerialNumber: serialString,
2034 Reason: req.Code,
2035 Method: "applicant",
2036 RequesterID: req.RegID,
2037 }
2038
2039
2040
2041
2042 defer func() {
2043 if err != nil {
2044 logEvent.Error = err.Error()
2045 }
2046 ra.log.AuditObject("Revocation request:", logEvent)
2047 }()
2048
2049 metadata, err := ra.SA.GetSerialMetadata(ctx, &sapb.Serial{Serial: serialString})
2050 if err != nil {
2051 return nil, err
2052 }
2053
2054 if req.RegID == metadata.RegistrationID {
2055
2056 logEvent.Method = "subscriber"
2057 } else {
2058
2059
2060 logEvent.Method = "control"
2061
2062 now := ra.clk.Now()
2063 var authzMapPB *sapb.Authorizations
2064 authzMapPB, err = ra.SA.GetValidAuthorizations2(ctx, &sapb.GetValidAuthorizationsRequest{
2065 RegistrationID: req.RegID,
2066 Domains: cert.DNSNames,
2067 NowNS: now.UnixNano(),
2068 Now: timestamppb.New(now),
2069 })
2070 if err != nil {
2071 return nil, err
2072 }
2073
2074 m := make(map[string]struct{})
2075 for _, authz := range authzMapPB.Authz {
2076 m[authz.Domain] = struct{}{}
2077 }
2078 for _, name := range cert.DNSNames {
2079 if _, present := m[name]; !present {
2080 return nil, berrors.UnauthorizedError("requester does not control all names in cert with serial %q", serialString)
2081 }
2082 }
2083
2084
2085
2086
2087
2088 req.Code = ocsp.CessationOfOperation
2089 logEvent.Reason = req.Code
2090 }
2091
2092 issuerID := issuance.GetIssuerNameID(cert)
2093 err = ra.revokeCertificate(
2094 ctx,
2095 cert.SerialNumber,
2096 int64(issuerID),
2097 revocation.Reason(req.Code),
2098 )
2099 if err != nil {
2100 return nil, err
2101 }
2102
2103
2104 _ = ra.purgeOCSPCache(ctx, cert, int64(issuerID))
2105
2106 return &emptypb.Empty{}, nil
2107 }
2108
2109
2110
2111 func (ra *RegistrationAuthorityImpl) addToBlockedKeys(ctx context.Context, key crypto.PublicKey, src string, comment string) error {
2112 var digest core.Sha256Digest
2113 digest, err := core.KeyDigest(key)
2114 if err != nil {
2115 return err
2116 }
2117
2118
2119 now := ra.clk.Now()
2120 _, err = ra.SA.AddBlockedKey(ctx, &sapb.AddBlockedKeyRequest{
2121 KeyHash: digest[:],
2122 AddedNS: now.UnixNano(),
2123 Added: timestamppb.New(now),
2124 Source: src,
2125 Comment: comment,
2126 })
2127 if err != nil {
2128 return err
2129 }
2130
2131 return nil
2132 }
2133
2134
2135
2136
2137
2138
2139
2140 func (ra *RegistrationAuthorityImpl) RevokeCertByKey(ctx context.Context, req *rapb.RevokeCertByKeyRequest) (*emptypb.Empty, error) {
2141 if req == nil || req.Cert == nil {
2142 return nil, errIncompleteGRPCRequest
2143 }
2144
2145 cert, err := x509.ParseCertificate(req.Cert)
2146 if err != nil {
2147 return nil, err
2148 }
2149
2150 issuerID := issuance.GetIssuerNameID(cert)
2151
2152 logEvent := certificateRevocationEvent{
2153 ID: core.NewToken(),
2154 SerialNumber: core.SerialToString(cert.SerialNumber),
2155 Reason: ocsp.KeyCompromise,
2156 Method: "key",
2157 RequesterID: 0,
2158 }
2159
2160
2161
2162
2163 defer func() {
2164 if err != nil {
2165 logEvent.Error = err.Error()
2166 }
2167 ra.log.AuditObject("Revocation request:", logEvent)
2168 }()
2169
2170
2171
2172
2173
2174 revokeErr := ra.revokeCertificate(
2175 ctx,
2176 cert.SerialNumber,
2177 int64(issuerID),
2178 revocation.Reason(ocsp.KeyCompromise),
2179 )
2180
2181
2182
2183
2184 err = ra.addToBlockedKeys(ctx, cert.PublicKey, "API", "")
2185 if err != nil {
2186 return nil, err
2187 }
2188
2189
2190 err = revokeErr
2191 if err == nil {
2192
2193
2194
2195 _ = ra.purgeOCSPCache(ctx, cert, int64(issuerID))
2196 return &emptypb.Empty{}, nil
2197 } else if errors.Is(err, berrors.AlreadyRevoked) {
2198
2199
2200 err = ra.updateRevocationForKeyCompromise(ctx, cert.SerialNumber, int64(issuerID))
2201
2202
2203
2204
2205
2206 _ = ra.purgeOCSPCache(ctx, cert, int64(issuerID))
2207 if err != nil {
2208 return nil, err
2209 }
2210 return &emptypb.Empty{}, nil
2211 } else {
2212
2213 return nil, err
2214 }
2215 }
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225 func (ra *RegistrationAuthorityImpl) AdministrativelyRevokeCertificate(ctx context.Context, req *rapb.AdministrativelyRevokeCertificateRequest) (*emptypb.Empty, error) {
2226 if req == nil || req.AdminName == "" {
2227 return nil, errIncompleteGRPCRequest
2228 }
2229 if req.Serial == "" {
2230 return nil, errIncompleteGRPCRequest
2231 }
2232
2233 reasonCode := revocation.Reason(req.Code)
2234 if reasonCode == ocsp.KeyCompromise && req.Cert == nil && !req.SkipBlockKey {
2235 return nil, fmt.Errorf("cannot revoke and block for KeyCompromise by serial alone")
2236 }
2237 if req.SkipBlockKey && reasonCode != ocsp.KeyCompromise {
2238 return nil, fmt.Errorf("cannot skip key blocking for reasons other than KeyCompromise")
2239 }
2240
2241 if _, present := revocation.AdminAllowedReasons[reasonCode]; !present {
2242 return nil, fmt.Errorf("cannot revoke for reason %d", reasonCode)
2243 }
2244
2245
2246
2247
2248
2249 var cert *x509.Certificate
2250 var issuerID int64
2251 var err error
2252 if req.Cert == nil {
2253 status, err := ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: req.Serial})
2254 if err != nil {
2255 return nil, fmt.Errorf("unable to confirm that serial %q was ever issued: %w", req.Serial, err)
2256 }
2257 issuerID = status.IssuerID
2258 } else {
2259 cert, err = x509.ParseCertificate(req.Cert)
2260 if err != nil {
2261 return nil, err
2262 }
2263 issuerID = int64(issuance.GetIssuerNameID(cert))
2264 }
2265
2266 logEvent := certificateRevocationEvent{
2267 ID: core.NewToken(),
2268 Method: "key",
2269 AdminName: req.AdminName,
2270 SerialNumber: req.Serial,
2271 }
2272
2273
2274
2275
2276 defer func() {
2277 if err != nil {
2278 logEvent.Error = err.Error()
2279 }
2280 ra.log.AuditObject("Revocation request:", logEvent)
2281 }()
2282
2283 var serialInt *big.Int
2284 serialInt, err = core.StringToSerial(req.Serial)
2285 if err != nil {
2286 return nil, err
2287 }
2288
2289 err = ra.revokeCertificate(ctx, serialInt, issuerID, revocation.Reason(req.Code))
2290
2291
2292 if errors.Is(err, berrors.AlreadyRevoked) {
2293 if cert != nil {
2294 err = ra.purgeOCSPCache(ctx, cert, issuerID)
2295 if err != nil {
2296 err = fmt.Errorf("OCSP cache purge for already revoked serial %v failed: %w", serialInt, err)
2297 return nil, err
2298 }
2299 }
2300 }
2301 if err != nil {
2302 if req.Code == ocsp.KeyCompromise && errors.Is(err, berrors.AlreadyRevoked) {
2303 err = ra.updateRevocationForKeyCompromise(ctx, serialInt, issuerID)
2304 if err != nil {
2305 return nil, err
2306 }
2307 }
2308 return nil, err
2309 }
2310
2311 if req.Code == ocsp.KeyCompromise && !req.SkipBlockKey {
2312 if cert == nil {
2313 return nil, errors.New("revoking for key compromise requires providing the certificate's DER")
2314 }
2315 err = ra.addToBlockedKeys(ctx, cert.PublicKey, "admin-revoker", fmt.Sprintf("revoked by %s", req.AdminName))
2316 if err != nil {
2317 return nil, err
2318 }
2319 }
2320
2321 if cert != nil {
2322 err = ra.purgeOCSPCache(ctx, cert, issuerID)
2323 if err != nil {
2324 err = fmt.Errorf("OCSP cache purge for serial %v failed: %w", serialInt, err)
2325 return nil, err
2326 }
2327 }
2328
2329 return &emptypb.Empty{}, nil
2330 }
2331
2332
2333 func (ra *RegistrationAuthorityImpl) DeactivateRegistration(ctx context.Context, reg *corepb.Registration) (*emptypb.Empty, error) {
2334 if reg == nil || reg.Id == 0 {
2335 return nil, errIncompleteGRPCRequest
2336 }
2337 if reg.Status != string(core.StatusValid) {
2338 return nil, berrors.MalformedError("only valid registrations can be deactivated")
2339 }
2340 _, err := ra.SA.DeactivateRegistration(ctx, &sapb.RegistrationID{Id: reg.Id})
2341 if err != nil {
2342 return nil, berrors.InternalServerError(err.Error())
2343 }
2344 return &emptypb.Empty{}, nil
2345 }
2346
2347
2348 func (ra *RegistrationAuthorityImpl) DeactivateAuthorization(ctx context.Context, req *corepb.Authorization) (*emptypb.Empty, error) {
2349 if req == nil || req.Id == "" || req.Status == "" {
2350 return nil, errIncompleteGRPCRequest
2351 }
2352 authzID, err := strconv.ParseInt(req.Id, 10, 64)
2353 if err != nil {
2354 return nil, err
2355 }
2356 if _, err := ra.SA.DeactivateAuthorization2(ctx, &sapb.AuthorizationID2{Id: authzID}); err != nil {
2357 return nil, err
2358 }
2359 return &emptypb.Empty{}, nil
2360 }
2361
2362
2363
2364
2365
2366 func (ra *RegistrationAuthorityImpl) checkOrderNames(names []string) error {
2367 idents := make([]identifier.ACMEIdentifier, len(names))
2368 for i, name := range names {
2369 idents[i] = identifier.DNSIdentifier(name)
2370 }
2371 err := ra.PA.WillingToIssueWildcards(idents)
2372 if err != nil {
2373 return err
2374 }
2375 return nil
2376 }
2377
2378
2379
2380
2381 func (ra *RegistrationAuthorityImpl) GenerateOCSP(ctx context.Context, req *rapb.GenerateOCSPRequest) (*capb.OCSPResponse, error) {
2382 status, err := ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: req.Serial})
2383 if err != nil {
2384 return nil, err
2385 }
2386
2387
2388
2389
2390
2391
2392
2393 if status.Status == string(core.OCSPStatusNotReady) {
2394 return nil, errors.New("serial belongs to a certificate that errored during issuance")
2395 }
2396
2397 notAfter := time.Unix(0, status.NotAfterNS).UTC()
2398 if ra.clk.Now().After(notAfter) {
2399 return nil, berrors.NotFoundError("certificate is expired")
2400 }
2401
2402 return ra.OCSP.GenerateOCSP(ctx, &capb.GenerateOCSPRequest{
2403 Serial: req.Serial,
2404 Status: status.Status,
2405 Reason: int32(status.RevokedReason),
2406 RevokedAtNS: status.RevokedDateNS,
2407 RevokedAt: timestamppb.New(time.Unix(0, status.RevokedDateNS)),
2408 IssuerID: status.IssuerID,
2409 })
2410 }
2411
2412
2413 func (ra *RegistrationAuthorityImpl) NewOrder(ctx context.Context, req *rapb.NewOrderRequest) (*corepb.Order, error) {
2414 if req == nil || req.RegistrationID == 0 {
2415 return nil, errIncompleteGRPCRequest
2416 }
2417
2418 newOrder := &sapb.NewOrderRequest{
2419 RegistrationID: req.RegistrationID,
2420 Names: core.UniqueLowerNames(req.Names),
2421 }
2422
2423 if len(newOrder.Names) > ra.maxNames {
2424 return nil, berrors.MalformedError(
2425 "Order cannot contain more than %d DNS names", ra.maxNames)
2426 }
2427
2428
2429 err := ra.checkOrderNames(newOrder.Names)
2430 if err != nil {
2431 return nil, err
2432 }
2433
2434 err = wildcardOverlap(newOrder.Names)
2435 if err != nil {
2436 return nil, err
2437 }
2438
2439
2440
2441 existingOrder, err := ra.SA.GetOrderForNames(ctx, &sapb.GetOrderForNamesRequest{
2442 AcctID: newOrder.RegistrationID,
2443 Names: newOrder.Names,
2444 })
2445
2446
2447 if err != nil && !errors.Is(err, berrors.NotFound) {
2448 return nil, err
2449 }
2450
2451
2452
2453 if existingOrder != nil {
2454
2455 if existingOrder.Id == 0 || existingOrder.CreatedNS == 0 || existingOrder.Status == "" || existingOrder.RegistrationID == 0 || existingOrder.ExpiresNS == 0 || len(existingOrder.Names) == 0 {
2456 return nil, errIncompleteGRPCResponse
2457 }
2458
2459 ra.orderAges.WithLabelValues("NewOrder").Observe(ra.clk.Since(time.Unix(0, existingOrder.CreatedNS)).Seconds())
2460 return existingOrder, nil
2461 }
2462
2463
2464 err = ra.checkNewOrderLimits(ctx, newOrder.Names, newOrder.RegistrationID)
2465 if err != nil {
2466 return nil, err
2467 }
2468
2469
2470
2471
2472
2473
2474
2475
2476 authzExpiryCutoff := ra.clk.Now().AddDate(0, 0, 1)
2477
2478 getAuthReq := &sapb.GetAuthorizationsRequest{
2479 RegistrationID: newOrder.RegistrationID,
2480 NowNS: authzExpiryCutoff.UnixNano(),
2481 Now: timestamppb.New(authzExpiryCutoff),
2482 Domains: newOrder.Names,
2483 }
2484 existingAuthz, err := ra.SA.GetAuthorizations2(ctx, getAuthReq)
2485 if err != nil {
2486 return nil, err
2487 }
2488
2489
2490
2491 nameToExistingAuthz := make(map[string]*corepb.Authorization, len(newOrder.Names))
2492 for _, v := range existingAuthz.Authz {
2493 nameToExistingAuthz[v.Domain] = v.Authz
2494 }
2495
2496
2497
2498
2499 var missingAuthzNames []string
2500 for _, name := range newOrder.Names {
2501
2502 if _, exists := nameToExistingAuthz[name]; !exists {
2503 missingAuthzNames = append(missingAuthzNames, name)
2504 continue
2505 }
2506 authz := nameToExistingAuthz[name]
2507 authzAge := (ra.authorizationLifetime - time.Unix(0, authz.ExpiresNS).Sub(ra.clk.Now())).Seconds()
2508
2509
2510
2511
2512
2513 if strings.HasPrefix(name, "*.") &&
2514 len(authz.Challenges) == 1 && core.AcmeChallenge(authz.Challenges[0].Type) == core.ChallengeTypeDNS01 {
2515 authzID, err := strconv.ParseInt(authz.Id, 10, 64)
2516 if err != nil {
2517 return nil, err
2518 }
2519 newOrder.V2Authorizations = append(newOrder.V2Authorizations, authzID)
2520 ra.authzAges.WithLabelValues("NewOrder", authz.Status).Observe(authzAge)
2521 continue
2522 } else if !strings.HasPrefix(name, "*.") {
2523
2524 authzID, err := strconv.ParseInt(authz.Id, 10, 64)
2525 if err != nil {
2526 return nil, err
2527 }
2528 newOrder.V2Authorizations = append(newOrder.V2Authorizations, authzID)
2529 ra.authzAges.WithLabelValues("NewOrder", authz.Status).Observe(authzAge)
2530 continue
2531 }
2532
2533
2534 delete(nameToExistingAuthz, name)
2535
2536
2537 missingAuthzNames = append(missingAuthzNames, name)
2538 }
2539
2540
2541
2542 if len(missingAuthzNames) > 0 {
2543 pendingAuthzLimits := ra.rlPolicies.PendingAuthorizationsPerAccount()
2544 if pendingAuthzLimits.Enabled() {
2545 started := ra.clk.Now()
2546 err := ra.checkPendingAuthorizationLimit(ctx, newOrder.RegistrationID, pendingAuthzLimits)
2547 elapsed := ra.clk.Since(started)
2548 if err != nil {
2549 if errors.Is(err, berrors.RateLimit) {
2550 ra.rlCheckLatency.WithLabelValues(ratelimit.PendingAuthorizationsPerAccount, ratelimits.Denied).Observe(elapsed.Seconds())
2551 }
2552 return nil, err
2553 }
2554 ra.rlCheckLatency.WithLabelValues(ratelimit.PendingAuthorizationsPerAccount, ratelimits.Allowed).Observe(elapsed.Seconds())
2555 }
2556 }
2557
2558
2559
2560 var newAuthzs []*corepb.Authorization
2561 for _, name := range missingAuthzNames {
2562 pb, err := ra.createPendingAuthz(newOrder.RegistrationID, identifier.ACMEIdentifier{
2563 Type: identifier.DNS,
2564 Value: name,
2565 })
2566 if err != nil {
2567 return nil, err
2568 }
2569 newAuthzs = append(newAuthzs, pb)
2570 ra.authzAges.WithLabelValues("NewOrder", pb.Status).Observe(0)
2571 }
2572
2573
2574
2575 minExpiry := ra.clk.Now().Add(ra.orderLifetime)
2576
2577
2578
2579 for _, authz := range nameToExistingAuthz {
2580
2581 if authz.ExpiresNS == 0 {
2582 return nil, berrors.InternalServerError(
2583 "SA.GetAuthorizations returned an authz (%s) with zero expiry",
2584 authz.Id)
2585 }
2586
2587
2588 authzExpiry := time.Unix(0, authz.ExpiresNS)
2589 if authzExpiry.Before(minExpiry) {
2590 minExpiry = authzExpiry
2591 }
2592 }
2593
2594
2595 if len(newAuthzs) > 0 {
2596 newPendingAuthzExpires := ra.clk.Now().Add(ra.pendingAuthorizationLifetime)
2597 if newPendingAuthzExpires.Before(minExpiry) {
2598 minExpiry = newPendingAuthzExpires
2599 }
2600 }
2601
2602
2603 newOrder.ExpiresNS = minExpiry.Truncate(time.Second).UnixNano()
2604 newOrder.Expires = timestamppb.New(minExpiry.Truncate(time.Second))
2605
2606 newOrderAndAuthzsReq := &sapb.NewOrderAndAuthzsRequest{
2607 NewOrder: newOrder,
2608 NewAuthzs: newAuthzs,
2609 }
2610 storedOrder, err := ra.SA.NewOrderAndAuthzs(ctx, newOrderAndAuthzsReq)
2611 if err != nil {
2612 return nil, err
2613 }
2614 if storedOrder.Id == 0 || storedOrder.CreatedNS == 0 || storedOrder.Status == "" || storedOrder.RegistrationID == 0 || storedOrder.ExpiresNS == 0 || len(storedOrder.Names) == 0 {
2615 return nil, errIncompleteGRPCResponse
2616 }
2617 ra.orderAges.WithLabelValues("NewOrder").Observe(0)
2618
2619
2620 ra.namesPerCert.With(prometheus.Labels{"type": "requested"}).Observe(float64(len(storedOrder.Names)))
2621
2622 return storedOrder, nil
2623 }
2624
2625
2626
2627
2628 func (ra *RegistrationAuthorityImpl) createPendingAuthz(reg int64, identifier identifier.ACMEIdentifier) (*corepb.Authorization, error) {
2629 expires := ra.clk.Now().Add(ra.pendingAuthorizationLifetime).Truncate(time.Second)
2630 authz := &corepb.Authorization{
2631 Identifier: identifier.Value,
2632 RegistrationID: reg,
2633 Status: string(core.StatusPending),
2634 ExpiresNS: expires.UnixNano(),
2635 Expires: timestamppb.New(expires),
2636 }
2637
2638
2639 challenges, err := ra.PA.ChallengesFor(identifier)
2640 if err != nil {
2641
2642
2643
2644 return nil, berrors.InternalServerError(err.Error())
2645 }
2646
2647 for _, challenge := range challenges {
2648 err := challenge.CheckConsistencyForClientOffer()
2649 if err != nil {
2650
2651
2652 err = berrors.InternalServerError("challenge didn't pass sanity check: %+v", challenge)
2653 return nil, err
2654 }
2655 challPB, err := bgrpc.ChallengeToPB(challenge)
2656 if err != nil {
2657 return nil, err
2658 }
2659 authz.Challenges = append(authz.Challenges, challPB)
2660 }
2661 return authz, nil
2662 }
2663
2664
2665
2666 func wildcardOverlap(dnsNames []string) error {
2667 nameMap := make(map[string]bool, len(dnsNames))
2668 for _, v := range dnsNames {
2669 nameMap[v] = true
2670 }
2671 for name := range nameMap {
2672 if name[0] == '*' {
2673 continue
2674 }
2675 labels := strings.Split(name, ".")
2676 labels[0] = "*"
2677 if nameMap[strings.Join(labels, ".")] {
2678 return berrors.MalformedError(
2679 "Domain name %q is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.", name)
2680 }
2681 }
2682 return nil
2683 }
2684
2685
2686
2687
2688
2689
2690
2691
2692 func validateContactsPresent(contacts []string, contactsPresent bool) error {
2693 if len(contacts) > 0 && !contactsPresent {
2694 return berrors.InternalServerError("account contacts present but contactsPresent false")
2695 }
2696 return nil
2697 }
2698
2699 func (ra *RegistrationAuthorityImpl) DrainFinalize() {
2700 ra.finalizeWG.Wait()
2701 }
2702
View as plain text