Skip to content

Commit ca90c4c

Browse files
committed
ACMEv2 POST-as-GET support
©! I, Hugo Landau <[email protected]>, hereby licence these changes under the ©! licence with SHA256 hash ©! fd80a26fbb3f644af1fa994134446702932968519797227e07a1368dea80f0bc.
1 parent 4dfbe62 commit ca90c4c

File tree

13 files changed

+63
-27
lines changed

13 files changed

+63
-27
lines changed

cli/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import (
1010
"strings"
1111
"syscall"
1212

13-
"github.com/hlandau/acmeapi"
14-
"github.com/hlandau/acmeapi/acmeutils"
1513
"github.com/hlandau/acmetool/hooks"
1614
"github.com/hlandau/acmetool/interaction"
1715
"github.com/hlandau/acmetool/redirector"
@@ -21,6 +19,8 @@ import (
2119
"github.com/hlandau/dexlogconfig"
2220
"github.com/hlandau/xlog"
2321
"gopkg.in/alecthomas/kingpin.v2"
22+
"gopkg.in/hlandau/acmeapi.v2"
23+
"gopkg.in/hlandau/acmeapi.v2/acmeutils"
2424
"gopkg.in/hlandau/easyconfig.v1/adaptflag"
2525
"gopkg.in/hlandau/service.v2"
2626
"gopkg.in/square/go-jose.v1"

cli/main_ig_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ package cli
44

55
import (
66
"fmt"
7-
//"github.com/hlandau/acmeapi"
8-
"github.com/hlandau/acmeapi/pebbletest"
7+
//"gopkg.in/hlandau/acmeapi.v2"
98
"github.com/hlandau/acmetool/interaction"
109
"github.com/hlandau/acmetool/responder"
1110
"github.com/hlandau/acmetool/storageops"
11+
"gopkg.in/hlandau/acmeapi.v2/pebbletest"
1212
"io/ioutil"
1313
"path/filepath"
1414
"strings"

cli/quickstart.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import (
44
"bytes"
55
"crypto/rand"
66
"fmt"
7-
"github.com/hlandau/acmeapi"
8-
"github.com/hlandau/acmeapi/acmeendpoints"
97
"github.com/hlandau/acmetool/hooks"
108
"github.com/hlandau/acmetool/interaction"
119
"github.com/hlandau/acmetool/storage"
1210
"github.com/hlandau/acmetool/storageops"
11+
"gopkg.in/hlandau/acmeapi.v2"
12+
"gopkg.in/hlandau/acmeapi.v2/acmeendpoints"
1313
"gopkg.in/hlandau/svcutils.v1/exepath"
1414
"gopkg.in/hlandau/svcutils.v1/passwd"
1515
"io/ioutil"

responder/dns.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"crypto"
55
"encoding/json"
66
"fmt"
7-
"github.com/hlandau/acmeapi/acmeutils"
7+
"gopkg.in/hlandau/acmeapi.v2/acmeutils"
88
)
99

1010
type DNSChallengeInfo struct {

responder/http.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import (
66
"crypto/tls"
77
"encoding/json"
88
"fmt"
9-
"github.com/hlandau/acmeapi/acmeutils"
109
"github.com/hlandau/acmetool/responder/reshttp"
1110
denet "github.com/hlandau/goutils/net"
1211
deos "github.com/hlandau/goutils/os"
12+
"gopkg.in/hlandau/acmeapi.v2/acmeutils"
1313
"io/ioutil"
1414
"net"
1515
"net/http"

solver/order.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ package solver
33
import (
44
"context"
55
"fmt"
6-
"github.com/hlandau/acmeapi"
76
"github.com/hlandau/acmetool/responder"
87
"github.com/hlandau/acmetool/util"
98
denet "github.com/hlandau/goutils/net"
109
"github.com/hlandau/xlog"
10+
"gopkg.in/hlandau/acmeapi.v2"
1111
"sync"
1212
"time"
1313
)
@@ -100,7 +100,7 @@ func orderProcess(ctx context.Context, rc *acmeapi.RealmClient, acct *acmeapi.Ac
100100
}
101101

102102
// Get a fresh picture of the order status. orderAuthorizeAll doesn't refresh it.
103-
err = rc.LoadOrder(ctx, order)
103+
err = rc.LoadOrder(ctx, acct, order)
104104
if err != nil {
105105
return true, err
106106
}

solver/preference.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package solver
22

33
import (
4-
"github.com/hlandau/acmeapi"
4+
"gopkg.in/hlandau/acmeapi.v2"
55
"sort"
66
)
77

solver/register.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package solver
22

33
import (
44
"fmt"
5-
"github.com/hlandau/acmeapi"
65
"github.com/hlandau/acmetool/interaction"
76
"golang.org/x/net/context"
7+
"gopkg.in/hlandau/acmeapi.v2"
88
"net/mail"
99
)
1010

storage/abs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type Store interface {
4444

4545
ImportKey(privateKey crypto.PrivateKey) (*Key, error) // Imports the key if it isn't already imported.
4646
ImportAccount(directoryURL string, privateKey crypto.PrivateKey) (*Account, error) // Imports an account key if it isn't already imported.
47-
ImportCertificate(url string) (*Certificate, error) // Imports a certificate if it isn't already imported.
47+
ImportCertificate(acct *Account, url string) (*Certificate, error) // Imports a certificate if it isn't already imported.
4848

4949
SetPreferredCertificateForHostname(hostname string, c *Certificate) error
5050

storage/storage-fdb.go

+24-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import (
66
"crypto"
77
"crypto/x509"
88
"fmt"
9-
"github.com/hlandau/acmeapi"
10-
"github.com/hlandau/acmeapi/acmeutils"
119
"github.com/hlandau/acmetool/fdb"
1210
"github.com/hlandau/acmetool/util"
1311
"github.com/hlandau/xlog"
12+
"gopkg.in/hlandau/acmeapi.v2"
13+
"gopkg.in/hlandau/acmeapi.v2/acmeutils"
1414
"gopkg.in/yaml.v2"
1515
"io"
1616
"io/ioutil"
@@ -491,6 +491,18 @@ func (s *fdbStore) validateCert(certID string, c *fdb.Collection) error {
491491
crt.Cached = true
492492
}
493493

494+
acctLink, err := c.ReadLink("account")
495+
if err == nil {
496+
if !strings.HasPrefix(acctLink.Target, "accounts/") {
497+
return fmt.Errorf("malformed certificate account symlink: %q %q", certID, acctLink.Target)
498+
}
499+
500+
crt.Account = s.AccountByID(acctLink.Target[9:])
501+
if crt.Account == nil {
502+
log.Warnf("certificate directory %#v contains account reference %#v but no such account was found", certID, acctLink.Target)
503+
}
504+
}
505+
494506
s.certs[certID] = crt
495507

496508
return nil
@@ -775,20 +787,27 @@ func (s *fdbStore) ImportKey(privateKey crypto.PrivateKey) (*Key, error) {
775787
// Given a certificate URL, imports the certificate into the store. The
776788
// certificate will be retrieved on the next reconcile. If a certificate with
777789
// that URL already exists, this is a no-op and returns nil.
778-
func (s *fdbStore) ImportCertificate(url string) (*Certificate, error) {
790+
func (s *fdbStore) ImportCertificate(acct *Account, url string) (*Certificate, error) {
779791
certID := determineCertificateID(url)
780792
c, ok := s.certs[certID]
781793
if ok {
782794
return c, nil
783795
}
784796

785-
err := fdb.WriteBytes(s.db.Collection("certs/"+certID), "url", []byte(url))
797+
coll := s.db.Collection("certs/" + certID)
798+
err := coll.WriteLink("account", fdb.Link{"accounts/" + acct.ID()})
799+
if err != nil {
800+
return nil, err
801+
}
802+
803+
err = fdb.WriteBytes(coll, "url", []byte(url))
786804
if err != nil {
787805
return nil, err
788806
}
789807

790808
c = &Certificate{
791-
URL: url,
809+
URL: url,
810+
Account: acct,
792811
}
793812

794813
s.certs[certID] = c

storage/types.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"crypto/rsa"
77
"encoding/base32"
88
"fmt"
9-
"github.com/hlandau/acmeapi"
109
"github.com/satori/go.uuid"
10+
"gopkg.in/hlandau/acmeapi.v2"
1111
"strings"
1212
)
1313

@@ -250,6 +250,11 @@ type Certificate struct {
250250
// N (for now). Whether this certificate has been revoked.
251251
Revoked bool
252252

253+
// N. Now required due to need to support POST-as-GET. The account under
254+
// which the certificate was requested. nil if this is unknown due to being a
255+
// legacy certificate directory.
256+
Account *Account
257+
253258
// D. Certificate data retrieved from URL, plus chained certificates.
254259
// The end certificate comes first, the root last, etc.
255260
Certificates [][]byte

storage/util.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"crypto/x509"
1010
"encoding/base32"
1111
"fmt"
12-
"github.com/hlandau/acmeapi/acmeutils"
12+
"gopkg.in/hlandau/acmeapi.v2/acmeutils"
1313
"io"
1414
"math/big"
1515
"net/url"

storageops/reconcile.go

+19-7
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import (
99
"crypto/x509/pkix"
1010
"encoding/asn1"
1111
"fmt"
12-
"github.com/hlandau/acmeapi"
13-
"github.com/hlandau/acmeapi/acmeendpoints"
1412
"github.com/hlandau/acmetool/hooks"
1513
"github.com/hlandau/acmetool/responder"
1614
"github.com/hlandau/acmetool/solver"
1715
"github.com/hlandau/acmetool/storage"
1816
"github.com/hlandau/acmetool/util"
1917
"github.com/hlandau/xlog"
2018
"github.com/jmhodges/clock"
19+
"gopkg.in/hlandau/acmeapi.v2"
20+
"gopkg.in/hlandau/acmeapi.v2/acmeendpoints"
2121
"net/http"
2222
"path/filepath"
2323
"sort"
@@ -458,7 +458,7 @@ func (r *reconcile) requestCertificateForTarget(t *storage.Target) error {
458458
return err
459459
}
460460

461-
c, err := r.store.ImportCertificate(order.URL)
461+
c, err := r.store.ImportCertificate(acct, order.URL)
462462
if err != nil {
463463
log.Errore(err, "could not import certificate")
464464
return err
@@ -590,14 +590,26 @@ func (r *reconcile) generateOrGetKey(trk *storage.TargetRequestKey) (crypto.Priv
590590
func (r *reconcile) downloadCertificateAdaptive(c *storage.Certificate) error {
591591
log.Debugf("downloading certificate %v", c)
592592

593-
cl, err := r.getGenericClient()
593+
if c.Account == nil {
594+
return fmt.Errorf("cannot download certificate because it is unknown which account requested it: %v", c)
595+
}
596+
597+
cl, err := r.getClientForDirectoryURL(c.Account.DirectoryURL)
594598
if err != nil {
595599
return err
596600
}
597601

602+
acctAPI := c.Account.ToAPI()
603+
if acctAPI.URL == "" {
604+
err = cl.LocateAccount(context.TODO(), acctAPI)
605+
if err != nil {
606+
return err
607+
}
608+
}
609+
598610
order := &acmeapi.Order{}
599611
cert := &acmeapi.Certificate{}
600-
isCert, err := cl.LoadOrderOrCertificate(context.TODO(), c.URL, order, cert)
612+
isCert, err := cl.LoadOrderOrCertificate(context.TODO(), c.URL, acctAPI, order, cert)
601613
if err != nil {
602614
return err
603615
}
@@ -621,7 +633,7 @@ func (r *reconcile) downloadCertificateAdaptive(c *storage.Certificate) error {
621633
return err
622634
}
623635

624-
err = cl.WaitLoadOrder(context.TODO(), order)
636+
err = cl.WaitLoadOrder(context.TODO(), acctAPI, order)
625637
if err != nil {
626638
return err
627639
}
@@ -640,7 +652,7 @@ func (r *reconcile) downloadCertificateAdaptive(c *storage.Certificate) error {
640652
URL: order.CertificateURL,
641653
}
642654

643-
err = cl.LoadCertificate(context.TODO(), cert)
655+
err = cl.LoadCertificate(context.TODO(), acctAPI, cert)
644656
if err != nil {
645657
return err
646658
}

0 commit comments

Comments
 (0)