mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 13:18:53 +00:00
tempfork/acme: update to latest version (#15543)
Pull in https://github.com/tailscale/golang-x-crypto/pull/16 Updates #15542 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
2
go.mod
2
go.mod
@@ -77,7 +77,7 @@ require (
|
||||
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e
|
||||
github.com/tailscale/depaware v0.0.0-20250112153213-b748de04d81b
|
||||
github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20250218230618-9a281fd8faca
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869
|
||||
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05
|
||||
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a
|
||||
github.com/tailscale/mkctr v0.0.0-20250228050937-c75ea1476830
|
||||
|
4
go.sum
4
go.sum
@@ -910,8 +910,8 @@ github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8
|
||||
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg=
|
||||
github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41 h1:/V2rCMMWcsjYaYO2MeovLw+ClP63OtXgCF2Y1eb8+Ns=
|
||||
github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ=
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20250218230618-9a281fd8faca h1:ecjHwH73Yvqf/oIdQ2vxAX+zc6caQsYdPzsxNW1J3G8=
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20250218230618-9a281fd8faca/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ=
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869 h1:SRL6irQkKGQKKLzvQP/ke/2ZuB7Py5+XuqtOgSj+iMM=
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ=
|
||||
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio=
|
||||
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8=
|
||||
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw=
|
||||
|
@@ -270,10 +270,7 @@ func (c *Client) FetchRenewalInfo(ctx context.Context, leaf []byte) (*RenewalInf
|
||||
return nil, fmt.Errorf("parsing leaf certificate: %w", err)
|
||||
}
|
||||
|
||||
renewalURL, err := c.getRenewalURL(parsedLeaf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generating renewal info URL: %w", err)
|
||||
}
|
||||
renewalURL := c.getRenewalURL(parsedLeaf)
|
||||
|
||||
res, err := c.get(ctx, renewalURL, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
@@ -288,16 +285,20 @@ func (c *Client) FetchRenewalInfo(ctx context.Context, leaf []byte) (*RenewalInf
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (c *Client) getRenewalURL(cert *x509.Certificate) (string, error) {
|
||||
func (c *Client) getRenewalURL(cert *x509.Certificate) string {
|
||||
// See https://www.ietf.org/archive/id/draft-ietf-acme-ari-04.html#name-the-renewalinfo-resource
|
||||
// for how the request URL is built.
|
||||
url := c.dir.RenewalInfoURL
|
||||
if !strings.HasSuffix(url, "/") {
|
||||
url += "/"
|
||||
}
|
||||
return url + certRenewalIdentifier(cert)
|
||||
}
|
||||
|
||||
func certRenewalIdentifier(cert *x509.Certificate) string {
|
||||
aki := base64.RawURLEncoding.EncodeToString(cert.AuthorityKeyId)
|
||||
serial := base64.RawURLEncoding.EncodeToString(cert.SerialNumber.Bytes())
|
||||
return fmt.Sprintf("%s%s.%s", url, aki, serial), nil
|
||||
return aki + "." + serial
|
||||
}
|
||||
|
||||
// AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service
|
||||
|
@@ -549,10 +549,7 @@ func TestGetRenewalURL(t *testing.T) {
|
||||
}
|
||||
|
||||
client := newTestClientWithMockDirectory()
|
||||
urlString, err := client.getRenewalURL(parsedLeaf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
urlString := client.getRenewalURL(parsedLeaf)
|
||||
|
||||
parsedURL, err := url.Parse(urlString)
|
||||
if err != nil {
|
||||
|
@@ -7,6 +7,7 @@ package acme
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
@@ -205,6 +206,7 @@ func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderO
|
||||
Identifiers []wireAuthzID `json:"identifiers"`
|
||||
NotBefore string `json:"notBefore,omitempty"`
|
||||
NotAfter string `json:"notAfter,omitempty"`
|
||||
Replaces string `json:"replaces,omitempty"`
|
||||
}{}
|
||||
for _, v := range id {
|
||||
req.Identifiers = append(req.Identifiers, wireAuthzID{
|
||||
@@ -218,6 +220,14 @@ func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderO
|
||||
req.NotBefore = time.Time(o).Format(time.RFC3339)
|
||||
case orderNotAfterOpt:
|
||||
req.NotAfter = time.Time(o).Format(time.RFC3339)
|
||||
case orderReplacesCert:
|
||||
req.Replaces = certRenewalIdentifier(o.cert)
|
||||
case orderReplacesCertDER:
|
||||
cert, err := x509.ParseCertificate(o)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse certificate being replaced: %w", err)
|
||||
}
|
||||
req.Replaces = certRenewalIdentifier(cert)
|
||||
default:
|
||||
// Package's fault if we let this happen.
|
||||
panic(fmt.Sprintf("unsupported order option type %T", o))
|
||||
|
@@ -766,10 +766,17 @@ func TestRFC_AuthorizeOrder(t *testing.T) {
|
||||
s.start()
|
||||
defer s.close()
|
||||
|
||||
prevCertDER, _ := pem.Decode([]byte(leafPEM))
|
||||
prevCert, err := x509.ParseCertificate(prevCertDER.Bytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
|
||||
o, err := cl.AuthorizeOrder(context.Background(), DomainIDs("example.org"),
|
||||
WithOrderNotBefore(time.Date(2019, 8, 31, 0, 0, 0, 0, time.UTC)),
|
||||
WithOrderNotAfter(time.Date(2019, 9, 2, 0, 0, 0, 0, time.UTC)),
|
||||
WithOrderReplacesCert(prevCert),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@@ -391,6 +391,30 @@ type orderNotAfterOpt time.Time
|
||||
|
||||
func (orderNotAfterOpt) privateOrderOpt() {}
|
||||
|
||||
// WithOrderReplacesCert indicates that this Order is for a replacement of an
|
||||
// existing certificate.
|
||||
// See https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5
|
||||
func WithOrderReplacesCert(cert *x509.Certificate) OrderOption {
|
||||
return orderReplacesCert{cert}
|
||||
}
|
||||
|
||||
type orderReplacesCert struct {
|
||||
cert *x509.Certificate
|
||||
}
|
||||
|
||||
func (orderReplacesCert) privateOrderOpt() {}
|
||||
|
||||
// WithOrderReplacesCertDER indicates that this Order is for a replacement of
|
||||
// an existing DER-encoded certificate.
|
||||
// See https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5
|
||||
func WithOrderReplacesCertDER(der []byte) OrderOption {
|
||||
return orderReplacesCertDER(der)
|
||||
}
|
||||
|
||||
type orderReplacesCertDER []byte
|
||||
|
||||
func (orderReplacesCertDER) privateOrderOpt() {}
|
||||
|
||||
// Authorization encodes an authorization response.
|
||||
type Authorization struct {
|
||||
// URI uniquely identifies a authorization.
|
||||
|
Reference in New Issue
Block a user