From 351dc6a5bf92a5f2ae22fadeee08eb6a45aa2d93 Mon Sep 17 00:00:00 2001 From: Alex Vaghin Date: Wed, 24 Aug 2016 15:50:57 +0200 Subject: [PATCH] acme: add client.DNS01ChallengeRecord This change adds implementation for dns-01 challenge responses. Change-Id: I22b2b304ca4a2caeec2980feff19a6c2bc277d8c Reviewed-on: https://go-review.googlesource.com/27613 Reviewed-by: Brad Fitzpatrick --- acme/internal/acme/acme.go | 14 ++++++++++++++ acme/internal/acme/acme_test.go | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/acme/internal/acme/acme.go b/acme/internal/acme/acme.go index 9eb35a3..0439f7e 100644 --- a/acme/internal/acme/acme.go +++ b/acme/internal/acme/acme.go @@ -471,6 +471,20 @@ func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error return v.challenge(), nil } +// DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response. +// A TXT record containing the returned value must be provisioned under +// "_acme-challenge" name of the domain being validated. +// +// The token argument is a Challenge.Token value. +func (c *Client) DNS01ChallengeRecord(token string) (string, error) { + ka, err := keyAuth(c.Key.Public(), token) + if err != nil { + return "", err + } + b := sha256.Sum256([]byte(ka)) + return base64.RawURLEncoding.EncodeToString(b[:]), nil +} + // HTTP01ChallengeResponse returns the response for an http-01 challenge. // Servers should respond with the value to HTTP requests at the URL path // provided by HTTP01ChallengePath to validate the challenge and prove control diff --git a/acme/internal/acme/acme_test.go b/acme/internal/acme/acme_test.go index 364cd68..2ae69a9 100644 --- a/acme/internal/acme/acme_test.go +++ b/acme/internal/acme/acme_test.go @@ -1044,6 +1044,22 @@ func TestHTTP01Challenge(t *testing.T) { } } +func TestDNS01ChallengeRecord(t *testing.T) { + // echo -n xxx. | \ + // openssl dgst -binary -sha256 | \ + // base64 | tr -d '=' | tr '/+' '_-' + const value = "8DERMexQ5VcdJ_prpPiA0mVdp7imgbCgjsG4SqqNMIo" + + client := &Client{Key: testKeyEC} + val, err := client.DNS01ChallengeRecord("xxx") + if err != nil { + t.Fatal(err) + } + if val != value { + t.Errorf("val = %q; want %q", val, value) + } +} + func TestBackoff(t *testing.T) { tt := []struct{ min, max time.Duration }{ {time.Second, 2 * time.Second},