8000 cert-manager produces invalid (per RFC5280) certificates when `cert sign` usage is set along with another usage · Issue #7660 · cert-manager/cert-manager · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
cert-manager produces invalid (per RFC5280) certificates when cert sign usage is set along with another usage #7660
Open
@solidDoWant

Description

@solidDoWant

Describe the bug:

When a certificate resource contains both cert sign and another non-CA usage (such as server auth), the x509 certificate produced by cert-manager splits the usage between X509v3 Key Usage and X509v3 Extended Key Usage fields. Per RFC5280 4.2.1.12,

If a certificate contains both a key usage extension and an extended
key usage extension, then both extensions MUST be processed
independently and the certificate MUST only be used for a purpose
consistent with both extensions. If there is no purpose consistent
with both extensions, then the certificate MUST NOT be used for any
purpose.

Because the usages are split between the key usage and extended key usage fields, the produced certificates are not valid for any of the usages.

Expected behaviour:
There key usage and extended key usage fields should have the same values set, or one of them should have no values set at all.

Steps to reproduce the bug:

  1. Deploy a certificate with cert sign and server auth usage:

    ---
    # yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: example-cert
    spec:
      isCA: true # Self-signed cert must be a CA
      commonName: Self signed cert
      dnsNames: &domain_names
        - some-domain.com
      usages:
        - server auth
        # Self-signed cert must be able to sign itself
        - cert sign
        - crl sign
      # Allow only signing for the license domain name
      nameConstraints:
        critical: true
        permitted:
          dnsDomains: *domain_names
      issuerRef:
        name: self-signed-issuer
        kind: ClusterIssuer
        group: cert-manager.io
      secretName: example-cert
  2. Get the signed cert and check the key usage via openssl:

    $ kubectl get secrets -n monitoring example-cert -o json | jq -r '.data["tls.crt"]' | base64 -d | openssl x509 -noout -text | grep -A4 'X509v3 extensions'
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication

If deployed to a basic webserver (i.e. nginx with bare minimum config), openssl reject this certificate due to 26 (unsupported certificate purpose)

$ echo | openssl s_client -connect some-domain.com:443
... # Unrelated lines omitted
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1567 bytes and written 443 bytes
Verification error: unsupported certificate purpose
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 26 (unsupported certificate purpose)
---
DONE

Anything else we need to know?:

Environment details:

  • Kubernetes version: N/A
  • Cloud-provider/provisioner: N/A
  • cert-manager version: 1.17.1
  • Install method: e.g. helm/static manifests Helm

/kind bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0