Add /acme/issuer-cert endpoint and up links to it

In /acme/new-cert and /acme/cert/<serial>.
This commit is contained in:
Roland Shoemaker 2015-05-09 16:04:52 -07:00 committed by Jacob Hoffman-Andrews
parent 2359e02000
commit 1276d82146
5 changed files with 48 additions and 2 deletions

View File

@ -34,7 +34,7 @@ type Config struct {
DBDriver string
DBName string
SerialPrefix int
// A PEM-encoded copy of the issuer certificate.
// Path to a PEM-encoded copy of the issuer certificate.
IssuerCert string
// This field is only allowed if TestMode is true, indicating that we are
// signing with a local key. In production we will use an HSM and this

View File

@ -8,6 +8,7 @@ package main
import (
"fmt"
"net/http"
"os"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/streadway/amqp"
@ -81,6 +82,9 @@ func main() {
wfe.SA = &sac
wfe.Stats = stats
wfe.IssuerCert, err = cmd.LoadCert(c.CA.IssuerCert)
cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.CA.IssuerCert))
go cmd.ProfileCmd("WFE", stats)
go func() {

View File

@ -88,6 +88,10 @@ func main() {
wfe.RA = &ra
wfe.SA = sa
wfe.Stats = stats
wfe.IssuerCert, err = cmd.LoadCert(c.CA.IssuerCert)
cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.CA.IssuerCert))
ra.CA = ca
ra.SA = sa
ra.VA = &va

View File

@ -23,6 +23,8 @@ package cmd
import (
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"os"
@ -195,3 +197,23 @@ func ProfileCmd(profileName string, stats statsd.Statter) {
time.Sleep(time.Second)
}
}
func LoadCert(path string) (cert []byte, err error) {
if path == "" {
err = errors.New("Issuer certificate was not provided in config.")
return
}
pemBytes, err := ioutil.ReadFile(path)
if err != nil {
return
}
block, _ := pem.Decode(pemBytes)
if block == nil || block.Type != "CERTIFICATE" {
err = errors.New("Invalid certificate value returned")
return
}
cert = block.Bytes
return
}

View File

@ -44,6 +44,10 @@ type WebFrontEndImpl struct {
CertBase string
CertPath string
TermsPath string
IssuerPath string
// Issuer certificate (DER) for /acme/issuer-cert
IssuerCert []byte
}
func NewWebFrontEndImpl() WebFrontEndImpl {
@ -58,6 +62,7 @@ func NewWebFrontEndImpl() WebFrontEndImpl {
NewCertPath: "/acme/new-cert",
CertPath: "/acme/cert/",
TermsPath: "/terms",
IssuerPath: "/acme/issuer-cert",
}
}
@ -77,6 +82,7 @@ func (wfe *WebFrontEndImpl) HandlePaths() {
http.HandleFunc(wfe.AuthzPath, wfe.Authorization)
http.HandleFunc(wfe.CertPath, wfe.Certificate)
http.HandleFunc(wfe.TermsPath, wfe.Terms)
http.HandleFunc(wfe.IssuerPath, wfe.Issuer)
}
// Method implementations
@ -312,6 +318,7 @@ func (wfe *WebFrontEndImpl) NewCertificate(response http.ResponseWriter, request
// TODO The spec says a client should send an Accept: application/pkix-cert
// header; either explicitly insist or tolerate
response.Header().Add("Location", certURL)
response.Header().Add("Link", link(wfe.IssuerPath, "up"))
response.Header().Set("Content-Type", "application/pkix-cert")
response.WriteHeader(http.StatusCreated)
if _, err = response.Write(cert.DER); err != nil {
@ -530,8 +537,8 @@ func (wfe *WebFrontEndImpl) Certificate(response http.ResponseWriter, request *h
}
// TODO: Content negotiation
// TODO: Link header
response.Header().Set("Content-Type", "application/pkix-cert")
response.Header().Add("Link", link(wfe.IssuerPath, "up"))
response.WriteHeader(http.StatusOK)
if _, err = response.Write(cert); err != nil {
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
@ -548,3 +555,12 @@ func (wfe *WebFrontEndImpl) Certificate(response http.ResponseWriter, request *h
func (wfe *WebFrontEndImpl) Terms(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "You agree to do the right thing")
}
func (wfe *WebFrontEndImpl) Issuer(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Location", wfe.IssuerPath)
w.Header().Set("Content-Type", "application/pkix-cert")
w.WriteHeader(http.StatusOK)
if _, err := w.Write(wfe.IssuerCert); err != nil {
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
}
}