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:
-
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
-
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
Describe the bug:
When a certificate resource contains both
cert signand another non-CA usage (such asserver auth), the x509 certificate produced by cert-manager splits the usage betweenX509v3 Key UsageandX509v3 Extended Key Usagefields. Per RFC5280 4.2.1.12,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:
Deploy a certificate with
cert signandserver authusage:Get the signed cert and check the key usage via openssl:
If deployed to a basic webserver (i.e. nginx with bare minimum config), openssl reject this certificate due to
26 (unsupported certificate purpose)Anything else we need to know?:
Environment details:
/kind bug