Use application/pem-certificate-chain for PEMs (#13927)

* Use application/pem-certificate-chain for PEMs

As mentioned in #10948, it appears we're incorrectly using the
`application/pkix-cert` media type for PEM blobs, when
`application/x-pem-file` is more appropriate. Per RFC 5280 Section
4.2.1.13, `application/pkix-crl` is only appropriate when the CRL is in
DER form. Likewise, Section 4.2.2.1 states that `application/pkix-cert`
is only applicable when a single DER certificate is used.

Per recommendation in RFC 8555 ("ACME"), Section 7.4.2 and 9.1, we use
the newer `application/pem-certificate-chain` media type for
certificates. However, this is not applicable for CRLs, so we use fall
back to `application/x-pem-file` for these. Notably, no official IETF
source is present for the latter. On the OpenSSL PKI tutorial
(https://pki-tutorial.readthedocs.io/en/latest/mime.html), this type is
cited as coming from S/MIME's predecessor, PEM, but neither of the main
PEM RFCs (RFC 934, 1421, 1422, 1423, or 1424) mention this type.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

* Add changelog entry

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
Alexander Scheel 2022-02-08 08:12:33 -05:00 committed by GitHub
parent 1a4dc03bf7
commit a0feefb2fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 8 additions and 2 deletions

View File

@ -1768,7 +1768,7 @@ func TestBackend_PathFetchValidRaw(t *testing.T) {
if bytes.Compare(resp.Data[logical.HTTPRawBody].([]byte), pemCert) != 0 { if bytes.Compare(resp.Data[logical.HTTPRawBody].([]byte), pemCert) != 0 {
t.Fatalf("failed to get pem cert") t.Fatalf("failed to get pem cert")
} }
if resp.Data[logical.HTTPContentType] != "application/pkix-cert" { if resp.Data[logical.HTTPContentType] != "application/pem-certificate-chain" {
t.Fatalf("failed to get raw cert content-type") t.Fatalf("failed to get raw cert content-type")
} }
} }

View File

@ -320,7 +320,7 @@ func runSteps(t *testing.T, rootB, intB *backend, client *api.Client, rootName,
if diff := deep.Equal(resp.Data["http_raw_body"].([]byte), []byte(caCert)); diff != nil { if diff := deep.Equal(resp.Data["http_raw_body"].([]byte), []byte(caCert)); diff != nil {
t.Fatal(diff) t.Fatal(diff)
} }
if resp.Data["http_content_type"].(string) != "application/pkix-cert" { if resp.Data["http_content_type"].(string) != "application/pem-certificate-chain" {
t.Fatal("wrong content type") t.Fatal("wrong content type")
} }
} }

View File

@ -157,6 +157,7 @@ func (b *backend) pathFetchRead(ctx context.Context, req *logical.Request, data
contentType = "application/pkix-cert" contentType = "application/pkix-cert"
if req.Path == "ca/pem" { if req.Path == "ca/pem" {
pemType = "CERTIFICATE" pemType = "CERTIFICATE"
contentType = "application/pem-certificate-chain"
} }
case req.Path == "ca_chain" || req.Path == "cert/ca_chain": case req.Path == "ca_chain" || req.Path == "cert/ca_chain":
serial = "ca_chain" serial = "ca_chain"
@ -168,6 +169,7 @@ func (b *backend) pathFetchRead(ctx context.Context, req *logical.Request, data
contentType = "application/pkix-crl" contentType = "application/pkix-crl"
if req.Path == "crl/pem" { if req.Path == "crl/pem" {
pemType = "X509 CRL" pemType = "X509 CRL"
contentType = "application/x-pem-file"
} }
case req.Path == "cert/crl": case req.Path == "cert/crl":
serial = "crl" serial = "crl"
@ -177,6 +179,7 @@ func (b *backend) pathFetchRead(ctx context.Context, req *logical.Request, data
contentType = "application/pkix-cert" contentType = "application/pkix-cert"
if strings.HasSuffix(req.Path, "/pem") { if strings.HasSuffix(req.Path, "/pem") {
pemType = "CERTIFICATE" pemType = "CERTIFICATE"
contentType = "application/pem-certificate-chain"
} }
default: default:
serial = data.Get("serial").(string) serial = data.Get("serial").(string)

3
changelog/13927.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
secrets/pki: Use application/pem-certificate-chain for PEM certificates, application/x-pem-file for PEM CRLs
```