summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/xenolf/lego
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2017-02-02 09:32:00 -0500
committerHarrison Healey <harrisonmhealey@gmail.com>2017-02-02 09:32:00 -0500
commit701d1ab638b23c24877fc41824add66232446676 (patch)
treeec120c88d38ac9d38d9eabdd3270b52bb6ac9d96 /vendor/github.com/xenolf/lego
parentca3211bc04f6dea34e8168217182637d1419f998 (diff)
downloadchat-701d1ab638b23c24877fc41824add66232446676.tar.gz
chat-701d1ab638b23c24877fc41824add66232446676.tar.bz2
chat-701d1ab638b23c24877fc41824add66232446676.zip
Updating server dependancies (#5249)
Diffstat (limited to 'vendor/github.com/xenolf/lego')
-rw-r--r--vendor/github.com/xenolf/lego/README.md2
-rw-r--r--vendor/github.com/xenolf/lego/acme/client.go149
-rw-r--r--vendor/github.com/xenolf/lego/acme/crypto.go2
-rw-r--r--vendor/github.com/xenolf/lego/acme/error.go15
-rw-r--r--vendor/github.com/xenolf/lego/acme/jws.go12
-rw-r--r--vendor/github.com/xenolf/lego/acme/messages.go23
-rw-r--r--vendor/github.com/xenolf/lego/cli_handlers.go8
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/azure/azure.go4
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go14
9 files changed, 128 insertions, 101 deletions
diff --git a/vendor/github.com/xenolf/lego/README.md b/vendor/github.com/xenolf/lego/README.md
index 136bc5548..9be562944 100644
--- a/vendor/github.com/xenolf/lego/README.md
+++ b/vendor/github.com/xenolf/lego/README.md
@@ -244,7 +244,7 @@ if err != nil {
// The acme library takes care of completing the challenges to obtain the certificate(s).
// The domains must resolve to this machine or you have to use the DNS challenge.
bundle := false
-certificates, failures := client.ObtainCertificate([]string{"mydomain.com"}, bundle, nil)
+certificates, failures := client.ObtainCertificate([]string{"mydomain.com"}, bundle, nil, false)
if len(failures) > 0 {
log.Fatal(failures)
}
diff --git a/vendor/github.com/xenolf/lego/acme/client.go b/vendor/github.com/xenolf/lego/acme/client.go
index 9f837af36..e824f5080 100644
--- a/vendor/github.com/xenolf/lego/acme/client.go
+++ b/vendor/github.com/xenolf/lego/acme/client.go
@@ -11,6 +11,7 @@ import (
"io/ioutil"
"log"
"net"
+ "net/http"
"regexp"
"strconv"
"strings"
@@ -22,6 +23,9 @@ var (
Logger *log.Logger
)
+// maxBodySize is the maximum size of body that we will read.
+const maxBodySize = 1024 * 1024
+
// logf writes a log entry. It uses Logger if not
// nil, otherwise it uses the default log.Logger.
func logf(format string, args ...interface{}) {
@@ -49,12 +53,11 @@ type validateFunc func(j *jws, domain, uri string, chlng challenge) error
// Client is the user-friendy way to ACME
type Client struct {
- directory directory
- user User
- jws *jws
- keyType KeyType
- issuerCert []byte
- solvers map[Challenge]solver
+ directory directory
+ user User
+ jws *jws
+ keyType KeyType
+ solvers map[Challenge]solver
}
// NewClient creates a new ACME client on behalf of the user. The client will depend on
@@ -611,89 +614,108 @@ func (c *Client) requestCertificateForCsr(authz []authorizationResource, bundle
return CertificateResource{}, err
}
- cerRes := CertificateResource{
+ certRes := CertificateResource{
Domain: commonName.Domain,
CertURL: resp.Header.Get("Location"),
- PrivateKey: privateKeyPem}
+ PrivateKey: privateKeyPem,
+ }
- for {
- switch resp.StatusCode {
- case 201, 202:
- cert, err := ioutil.ReadAll(limitReader(resp.Body, 1024*1024))
- resp.Body.Close()
- if err != nil {
- return CertificateResource{}, err
- }
+ maxChecks := 1000
+ for i := 0; i < maxChecks; i++ {
+ done, err := c.checkCertResponse(resp, &certRes, bundle)
+ resp.Body.Close()
+ if err != nil {
+ return CertificateResource{}, err
+ }
+ if done {
+ break
+ }
+ if i == maxChecks-1 {
+ return CertificateResource{}, fmt.Errorf("polled for certificate %d times; giving up", i)
+ }
+ resp, err = httpGet(certRes.CertURL)
+ if err != nil {
+ return CertificateResource{}, err
+ }
+ }
+
+ return certRes, nil
+}
+
+// checkCertResponse checks resp to see if a certificate is contained in the
+// response, and if so, loads it into certRes and returns true. If the cert
+// is not yet ready, it returns false. This function honors the waiting period
+// required by the Retry-After header of the response, if specified. This
+// function may read from resp.Body but does NOT close it. The certRes input
+// should already have the Domain (common name) field populated. If bundle is
+// true, the certificate will be bundled with the issuer's cert.
+func (c *Client) checkCertResponse(resp *http.Response, certRes *CertificateResource, bundle bool) (bool, error) {
+ switch resp.StatusCode {
+ case 201, 202:
+ cert, err := ioutil.ReadAll(limitReader(resp.Body, maxBodySize))
+ if err != nil {
+ return false, err
+ }
+
+ // The server returns a body with a length of zero if the
+ // certificate was not ready at the time this request completed.
+ // Otherwise the body is the certificate.
+ if len(cert) > 0 {
+ certRes.CertStableURL = resp.Header.Get("Content-Location")
+ certRes.AccountRef = c.user.GetRegistration().URI
- // The server returns a body with a length of zero if the
- // certificate was not ready at the time this request completed.
- // Otherwise the body is the certificate.
- if len(cert) > 0 {
+ issuedCert := pemEncode(derCertificateBytes(cert))
- cerRes.CertStableURL = resp.Header.Get("Content-Location")
- cerRes.AccountRef = c.user.GetRegistration().URI
+ // The issuer certificate link is always supplied via an "up" link
+ // in the response headers of a new certificate.
+ links := parseLinks(resp.Header["Link"])
+ issuerCert, err := c.getIssuerCertificate(links["up"])
+ if err != nil {
+ // If we fail to acquire the issuer cert, return the issued certificate - do not fail.
+ logf("[WARNING][%s] acme: Could not bundle issuer certificate: %v", certRes.Domain, err)
+ } else {
+ issuerCert = pemEncode(derCertificateBytes(issuerCert))
- issuedCert := pemEncode(derCertificateBytes(cert))
// If bundle is true, we want to return a certificate bundle.
- // To do this, we need the issuer certificate.
+ // To do this, we append the issuer cert to the issued cert.
if bundle {
- // The issuer certificate link is always supplied via an "up" link
- // in the response headers of a new certificate.
- links := parseLinks(resp.Header["Link"])
- issuerCert, err := c.getIssuerCertificate(links["up"])
- if err != nil {
- // If we fail to acquire the issuer cert, return the issued certificate - do not fail.
- logf("[WARNING][%s] acme: Could not bundle issuer certificate: %v", commonName.Domain, err)
- } else {
- // Success - append the issuer cert to the issued cert.
- issuerCert = pemEncode(derCertificateBytes(issuerCert))
- issuedCert = append(issuedCert, issuerCert...)
- }
+ issuedCert = append(issuedCert, issuerCert...)
}
-
- cerRes.Certificate = issuedCert
- logf("[INFO][%s] Server responded with a certificate.", commonName.Domain)
- return cerRes, nil
- }
-
- // The certificate was granted but is not yet issued.
- // Check retry-after and loop.
- ra := resp.Header.Get("Retry-After")
- retryAfter, err := strconv.Atoi(ra)
- if err != nil {
- return CertificateResource{}, err
}
- logf("[INFO][%s] acme: Server responded with status 202; retrying after %ds", commonName.Domain, retryAfter)
- time.Sleep(time.Duration(retryAfter) * time.Second)
-
- break
- default:
- return CertificateResource{}, handleHTTPError(resp)
+ certRes.Certificate = issuedCert
+ certRes.IssuerCertificate = issuerCert
+ logf("[INFO][%s] Server responded with a certificate.", certRes.Domain)
+ return true, nil
}
- resp, err = httpGet(cerRes.CertURL)
+ // The certificate was granted but is not yet issued.
+ // Check retry-after and loop.
+ ra := resp.Header.Get("Retry-After")
+ retryAfter, err := strconv.Atoi(ra)
if err != nil {
- return CertificateResource{}, err
+ return false, err
}
+
+ logf("[INFO][%s] acme: Server responded with status 202; retrying after %ds", certRes.Domain, retryAfter)
+ time.Sleep(time.Duration(retryAfter) * time.Second)
+
+ return false, nil
+ default:
+ return false, handleHTTPError(resp)
}
}
-// getIssuerCertificate requests the issuer certificate and caches it for
-// subsequent requests.
+// getIssuerCertificate requests the issuer certificate
func (c *Client) getIssuerCertificate(url string) ([]byte, error) {
logf("[INFO] acme: Requesting issuer cert from %s", url)
- if c.issuerCert != nil {
- return c.issuerCert, nil
- }
-
resp, err := httpGet(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
- issuerBytes, err := ioutil.ReadAll(limitReader(resp.Body, 1024*1024))
+ issuerBytes, err := ioutil.ReadAll(limitReader(resp.Body, maxBodySize))
if err != nil {
return nil, err
}
@@ -703,7 +725,6 @@ func (c *Client) getIssuerCertificate(url string) ([]byte, error) {
return nil, err
}
- c.issuerCert = issuerBytes
return issuerBytes, err
}
diff --git a/vendor/github.com/xenolf/lego/acme/crypto.go b/vendor/github.com/xenolf/lego/acme/crypto.go
index c63b23b99..fa868a90d 100644
--- a/vendor/github.com/xenolf/lego/acme/crypto.go
+++ b/vendor/github.com/xenolf/lego/acme/crypto.go
@@ -226,7 +226,7 @@ func generateCsr(privateKey crypto.PrivateKey, domain string, san []string, must
}
if mustStaple {
- template.Extensions = append(template.Extensions, pkix.Extension{
+ template.ExtraExtensions = append(template.ExtraExtensions, pkix.Extension{
Id: tlsFeatureExtensionOID,
Value: ocspMustStapleFeature,
})
diff --git a/vendor/github.com/xenolf/lego/acme/error.go b/vendor/github.com/xenolf/lego/acme/error.go
index 2aa690b33..6d7013cf1 100644
--- a/vendor/github.com/xenolf/lego/acme/error.go
+++ b/vendor/github.com/xenolf/lego/acme/error.go
@@ -8,9 +8,7 @@ import (
"strings"
)
-const (
- tosAgreementError = "Must agree to subscriber agreement before any further actions"
-)
+const tosAgreementError = "Must agree to subscriber agreement before any further actions"
// RemoteError is the base type for all errors specific to the ACME protocol.
type RemoteError struct {
@@ -54,20 +52,17 @@ func (c challengeError) Error() string {
func handleHTTPError(resp *http.Response) error {
var errorDetail RemoteError
- contenType := resp.Header.Get("Content-Type")
- // try to decode the content as JSON
- if contenType == "application/json" || contenType == "application/problem+json" {
- decoder := json.NewDecoder(resp.Body)
- err := decoder.Decode(&errorDetail)
+ contentType := resp.Header.Get("Content-Type")
+ if contentType == "application/json" || contentType == "application/problem+json" {
+ err := json.NewDecoder(resp.Body).Decode(&errorDetail)
if err != nil {
return err
}
} else {
- detailBytes, err := ioutil.ReadAll(limitReader(resp.Body, 1024*1024))
+ detailBytes, err := ioutil.ReadAll(limitReader(resp.Body, maxBodySize))
if err != nil {
return err
}
-
errorDetail.Detail = string(detailBytes)
}
diff --git a/vendor/github.com/xenolf/lego/acme/jws.go b/vendor/github.com/xenolf/lego/acme/jws.go
index f70513e38..2a1fc244d 100644
--- a/vendor/github.com/xenolf/lego/acme/jws.go
+++ b/vendor/github.com/xenolf/lego/acme/jws.go
@@ -32,7 +32,9 @@ func keyAsJWK(key interface{}) *jose.JsonWebKey {
}
}
-// Posts a JWS signed message to the specified URL
+// Posts a JWS signed message to the specified URL.
+// It does NOT close the response body, so the caller must
+// do that if no error was returned.
func (j *jws) post(url string, content []byte) (*http.Response, error) {
signedContent, err := j.signContent(content)
if err != nil {
@@ -44,6 +46,8 @@ func (j *jws) post(url string, content []byte) (*http.Response, error) {
return nil, err
}
+ j.Lock()
+ defer j.Unlock()
j.getNonceFromResponse(resp)
return resp, err
@@ -77,8 +81,6 @@ func (j *jws) signContent(content []byte) (*jose.JsonWebSignature, error) {
}
func (j *jws) getNonceFromResponse(resp *http.Response) error {
- j.Lock()
- defer j.Unlock()
nonce := resp.Header.Get("Replay-Nonce")
if nonce == "" {
return fmt.Errorf("Server did not respond with a proper nonce header.")
@@ -98,6 +100,8 @@ func (j *jws) getNonce() error {
}
func (j *jws) Nonce() (string, error) {
+ j.Lock()
+ defer j.Unlock()
nonce := ""
if len(j.nonces) == 0 {
err := j.getNonce()
@@ -108,8 +112,6 @@ func (j *jws) Nonce() (string, error) {
if len(j.nonces) == 0 {
return "", fmt.Errorf("Can't get nonce")
}
- j.Lock()
- defer j.Unlock()
nonce, j.nonces = j.nonces[len(j.nonces)-1], j.nonces[:len(j.nonces)-1]
return nonce, nil
}
diff --git a/vendor/github.com/xenolf/lego/acme/messages.go b/vendor/github.com/xenolf/lego/acme/messages.go
index 0f6514c3f..36db3b217 100644
--- a/vendor/github.com/xenolf/lego/acme/messages.go
+++ b/vendor/github.com/xenolf/lego/acme/messages.go
@@ -94,16 +94,17 @@ type revokeCertMessage struct {
}
// CertificateResource represents a CA issued certificate.
-// PrivateKey and Certificate are both already PEM encoded
-// and can be directly written to disk. Certificate may
-// be a certificate bundle, depending on the options supplied
-// to create it.
+// PrivateKey, Certificate and IssuerCertificate are all
+// already PEM encoded and can be directly written to disk.
+// Certificate may be a certificate bundle, depending on the
+// options supplied to create it.
type CertificateResource struct {
- Domain string `json:"domain"`
- CertURL string `json:"certUrl"`
- CertStableURL string `json:"certStableUrl"`
- AccountRef string `json:"accountRef,omitempty"`
- PrivateKey []byte `json:"-"`
- Certificate []byte `json:"-"`
- CSR []byte `json:"-"`
+ Domain string `json:"domain"`
+ CertURL string `json:"certUrl"`
+ CertStableURL string `json:"certStableUrl"`
+ AccountRef string `json:"accountRef,omitempty"`
+ PrivateKey []byte `json:"-"`
+ Certificate []byte `json:"-"`
+ IssuerCertificate []byte `json:"-"`
+ CSR []byte `json:"-"`
}
diff --git a/vendor/github.com/xenolf/lego/cli_handlers.go b/vendor/github.com/xenolf/lego/cli_handlers.go
index 858d71000..dad19a144 100644
--- a/vendor/github.com/xenolf/lego/cli_handlers.go
+++ b/vendor/github.com/xenolf/lego/cli_handlers.go
@@ -136,12 +136,20 @@ func saveCertRes(certRes acme.CertificateResource, conf *Configuration) {
privOut := path.Join(conf.CertPath(), certRes.Domain+".key")
pemOut := path.Join(conf.CertPath(), certRes.Domain+".pem")
metaOut := path.Join(conf.CertPath(), certRes.Domain+".json")
+ issuerOut := path.Join(conf.CertPath(), certRes.Domain+".issuer.crt")
err := ioutil.WriteFile(certOut, certRes.Certificate, 0600)
if err != nil {
logger().Fatalf("Unable to save Certificate for domain %s\n\t%s", certRes.Domain, err.Error())
}
+ if certRes.IssuerCertificate != nil {
+ err = ioutil.WriteFile(issuerOut, certRes.IssuerCertificate, 0600)
+ if err != nil {
+ logger().Fatalf("Unable to save IssuerCertificate for domain %s\n\t%s", certRes.Domain, err.Error())
+ }
+ }
+
if certRes.PrivateKey != nil {
// if we were given a CSR, we don't know the private key
err = ioutil.WriteFile(privOut, certRes.PrivateKey, 0600)
diff --git a/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go b/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go
index 6742e4f56..9d281cd69 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go
@@ -72,7 +72,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error {
relative := toRelativeRecord(fqdn, acme.ToFqdn(zone))
rec := dns.RecordSet{
Name: &relative,
- Properties: &dns.RecordSetProperties{
+ RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(60),
TXTRecords: &[]dns.TxtRecord{dns.TxtRecord{Value: &[]string{value}}},
},
@@ -103,7 +103,7 @@ func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
relative := toRelativeRecord(fqdn, acme.ToFqdn(zone))
rsc := dns.NewRecordSetsClient(c.subscriptionId)
rsc.Authorizer, err = c.newServicePrincipalTokenFromCredentials(azure.PublicCloud.ResourceManagerEndpoint)
- _, err = rsc.Delete(c.resourceGroup, zone, relative, dns.TXT, "", "")
+ _, err = rsc.Delete(c.resourceGroup, zone, relative, dns.TXT, "")
if err != nil {
return err
}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go b/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go
index 53804e270..bc2067579 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go
@@ -49,7 +49,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error {
name := c.extractRecordName(fqdn, zoneDomain)
- err = c.client.CreateDnsRecord(zoneDomain, name, "TXT", `"`+value+`"`, 0, ttl)
+ err = c.client.CreateDNSRecord(zoneDomain, name, "TXT", `"`+value+`"`, 0, ttl)
if err != nil {
return fmt.Errorf("Vultr API call failed: %v", err)
}
@@ -67,7 +67,7 @@ func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
}
for _, rec := range records {
- err := c.client.DeleteDnsRecord(zoneDomain, rec.RecordID)
+ err := c.client.DeleteDNSRecord(zoneDomain, rec.RecordID)
if err != nil {
return err
}
@@ -76,12 +76,12 @@ func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
}
func (c *DNSProvider) getHostedZone(domain string) (string, error) {
- domains, err := c.client.GetDnsDomains()
+ domains, err := c.client.GetDNSDomains()
if err != nil {
return "", fmt.Errorf("Vultr API call failed: %v", err)
}
- var hostedDomain vultr.DnsDomain
+ var hostedDomain vultr.DNSDomain
for _, d := range domains {
if strings.HasSuffix(domain, d.Domain) {
if len(d.Domain) > len(hostedDomain.Domain) {
@@ -96,14 +96,14 @@ func (c *DNSProvider) getHostedZone(domain string) (string, error) {
return hostedDomain.Domain, nil
}
-func (c *DNSProvider) findTxtRecords(domain, fqdn string) (string, []vultr.DnsRecord, error) {
+func (c *DNSProvider) findTxtRecords(domain, fqdn string) (string, []vultr.DNSRecord, error) {
zoneDomain, err := c.getHostedZone(domain)
if err != nil {
return "", nil, err
}
- var records []vultr.DnsRecord
- result, err := c.client.GetDnsRecords(zoneDomain)
+ var records []vultr.DNSRecord
+ result, err := c.client.GetDNSRecords(zoneDomain)
if err != nil {
return "", records, fmt.Errorf("Vultr API call has failed: %v", err)
}