Skip to content

Commit

Permalink
Change example.com to amppackageexample.com. (#181)
Browse files Browse the repository at this point in the history
This way the suggested minimal config will work in development mode, as
amppackageexample serves AMP. Also change the default OCSP cache file to
something that doesn't require a mkdir.

Also:
* Update testdata readme and fix other example refs.
* Update cert so subject is amppackageexample.com.
* Update the tests to require fewer places to change when the cert changes.
* Comment out default PathExcludeRE.
* Clarify development cert instructions.
* Add DigiCert link.
  • Loading branch information
twifkak committed Nov 5, 2018
1 parent 557cdd1 commit ceb18b8
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 59 deletions.
15 changes: 7 additions & 8 deletions README.md
Expand Up @@ -26,8 +26,8 @@ and signs AMP documents as requested by the AMP Cache.

### How to use

In all the instructions below, replace `example.com` with a domain you own and
can obtain certificates for.
In all the instructions below, replace `amppackageexample.com` with a domain you
own and can obtain certificates for.

#### Development server

Expand All @@ -43,15 +43,14 @@ can obtain certificates for.
PackagerBase = 'https://localhost:8080/'
CertFile = 'path/to/fullchain.pem'
KeyFile = 'path/to/privkey.pem'
OCSPCache = '/tmp/amppkg/ocsp'
OCSPCache = '/tmp/amppkg-ocsp'
[[URLSet]]
[URLSet.Sign]
Domain = "example.com"
Domain = "amppackageexample.com"
```
More details can be found in [amppkg.example.toml](amppkg.example.toml).
4. `mkdir /tmp/amppkg`
5. `amppkg -development`
4. `amppkg -development`

If `amppkg.toml` is not in the current working directory, pass
`-config=/path/to/amppkg.toml`.
Expand All @@ -66,7 +65,7 @@ can obtain certificates for.
--user-data-dir=/tmp/udd
--ignore-certificate-errors-spki-list=$(openssl x509 -pubkey -noout -in path/to/fullchain.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64)
--enable-features=SignedHTTPExchange
'data:text/html,<a href="https://localhost:8080/priv/doc/https://example.com/">click me'
'data:text/html,<a href="https://localhost:8080/priv/doc/https://amppackageexample.com/">click me'
```
2. Open DevTools. Check 'Preserve log'.
3. Click the `click me` link.
Expand All @@ -81,7 +80,7 @@ prefetch](https://wicg.github.io/webpackage/draft-yasskin-webpackage-use-cases.h
works with SXGs.

1. `go get -u github.com/ampproject/amppackager/cmd/amppkg_dl_sxg`.
2. `amppkg_dl_sxg https://localhost:8080/priv/doc/https://example.com/`
2. `amppkg_dl_sxg https://localhost:8080/priv/doc/https://amppackageexample.com/`
3. Stop `amppkg` with Ctrl-C.
4. `go get -u github.com/ampproject/amppackager/cmd/amppkg_test_cache`.
5. `amppkg_test_cache`
Expand Down
27 changes: 16 additions & 11 deletions amppkg.example.toml
Expand Up @@ -20,8 +20,10 @@
# where the first certificate is for your domain, and the second is your CA's
# cert.
#
# For development, it may be any certificate. For production, it must meet
# the following requirements set by the Signed Exchanges specification:
# For development, it may be any certificate that has an OCSP URL in its
# Authority Information Access section (e.g. a TLS cert from Let's Encrypt).
# For production, it must meet the following requirements set by the Signed
# Exchanges specification:
#
# The leaf certificate must use an EC P-256 key. (See https://goo.gl/pwK9EJ
# item 3.1.5.) It must have at least one SCT, either as an X.509 extension or
Expand All @@ -32,6 +34,9 @@
# certificate should be minted from a different private key than your TLS
# certificate. See https://goo.gl/U4vasm for details.
#
# As of November 2018, DigiCert is the only provider of such certs:
# https://www.digicert.com/account/ietf/http-signed-exchange.php
#
# To verify it has the right key type:
# openssl x509 -in cert.pem -text | grep 'ASN1 OID: prime256v1'
# To verify it has the CanSignHttpExchanges extension:
Expand All @@ -49,7 +54,7 @@ KeyFile = './pems/privkey.pem'
# The path to a file where the OCSP response will be cached. The parent
# directory should exist, but the file need not. If this is a network-mounted
# file, it should support shared/exclusive locking.
OCSPCache = '/tmp/amppkg/ocsp'
OCSPCache = '/tmp/amppkg-ocsp'

# This is a simple level of validation, to guard against accidental
# misconfiguration of the reverse proxy that sits in front of the packager.
Expand All @@ -65,9 +70,9 @@ OCSPCache = '/tmp/amppkg/ocsp'
# URLSet.Fetch below.
#
# To ask the packager to fetch/sign a specific URL, request it like this:
# /priv/doc/https://example.com/
# /priv/doc/https://amppackageexample.com/
# or this:
# /priv/doc?sign=https%3A%2F%2Fexample.com%2F
# /priv/doc?sign=https%3A%2F%2Famppackageexample.com%2F
#
# Note the need for the latter to be URL-escaped. Both options are provided,
# depending on what's easier for your server software.
Expand All @@ -77,7 +82,7 @@ OCSPCache = '/tmp/amppkg/ocsp'

# The domain to limit signed URLs to. An exact string match. The
# certificate must cover this domain.
Domain = "example.com"
Domain = "amppackageexample.com"

# A full-match regexp on the path (not including the ?query).
# Defaults to ".*". The below example allows paths starting with /world/.
Expand All @@ -93,7 +98,7 @@ OCSPCache = '/tmp/amppkg/ocsp'
# chance of an XSS vulnerability in your templating library, the impact
# of such event is higher here: even after you've fixed the bug, caches
# may serve your signed packages for up to 7 days.
PathExcludeRE = []
# PathExcludeRE = []

# A full-match regexp on the query portion of the URL, excluding the initial
# "?". Defaults to ".*". The below example disallows non-empty query strings
Expand All @@ -114,11 +119,11 @@ OCSPCache = '/tmp/amppkg/ocsp'
# allows the frontend to specify an additional `fetch` query parameter.
# Instead of looking like:
#
# /priv/doc/https://example.com/page.html
# /priv/doc/https://amppackageexample.com/page.html
#
# The URL will look like:
#
# /priv/doc?fetch=https%3A%2F%2Finternal.example.com%2Fpage.html&sign=https%3A%2F%2Fexample.com%2Fpage.html
# /priv/doc?fetch=https%3A%2F%2Finternal.amppackageexample.com%2Fpage.html&sign=https%3A%2F%2Famppackageexample.com%2Fpage.html
#
# Note that this reduces the defense-in-depth against the "signing oracle"
# attack. If an attacker can request custom URLs from the packager (or
Expand All @@ -141,9 +146,9 @@ OCSPCache = '/tmp/amppkg/ocsp'
# # Domain may be specified. Exercise caution; test the regexp thoroughly.
# # For instance, a DomainRE of "www.example.com" would allow fetches from
# # www-example.com.
# DomainRE = "www\\.corp\\d+\\.example\\.com"
# DomainRE = "www\\.corp\\d+\\.amppackageexample\\.com"
#
# # All other fields behave the same.
# Domain = "www.corp.example.com"
# Domain = "www.corp.amppackageexample.com"
# PathRE = "/world/.*"
# QueryRE = ""
8 changes: 3 additions & 5 deletions packager/certcache/certcache_test.go
Expand Up @@ -36,8 +36,6 @@ import (
"golang.org/x/crypto/ocsp"
)

const certName = "k9GCZZIDzAt2X0b2czRv0c2omW5vgYNh6ZaIz_UNTRQ"

var caCert = func() *x509.Certificate {
certPem, _ := ioutil.ReadFile("../../testdata/b1/ca.cert")
certs, _ := signedexchange.ParseCertificates(certPem)
Expand Down Expand Up @@ -170,7 +168,7 @@ func (this *CertCacheSuite) DecodeCBOR(r io.Reader) map[string][]byte {
}

func (this *CertCacheSuite) TestServesCertificate() {
resp := pkgt.GetP(this.T(), this.handler, "/amppkg/cert/"+certName, httprouter.Params{httprouter.Param{"certName", certName}})
resp := pkgt.GetP(this.T(), this.handler, "/amppkg/cert/"+pkgt.CertName, httprouter.Params{httprouter.Param{"certName", pkgt.CertName}})
this.Assert().Equal(http.StatusOK, resp.StatusCode, "incorrect status: %#v", resp)
this.Assert().Equal("nosniff", resp.Header.Get("X-Content-Type-Options"))
cbor := this.DecodeCBOR(resp.Body)
Expand All @@ -189,7 +187,7 @@ func (this *CertCacheSuite) TestServes404OnMissingCertificate() {

func (this *CertCacheSuite) TestOCSP() {
// Verify it gets included in the cert-chain+cbor payload.
resp := pkgt.GetP(this.T(), this.handler, "/amppkg/cert/"+certName, httprouter.Params{httprouter.Param{"certName", certName}})
resp := pkgt.GetP(this.T(), this.handler, "/amppkg/cert/"+pkgt.CertName, httprouter.Params{httprouter.Param{"certName", pkgt.CertName}})
this.Assert().Equal(http.StatusOK, resp.StatusCode, "incorrect status: %#v", resp)
// 302400 is 3.5 days. max-age is slightly less because of the time between fake OCSP generation and cert-chain response.
// TODO(twifkak): Make this less flaky, by injecting a fake clock.
Expand Down Expand Up @@ -224,7 +222,7 @@ func (this *CertCacheSuite) TestOCSPExpiry() {
}))

// Verify HTTP response expires immediately:
resp := pkgt.GetP(this.T(), this.handler, "/amppkg/cert/"+certName, httprouter.Params{httprouter.Param{"certName", certName}})
resp := pkgt.GetP(this.T(), this.handler, "/amppkg/cert/"+pkgt.CertName, httprouter.Params{httprouter.Param{"certName", pkgt.CertName}})
this.Assert().Equal("public, max-age=0", resp.Header.Get("Cache-Control"))

// On update, verify network is called:
Expand Down
4 changes: 2 additions & 2 deletions packager/signer/signer_test.go
Expand Up @@ -169,8 +169,8 @@ func (this *SignerSuite) TestSimple() {
this.Assert().Equal("nosniff", exchange.ResponseHeaders.Get("X-Content-Type-Options"))
this.Assert().Contains(exchange.SignatureHeaderValue, "validity-url=\""+this.httpSignURL()+"/amppkg/validity\"")
this.Assert().Contains(exchange.SignatureHeaderValue, "integrity=\"digest/mi-sha256-03\"")
this.Assert().Contains(exchange.SignatureHeaderValue, "cert-url=\""+this.httpSignURL()+"/amppkg/cert/k9GCZZIDzAt2X0b2czRv0c2omW5vgYNh6ZaIz_UNTRQ\"")
this.Assert().Contains(exchange.SignatureHeaderValue, "cert-sha256=*k9GCZZIDzAt2X0b2czRv0c2omW5vgYNh6ZaIz/UNTRQ=*")
this.Assert().Contains(exchange.SignatureHeaderValue, "cert-url=\""+this.httpSignURL()+"/amppkg/cert/"+pkgt.CertName+"\"")
this.Assert().Contains(exchange.SignatureHeaderValue, "cert-sha256=*"+pkgt.CertName+"=*")
// TODO(twifkak): Control date, and test for expires and sig.
// The response header values are untested here, as that is covered by signedexchange tests.

Expand Down
3 changes: 3 additions & 0 deletions packager/testing/testing.go
Expand Up @@ -43,6 +43,9 @@ var Key = func() crypto.PrivateKey {
return key
}()

// The URL path component corresponding to the cert's sha-256.
var CertName = util.CertName(Certs[0])

// A variant of http.Handler that's required by httprouter.
type AlmostHandler interface {
ServeHTTP(http.ResponseWriter, *http.Request, httprouter.Params)
Expand Down
2 changes: 1 addition & 1 deletion packager/util/util_test.go
Expand Up @@ -12,7 +12,7 @@ import (
)

func TestCertName(t *testing.T) {
assert.Equal(t, "k9GCZZIDzAt2X0b2czRv0c2omW5vgYNh6ZaIz_UNTRQ", util.CertName(pkgt.Certs[0]))
assert.Equal(t, "PJ1IwfP1igOlJd2oTUVs2mj4dWIZcOWHMk5jfJYS2Qc", util.CertName(pkgt.Certs[0]))
}

// ParsePrivateKey() is tested indirectly via the definition of pkgt.Key.
Expand Down
4 changes: 2 additions & 2 deletions testdata/b1/README.md
Expand Up @@ -11,7 +11,7 @@ $ openssl req -x509 -new -nodes -key ca.privkey -sha256 -days 1825 -out ca.cert
$ openssl ecparam -out server.privkey -name prime256v1 -genkey
$ openssl req -new -sha256 -key server.privkey -out server.csr -subj /CN=example.com
$ openssl x509 -req -in server.csr -CA ca.cert -CAkey ca.privkey -CAcreateserial -out server.cert -days 3650 \
-extfile <(echo -e "1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL\nsubjectAltName=DNS:example.org")
-extfile <(echo -e "1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL")
$ cat server.cert ca.cert >fullchain.cert
```

Expand All @@ -33,7 +33,7 @@ file.


```
$ openssl ocsp -index ./index.txt -rsigner ca.ocsp.cert -rkey ca.privkey -CA ca.cert -ndays 7 -reqin ocspreq.der -respout <path_to_response>.der
$ openssl ocsp -index ./index.txt -rsigner ca.ocsp.cert -rkey ca.privkey -CA ca.cert -ndays 7 -reqin ocspreq.der -respout /tmp/amppkg-ocsp
```


Expand Down
2 changes: 1 addition & 1 deletion testdata/b1/ca.srl
@@ -1 +1 @@
FA2006BB9AAF740C
FA2006BB9AAF740D
23 changes: 11 additions & 12 deletions testdata/b1/fullchain.cert
@@ -1,17 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICQzCCASugAwIBAgIJAPogBruar3QMMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
MIICNTCCAR2gAwIBAgIJAPogBruar3QNMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MDgyOTIzMjMxMloXDTI4MDgyNjIzMjMx
MlowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB
BwNCAASmrg3SzVh7uYFqc/wRleLNZmLcOxvq9CVUi/sIjX3JW6jCaorZrkAPIo/K
hnoptV9j9XlhIqEFVAlPU9Gnl3SOoywwKjAQBgorBgEEAdZ5AgEWBAIFADAWBgNV
HREEDzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAYqGtLmIrwbwK
kjX6oo3RVtaxS4vSAEbAJWSosxDuTtSJq8jd2XIs7N6OAiZmAXzjeNANJI6aMEEO
EKjaKEVzFfNSVlVTVmwu+QnM/VmYmucJDFoNgmKES7LN5GVMk6lTgzvKZ8Zm+98v
reYDbi+1gC9iV66w2arh5Qh9MPh55wroR5cL0NcphrA7KyDpw56nOhZ3/cFGlrP+
7MjmHyeISZXR2UPRuS7n/OlzN032sdJce/t0qGMPEoF8Rp+N8djm9KCpyo7ma/fp
px9keg2xng9TZe0QBiyA1MBOpvI9RtfineEdkHa0gUGo/SwOa5Vj5AEYi68XuQgF
dBJOms3chA==
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MTEwMjIzMzAyMloXDTI4MTAzMDIzMzAy
MlowIDEeMBwGA1UEAwwVYW1wcGFja2FnZWV4YW1wbGUuY29tMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAEpq4N0s1Ye7mBanP8EZXizWZi3Dsb6vQlVIv7CI19yVuo
wmqK2a5ADyKPyoZ6KbVfY/V5YSKhBVQJT1PRp5d0jqMUMBIwEAYKKwYBBAHWeQIB
FgQCBQAwDQYJKoZIhvcNAQELBQADggEBAKgLPVYS8dlg4NnDmeePMNelX0aoONV2
pijVBjVkFf8lN00TVgthNDPZlk9Vxq7dxnU6ATbsb62JbZRoSPRxW7dk91YOb3ht
12tzTlFbdX485k+KsREdCFbu9cpF8I34VGKcZUsi7u7uMZFfi8S+XcMyC1EQpueQ
+xlOTUQAOXspg+qQ1gwlOSznV0UZ+4B2/XkghOkweZfwla/62WzgtmD8a9uuoVd0
RARwfB/D7ye9mvqbMyiOc3uO5zfCUrtiW5oin4SEgTGYvuEcHRaMV6cjx1r7MBLt
KpIgRXTPWLAVo9OLxmDKUZH23DYVAx8BIBDpQzoqchmgW1X9eX1k1Y8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDaDCCAlCgAwIBAgIJAKRDrJBUupZAMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
Expand Down
Empty file added testdata/b1/index.txt
Empty file.
Empty file added testdata/b1/index.txt.attr
Empty file.
23 changes: 11 additions & 12 deletions testdata/b1/server.cert
@@ -1,15 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICQzCCASugAwIBAgIJAPogBruar3QMMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
MIICNTCCAR2gAwIBAgIJAPogBruar3QNMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MDgyOTIzMjMxMloXDTI4MDgyNjIzMjMx
MlowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB
BwNCAASmrg3SzVh7uYFqc/wRleLNZmLcOxvq9CVUi/sIjX3JW6jCaorZrkAPIo/K
hnoptV9j9XlhIqEFVAlPU9Gnl3SOoywwKjAQBgorBgEEAdZ5AgEWBAIFADAWBgNV
HREEDzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAYqGtLmIrwbwK
kjX6oo3RVtaxS4vSAEbAJWSosxDuTtSJq8jd2XIs7N6OAiZmAXzjeNANJI6aMEEO
EKjaKEVzFfNSVlVTVmwu+QnM/VmYmucJDFoNgmKES7LN5GVMk6lTgzvKZ8Zm+98v
reYDbi+1gC9iV66w2arh5Qh9MPh55wroR5cL0NcphrA7KyDpw56nOhZ3/cFGlrP+
7MjmHyeISZXR2UPRuS7n/OlzN032sdJce/t0qGMPEoF8Rp+N8djm9KCpyo7ma/fp
px9keg2xng9TZe0QBiyA1MBOpvI9RtfineEdkHa0gUGo/SwOa5Vj5AEYi68XuQgF
dBJOms3chA==
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MTEwMjIzMzAyMloXDTI4MTAzMDIzMzAy
MlowIDEeMBwGA1UEAwwVYW1wcGFja2FnZWV4YW1wbGUuY29tMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAEpq4N0s1Ye7mBanP8EZXizWZi3Dsb6vQlVIv7CI19yVuo
wmqK2a5ADyKPyoZ6KbVfY/V5YSKhBVQJT1PRp5d0jqMUMBIwEAYKKwYBBAHWeQIB
FgQCBQAwDQYJKoZIhvcNAQELBQADggEBAKgLPVYS8dlg4NnDmeePMNelX0aoONV2
pijVBjVkFf8lN00TVgthNDPZlk9Vxq7dxnU6ATbsb62JbZRoSPRxW7dk91YOb3ht
12tzTlFbdX485k+KsREdCFbu9cpF8I34VGKcZUsi7u7uMZFfi8S+XcMyC1EQpueQ
+xlOTUQAOXspg+qQ1gwlOSznV0UZ+4B2/XkghOkweZfwla/62WzgtmD8a9uuoVd0
RARwfB/D7ye9mvqbMyiOc3uO5zfCUrtiW5oin4SEgTGYvuEcHRaMV6cjx1r7MBLt
KpIgRXTPWLAVo9OLxmDKUZH23DYVAx8BIBDpQzoqchmgW1X9eX1k1Y8=
-----END CERTIFICATE-----
10 changes: 5 additions & 5 deletions testdata/b1/server.csr
@@ -1,7 +1,7 @@
-----BEGIN CERTIFICATE REQUEST-----
MIHPMHgCAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAASmrg3SzVh7uYFqc/wRleLNZmLcOxvq9CVUi/sIjX3JW6jCaorZ
rkAPIo/KhnoptV9j9XlhIqEFVAlPU9Gnl3SOoAAwCgYIKoZIzj0EAwIDRwAwRAIg
ITB+IL7G5YhjJ+hLNXJZip+7E4aWqDw4UfpJoqJ9oWgCIBP8k4wA5Y51APjHRoLk
oaoHm7ekxJYwXR69NTMr8RLI
MIHbMIGCAgEAMCAxHjAcBgNVBAMMFWFtcHBhY2thZ2VleGFtcGxlLmNvbTBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABKauDdLNWHu5gWpz/BGV4s1mYtw7G+r0JVSL
+wiNfclbqMJqitmuQA8ij8qGeim1X2P1eWEioQVUCU9T0aeXdI6gADAKBggqhkjO
PQQDAgNIADBFAiEAhwIm8LIS+pB8/2GBqRX81R0n7Hyl0aJswhEP/bvK0x8CIB8U
Idu3yFpZLOo1YMUWGTNyatzHYh4BwuTDquL0dcPA
-----END CERTIFICATE REQUEST-----

0 comments on commit ceb18b8

Please sign in to comment.