Closed phamrak closed 2 years ago
@phamrak This is a misunderstanding of how RFC 5280 and PKI work.
CAs are free to use what information from the CSR they want. They aren't bound to taking everything from the CSR or wholesale rejecting it; they're free to modify it and manipulate it into a Certificate in any form (and from any subset of values set on the CSR) that they want. This is well-known behavior of other PKI systems like Dogtag and EJBCA (which have complex issuance policy engines that allow overwriting specific attributes, validating provided ones, or even conditional lookups in the case of Dogtag's Java based engine) or even ACME based CAs -- ACME has out-of-band subject identifiers and will discard what is on the CSR in favor of what was specified in the protocol.
Vault's PKI Secrets engine lets the operator (not the cert requester --- as that'd be a security vulnerability!) control the final cert's subject via roles. The CSR's fields are supposed to be translated to request parameters.
There are three relevant parameters on the role:
- require_cn (bool: true) - If set to false, makes the common_name field optional while generating a certificate.
- use_csr_common_name (bool: true) - When used with the CSR signing endpoint, the common name in the CSR will be used instead of taken from the JSON data. This does not include any requested SANs in the CSR; use use_csr_sans for that.
- use_csr_sans (bool: true) - When used with the CSR signing endpoint, the subject alternate names in the CSR will be used instead of taken from the JSON data. This does not include the common name in the CSR; use use_csr_common_name for that.
It might be that your role has set all of these to false
(try a vault read pki/roles/example-dot-com
), to reject taking the CN and SANs from the cert, and not to require a CN.
The reason why additional Subject attributes are not specified are because these are typically used in permissions systems (e.g., LDAP) and thus consumes a risk: the operator should grant explicit Group/OU/O permissions via the role, rather than taking potentially insecure values from the CSR. If you want, you can view the role exactly as the request above described: the role disallowed all other attributes, so they're not pulled from the CSR. Add them to the role and they'll be set. ;-)
If you want this type of verbatim certificate issuance, you can use sign-verbatim
without the role.
For a more comprehensive Subject construction system, see the feature request in #12426. Closing this one in favor of that one, but note the validation model still needs to be defined. At that point, we'll likely add a third parameter, use_csr_rdns
and allow operators to control whether RDNs are used wholesale from the CSR or not (validating them against the new RDN-construction policy engine).
FWIW, I am unable to reproduce the above report with the empty subject:
[cipherboy@xps15 14]$ vault read pki/roles/testing
Key Value
--- -----
allow_any_name true
allow_bare_domains false
allow_glob_domains false
allow_ip_sans true
allow_localhost true
allow_subdomains false
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains []
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
basic_constraints_valid_for_non_ca false
client_flag true
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames true
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref default
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 0s
no_store false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
server_flag true
signature_bits 256
street_address []
ttl 0s
use_csr_common_name true
use_csr_sans true
use_pss false
[cipherboy@xps15 14]$ openssl req -nodes -newkey rsa:2048 -keyout example.key -out example.csr -subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=example.com"
.............+.............+.....+.......+.........+...+...........+.+...+...+..+.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+......+..+.......+.....+...+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+......+..+...+...+............+...+....+...+...+..+.......+...+..................+..+..........+...+......+...+..+...+.+......+.........+......+........+................+.....+......+.+..+..........+.....................+.....+.+.........+.....+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.......+..+....+..................+..+...+......+.+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+............+...+..+.......+.....+.+..............+...+...+.+...+.....+.......+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.........+......+...........+...+...+...................+...+...+...+..+...+.........+.+..+.......+..+..........+...+...+........+.+......+........+.+.........+.........+..+......+...+.+.....+....+..+...+....+.....+..........+.....+...+....+......+...+......+...............+.....+....+......+...+...+..+...+....+.....+.........+.......+..+.+...............+..+...+..........+.....+.+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
[cipherboy@xps15 14]$ vault write pki/sign/testing csr=@example.csr ttl=5s
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAwIBAgIUU+COV4AAXEufDAcF8sz431hLjKIwDQYJKoZIhvcNAQEL
BQAwEjEQMA4GA1UEAxMHUk9PVCBYMTAeFw0yMjA5MjYxNDQyNTJaFw0yMjEwMjgx
NDQzMjJaMBIxEDAOBgNVBAMTB1JPT1QgWDEwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDTothnktgKcdfuzx1TvxwBdciDFmkBerJjPOn1ZKOh+IWVGEHw
gR60Df51idcE8wrCNk42X3wYRs9QbPMMA6GrWNXYf6hlpoRJuCKTKGOHhgJbW8iW
W+FJeYaUepcfgy39JH/VHpRhVMCsYJtq4oGm6cBDCy5vZXLIorkRULE9sDv0N1B6
Xy7xUGSdT5PWoYwe/GMKQzjyb7wi5oXZp9r73/29jH6+mUqVB3SgkFS/bem9zqRS
XKhSI0HMK5bfFq8bajHrUVkA3dmS2FUjMOzgGScZzrW+whcS8VS50zHXtFzbnH7F
yV3KAKBfw1VPLl7QRpzY8Ijb5DtidYyjK3oDAgMBAAGjYzBhMA4GA1UdDwEB/wQE
AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR1c2pymFDFJ5t3TKvsQmxw
AfcUTDAfBgNVHSMEGDAWgBR1c2pymFDFJ5t3TKvsQmxwAfcUTDANBgkqhkiG9w0B
AQsFAAOCAQEAYCHJ4w3GbrMmz+LZKeviECQIZ/NvJzvmNg6zHlmoh1kZUCLaq9iD
mAcRxqlf5Jdck1puXmZaeIAcyEL2FvBNGgIVvkfMrhmh0XqZuT5R42boPS+DwJ4S
jJhmUTR7fK/m+7gjt8ajj4kiL9AGTKXF9XIpgOJ4yxIQnvPXC0SEKEXhBxyITt4b
40XzcOexkj/0jKmpD8520vtRmjyuW2fumMHz6e2Up5IBAKUiYyhrri+Nzpw6eB5a
qxfbi78J5j7k3MDoSXbY6UHM6qkhsqtcqHHFZX+5OaEU23eARCLDOQpuXchXoOSW
WfdRwxapsLbVjaGmNL5U5NzwBaiQbrJRCg==
-----END CERTIFICATE-----]
certificate -----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIUJD8rIp12ciO5sgIbMNoZC3UFqaswDQYJKoZIhvcNAQEL
BQAwEjEQMA4GA1UEAxMHUk9PVCBYMTAeFw0yMjA5MjYxNDQzMDJaFw0yMjA5MjYx
NDQzMzdaMBYxFDASBgNVBAMTC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAu3R5myHrNZUOda4BqZc7sktrOtRu3J1A1+0WeZfrfpZS
aD2ZbjgDaxcQSMRl3sJCC3fgAEHs2jxjzoLNievD9wRQFyBCNaNKUV5i1W2CrvfV
GH9JWedRng+oCBUog/URTR0sOyBj7q5SePDzXYVfXF2S3ns9EVxLFsBzUEDh18TB
au+qQKeMYNT3YTJkJDTYnUlDP/2XBbxjJPW1wEdrWD/nz6dzq8N4x+GLTIc3LjlR
jmjGYdBmMnVAnyfr1i5hdcPidUlfmTw1317QfYghGq/pSIT0cUnp9XSYR/HWGL/N
sxQyw5QjZdTJlVzWGn2zny2xtJ15nTUNMdXKfwTfBwIDAQABo4GKMIGHMA4GA1Ud
DwEB/wQEAwIDqDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0O
BBYEFACh0qe7CfHhg0FrIY1QndB4Y4kDMB8GA1UdIwQYMBaAFHVzanKYUMUnm3dM
q+xCbHAB9xRMMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUA
A4IBAQA5vjWi2+eXqqgClv6/g4nrQCMUCBXfx/R3xVyBiMhC4kQrFyVjtk4XnLQx
ixWfL21tVA7QmNWYojKZbqUhFuvbDv4tc2qZwTORRADO7ZqBnDvRj3XRxXKkq0vi
Dm+4fNa/h3WUXOU50fQbTEHQPU/TDUdjxl292ozxxs9k5WEF5UDpqng6nJR2znUu
2QmtOe9u7g6wIT0T+/iocr7nhxGbgh2pv9dJPcPFTiP/GRD7+etX7BZIVWk8AvxV
IS3MzV4XEOYrr+2IgtY2Mj9vR//pg1vkHhkJbABouycpQID87siooyl0PqwcE+B4
6IcfGlehaUnIjGbkZ7OF1EDXxpbC
-----END CERTIFICATE-----
expiration 1664203417
issuing_ca -----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAwIBAgIUU+COV4AAXEufDAcF8sz431hLjKIwDQYJKoZIhvcNAQEL
BQAwEjEQMA4GA1UEAxMHUk9PVCBYMTAeFw0yMjA5MjYxNDQyNTJaFw0yMjEwMjgx
NDQzMjJaMBIxEDAOBgNVBAMTB1JPT1QgWDEwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDTothnktgKcdfuzx1TvxwBdciDFmkBerJjPOn1ZKOh+IWVGEHw
gR60Df51idcE8wrCNk42X3wYRs9QbPMMA6GrWNXYf6hlpoRJuCKTKGOHhgJbW8iW
W+FJeYaUepcfgy39JH/VHpRhVMCsYJtq4oGm6cBDCy5vZXLIorkRULE9sDv0N1B6
Xy7xUGSdT5PWoYwe/GMKQzjyb7wi5oXZp9r73/29jH6+mUqVB3SgkFS/bem9zqRS
XKhSI0HMK5bfFq8bajHrUVkA3dmS2FUjMOzgGScZzrW+whcS8VS50zHXtFzbnH7F
yV3KAKBfw1VPLl7QRpzY8Ijb5DtidYyjK3oDAgMBAAGjYzBhMA4GA1UdDwEB/wQE
AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR1c2pymFDFJ5t3TKvsQmxw
AfcUTDAfBgNVHSMEGDAWgBR1c2pymFDFJ5t3TKvsQmxwAfcUTDANBgkqhkiG9w0B
AQsFAAOCAQEAYCHJ4w3GbrMmz+LZKeviECQIZ/NvJzvmNg6zHlmoh1kZUCLaq9iD
mAcRxqlf5Jdck1puXmZaeIAcyEL2FvBNGgIVvkfMrhmh0XqZuT5R42boPS+DwJ4S
jJhmUTR7fK/m+7gjt8ajj4kiL9AGTKXF9XIpgOJ4yxIQnvPXC0SEKEXhBxyITt4b
40XzcOexkj/0jKmpD8520vtRmjyuW2fumMHz6e2Up5IBAKUiYyhrri+Nzpw6eB5a
qxfbi78J5j7k3MDoSXbY6UHM6qkhsqtcqHHFZX+5OaEU23eARCLDOQpuXchXoOSW
WfdRwxapsLbVjaGmNL5U5NzwBaiQbrJRCg==
-----END CERTIFICATE-----
serial_number 24:3f:2b:22:9d:76:72:23:b9:b2:02:1b:30:da:19:0b:75:05:a9:ab
This certificate has example.com
on the CN field. When I either remove the CN from the CSR (and leave it off the API call) or modify the role to set use_csr_common_name=false
, I get:
[cipherboy@xps15 14]$ vault write pki/sign/testing csr=@example.csr ttl=5s
Error writing data to pki/sign/testing: Error making API request.
URL: PUT http://localhost:8200/v1/pki/sign/testing
Code: 400. Errors:
* the common_name field is required, or must be provided in a CSR with "use_csr_common_name" set to true, unless "require_cn" is set to false
So likely, you're also interacting with a role with require_cn=false
.
HTH,
Thx @cipherboy! I'll keep watching #12426.
Just some sidenotes, may be someone will reach this point once. We're using k8s cert-manager with vault to issue certificates and it allows to specify (check more here):
subject:
organizations:
- jetstack
Found out while digging, that the cert-manager is adding the subject
to the CSR and calls a PKI role to sign, but the generated certificate is not having any organization (the PKI role doesn't define any in our case). Agree it's a security concern without validation, but eager to have once the use_csr_rdns
option.
@phamrak Can you add the organization to the role that cert-manager is hitting? E.g., vault write pki/roles/example-dot-com ... o=jetstack
?
I think from my discussions with Ricardo that is how it is typically deployed, with each cert-manager using a different role based on the desired organizations...
@cipherboy yes, we can split the roles by organizations. My previous post was about that the cert-manager subject
configuration is ignored. Understand the reason why it's like this on behind, but it's not obvious. A nice hint about in the documentation would be nice. But not sure where's the best place, probably in cert-manager itself.
@cipherboy @phamrak
`vault write test/roles/test_server key_bits=2048 max_ttl=8750h allow_any_name=true require_cn=false use_csr_common_name=true
openssl req -new -key private.key -out req1.csr -subj "/C=CN/ST=London/L=London/O=example/OU=Personal/CN=we/emailAddress=aospace@com"
`vault write -format=json test/issue/test_server common_name="example.com" csr=@req1.csr format=pem ttl="8660h" | jq -r '.data.certificate' > certificate.crt`
but the cert certificate has no csr subject informations? `
C
, ST
, L
, O
, OU
are not the common name and thus won't be copied over. use_csr_common_name=true
strictly uses the Subject/CN
field that you should seen should be copied over... Other than you overriding it explicitly on the CLI with common_name
perhaps (drop that and it definitely should be).
If you want to sign CSRs as-is, including O/OU information, right now your best approach is using sign-verbatim
, which requires pre-verification of the CSR.
The Hashicorp Vault Discuss forum might be a better place for this discussion, tbh.
Describe the bug CSR subject field is not carried over to certificate subject while PKI signing process. By definition in the RF5280 states that certificate
Subject
field shouldidentify the entity associated with the public key
. The only way to know it for the CA is to read it from the CSRSubject
and if valid, pass it to the issued certificate. This is not the case for vault PKI.To Reproduce
Sign the CSR with vault. Set the X-Vault-Token header to valid token and change host/port to valid destination:
Show the text of generated certificate
Expected behavior Expecting that issued certificate contains the
Subject
RDNs from CSR. The cert_util.go takes just the settings of the PKI role. It's debatable, but PKI role should state which O,OU etc. are valid but CSR should be the one defining them.Environment:
Additional context Check discussion 44456