Skip to content

Commit

Permalink
CA: allow configuring EE cert OCSP Responder URL (#242)
Browse files Browse the repository at this point in the history
Pebble is not designed to be an OCSP responder of the certificates it issues,
since it is not its purpose. However, it is easy to setup a proper OCSP
responder alongside it, thanks to the ability to get the intermediate CA
certificate with `/intermediate` and `/intermediate-key` endpoints.

To make this interaction complete, and allow a client (like Certbot) to get
a proper OCSP response status during tests, the certificates generated by Pebble
need to contain an arbitrary OCSP Responder URL.

This PR allows that, by setting a `ocspResponderURL` configuration field. If
set, then Pebble will add to the certificate template the given OCSP Responder
URL, to be included in the certificates when they are generated. If not set
(empty string), the template does not contain the OCSP field.

Typical example is:
`"ocspResponderURL": "http://127.0.0.1:4002 pebble"`

Instruction in README are updated with this new config variable.
  • Loading branch information
adferrand authored and Daniel McCarney committed Jun 20, 2019
1 parent 3901cd0 commit afbe2db
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,19 @@ purposes, since Pebble and its generated keys are not audited or held to the
same standards as the Let's Encrypt production CA and their keys. Moreover
these keys are exposed by Pebble and will be lost as soon as the process
terminates: so they are not safe to use for anything other than testing.**

### OCSP Responder URL

Pebble does not support the OCSP protocol as a responder and so does not set
the OCSP Responder URL in the issued certificates. However, if you setup a
proper OCSP Responder run side by side with Pebble, you may want to set this URL.
This is possible by setting the field `ocspResponderURL` of the `pebble-config.json`
consummed by Pebble to a non empty string: in this case, this string will be use
in the appropriate field of all issued certificates.

For instance, to have Pebble issue certificates that instruct a client to check the URL `http://127.0.0.1:4002`
to retrieve the OCSP status of a certificate, run Pebble with a `pebble-config.json` that includes:

```
"ocspResponderURL": "http://127.0.0.1:4002",
```
18 changes: 15 additions & 3 deletions ca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ const (
)

type CAImpl struct {
log *log.Logger
db *db.MemoryStore
log *log.Logger
db *db.MemoryStore
ocspResponderURL string

root *issuer
intermediate *issuer
Expand Down Expand Up @@ -188,6 +189,11 @@ func (ca *CAImpl) newCertificate(domains []string, ips []net.IP, key crypto.Publ
BasicConstraintsValid: true,
IsCA: false,
}

if ca.ocspResponderURL != "" {
template.OCSPServer = []string{ca.ocspResponderURL}
}

der, err := x509.CreateCertificate(rand.Reader, template, issuer.cert.Cert, key, issuer.key)
if err != nil {
return nil, err
Expand All @@ -212,11 +218,17 @@ func (ca *CAImpl) newCertificate(domains []string, ips []net.IP, key crypto.Publ
return newCert, nil
}

func New(log *log.Logger, db *db.MemoryStore) *CAImpl {
func New(log *log.Logger, db *db.MemoryStore, ocspResponderURL string) *CAImpl {
ca := &CAImpl{
log: log,
db: db,
}

if ocspResponderURL != "" {
ca.ocspResponderURL = ocspResponderURL
ca.log.Printf("Setting OCSP responder URL for issued certificates to %q", ca.ocspResponderURL)
}

err := ca.newRootIssuer()
if err != nil {
panic(fmt.Sprintf("Error creating new root issuer: %s", err.Error()))
Expand Down
13 changes: 7 additions & 6 deletions cmd/pebble/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ import (

type config struct {
Pebble struct {
ListenAddress string
HTTPPort int
TLSPort int
Certificate string
PrivateKey string
ListenAddress string
HTTPPort int
TLSPort int
Certificate string
PrivateKey string
OCSPResponderURL string
}
}

Expand Down Expand Up @@ -57,7 +58,7 @@ func main() {
}

db := db.NewMemoryStore()
ca := ca.New(logger, db)
ca := ca.New(logger, db, c.Pebble.OCSPResponderURL)
va := va.New(logger, c.Pebble.HTTPPort, c.Pebble.TLSPort, *strictMode)

wfeImpl := wfe.New(logger, db, va, ca, *strictMode)
Expand Down
3 changes: 2 additions & 1 deletion test/config/pebble-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"certificate": "test/certs/localhost/cert.pem",
"privateKey": "test/certs/localhost/key.pem",
"httpPort": 5002,
"tlsPort": 5001
"tlsPort": 5001,
"ocspResponderURL": ""
}
}

0 comments on commit afbe2db

Please sign in to comment.