From ba04a284f8a8a4a8f08cd29a2f49dcbf7e730e59 Mon Sep 17 00:00:00 2001 From: Vault Automation Date: Wed, 14 Jan 2026 11:12:57 -0800 Subject: [PATCH] Validate that certificate of the connection matches (#11695) (#11764) * Validate that certificate of the connection is the same as the certificate we are trying to renew for. * add changelog * Add explicit check for nil-entry. * Remove the cast - PR feedback. Co-authored-by: Kit Haines --- builtin/credential/cert/backend_test.go | 31 +++++++++++++++++-- builtin/credential/cert/path_login.go | 6 +++- .../cert/test-fixtures/testcert1.pem | 20 ++++++++++++ .../cert/test-fixtures/testcert2.pem | 20 ++++++++++++ .../cert/test-fixtures/testkey1.pem | 27 ++++++++++++++++ .../cert/test-fixtures/testkey2.pem | 27 ++++++++++++++++ changelog/_11695.txt | 3 ++ 7 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 builtin/credential/cert/test-fixtures/testcert1.pem create mode 100644 builtin/credential/cert/test-fixtures/testcert2.pem create mode 100644 builtin/credential/cert/test-fixtures/testkey1.pem create mode 100644 builtin/credential/cert/test-fixtures/testkey2.pem create mode 100644 changelog/_11695.txt diff --git a/builtin/credential/cert/backend_test.go b/builtin/credential/cert/backend_test.go index c0ea9278a0..efad03179e 100644 --- a/builtin/credential/cert/backend_test.go +++ b/builtin/credential/cert/backend_test.go @@ -2363,8 +2363,8 @@ func Test_Renew(t *testing.T) { } b := lb.(*backend) - connState, err := testConnState("test-fixtures/keys/cert.pem", - "test-fixtures/keys/key.pem", "test-fixtures/root/rootcacert.pem") + connState, err := testConnState("test-fixtures/testcert1.pem", + "test-fixtures/testkey1.pem", "test-fixtures/root/rootcacert.pem") if err != nil { t.Fatalf("error testing connection state: %v", err) } @@ -2426,6 +2426,33 @@ func Test_Renew(t *testing.T) { t.Fatalf("got error: %#v", *resp) } + // Try changing the cert - this should fail + goodConnState := connState + connState, err = testConnState("test-fixtures/testcert2.pem", + "test-fixtures/testkey2.pem", "test-fixtures/root/rootcacert.pem") + req.Connection.ConnState = &connState + if err != nil { + t.Fatal(err) + } + _, err = b.pathLoginRenew(context.Background(), req, empty_login_fd) + if err == nil { + t.Fatal("expected error") + } + + // Reset connState to the good one, this should work: + connState = goodConnState + req.Connection.ConnState = &connState + resp, err = b.pathLoginRenew(context.Background(), req, empty_login_fd) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("got nil response from renew") + } + if resp.IsError() { + t.Fatalf("got error: %#v", *resp) + } + // Change the policies -- this should fail fd.Raw["token_policies"] = "zip,zap" _, err = b.pathCertWrite(context.Background(), req, fd) diff --git a/builtin/credential/cert/path_login.go b/builtin/credential/cert/path_login.go index 35e227629f..849f1fba38 100644 --- a/builtin/credential/cert/path_login.go +++ b/builtin/credential/cert/path_login.go @@ -280,9 +280,13 @@ func (b *backend) pathLoginRenew(ctx context.Context, req *logical.Request, d *f // Certificate should not only match a registered certificate policy. // Also, the identity of the certificate presented should match the identity of the certificate used during login - if req.Auth.InternalData["subject_key_id"] != skid && req.Auth.InternalData["authority_key_id"] != akid { + // For the identity of the certificate to match, both the subject key ID and authority key Id should match + if req.Auth.InternalData["subject_key_id"] != skid { return nil, fmt.Errorf("client identity during renewal not matching client identity used during login") } + if req.Auth.InternalData["authority_key_id"] != akid { + return nil, fmt.Errorf("client authority identity during renewal not matching client identity used during login") + } } // Get the cert and use its TTL diff --git a/builtin/credential/cert/test-fixtures/testcert1.pem b/builtin/credential/cert/test-fixtures/testcert1.pem new file mode 100644 index 0000000000..ae39599d14 --- /dev/null +++ b/builtin/credential/cert/test-fixtures/testcert1.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUKJtTQMEcL+SjIDyoqDFZ/JQFAIwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wIBcNMjYwMTA5MjEyMzM2WhgPMjA3 +NTEwMDYxMzI0MDZaMBsxGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0Il8itdPokxLUfLylUx2BU0keMVc1 +ADkQLVSRbn8PadSDp6bs9EBe2vhWM0kfs/OyKC9Y1AMd7dubmj+KYemOpEjnayoi +ym/RB767b9JgphnkbvR13V7qUVkWGdiXVBbultTaSpNNSUTPkhQoxYgl3VM9G+Vc +7hXJ4u7/SyhqA5R2HuPAse4HQG2HBvHU5qsmSEfZijQNR6YpL/qfCki3Fj7G4ZA0 +6QGVYltcAKmsBC1KtIxlxbxMzdkkiQrzaq1otEGR1Db9ScLFz1Kf5APT5lIoOC4T +qwn9KRA10wkTL0yCYO0LkrHbmEFcagZBq0I8tfan2TMkOQdMLrhk0U2jAgMBAAGj +gZUwgZIwDgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +BQcDAjAdBgNVHQ4EFgQUAsz+3ch3eUMLIOBSaBHNvkuotpwwHwYDVR0jBBgwFoAU +ncSzT/6HMexyuiU9/7EgHu+ok5swIQYDVR0RBBowGIIQdGVzdC5leGFtcGxlLmNv +bYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAeQpN2vLKiTbLw1JhpvIlUzOftWU/ +tykJDMuTOP2QBTPq9pRvofE5Ij/nCZj2z7+Ui3M/RsuziCA2qzlT5voqL3cQZ6FJ +xYm+oUlIyw+88/ArcSUZmWaA/dtkvn0CUTImSgYKswlzCBABISGGzCC5xPkhLKfa +lVB6jQFmSyOXmeSKwA1KXOhykzUVvFvhjMJidWj12rsB6jzixLCtCuhPgXol801w +X76Ul8bKtVaZOLyzUd/eWcd3qSVi7jvuTtC368pV9CsIzanXAG+rfmOXQhMh48C+ +4IQFEXjf9u18KgQrk3UCwN4bhIwzyNAd90A3rdiv0a86jZjmOtPJZzypEw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/builtin/credential/cert/test-fixtures/testcert2.pem b/builtin/credential/cert/test-fixtures/testcert2.pem new file mode 100644 index 0000000000..c6defccc02 --- /dev/null +++ b/builtin/credential/cert/test-fixtures/testcert2.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUegOuC0oLkgJXvcRbbqq6HaU4b48wDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wIBcNMjYwMTA5MjEzODM1WhgPMjA3 +NTEwMDYxMzM5MDVaMBsxGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwzWVwpgL1ezR+nphVdcSJpAXDIqh0 +ByClMi9Zr9iDEPnSAoLAaXKkhn81IyydsL2RHbt+jjUaGjBfd8Y4ib/0abiGN6fo +R1WNIVRE6tYMJZ6WntWyPsGrqPCpLU9PTrovGGqV1u498AJPJPmPYHvEoceHUEbS +e9qlsQis+hjd9CuQfXRYhhcBjBZQo6IQ/9ucS5VPF2M7+c+6TjlnHiO+UPKIwEtr +74SRQngG4jMVYwG8GLDBB6rLlqhoUqwxl1ld4UnIitbb7uiG0lnT4liT0l11pjVy +1DxMM5g6h2tIIqNECriwAD1DWe28GVmi59EPwBT6yPt/1QkGcj1ukPsJAgMBAAGj +gZUwgZIwDgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +BQcDAjAdBgNVHQ4EFgQUidElpxqnvZelSOfHrdHBDj4WOYowHwYDVR0jBBgwFoAU +ncSzT/6HMexyuiU9/7EgHu+ok5swIQYDVR0RBBowGIIQdGVzdC5leGFtcGxlLmNv +bYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAM0rhxChmXvCNOZLmeoijW8u3Piw4 +HrYNKvubgoWlhSaJTyvqHyNtgvIDoR4nLwlTe0hfww32gSueIqRcmmrH+0S1406k +Z88bgFFN1pNRR0yNhu9obxAbHY/nK8/ODeJF8h+waqhfWw6JRWxV3+8IprqAL+F8 +Oz5gJ1JpMNR7SfgZgNMDHnXdYt/XyDGWdzIG9L8xJ8X6wPZRmYYWKIfuFZWijoav +9LReF31VbXrEn/Qlb7JO5lfPFmmasXzkCJC8DlnWVFhsh/iyfxDo35kc4WlQ371K +KRZco41pVge0ExY69IENa8dqL882hrU+g3UTo09MCMpuNUYwmS4wrmEOgA== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/builtin/credential/cert/test-fixtures/testkey1.pem b/builtin/credential/cert/test-fixtures/testkey1.pem new file mode 100644 index 0000000000..6d81857a63 --- /dev/null +++ b/builtin/credential/cert/test-fixtures/testkey1.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAtCJfIrXT6JMS1Hy8pVMdgVNJHjFXNQA5EC1UkW5/D2nUg6em +7PRAXtr4VjNJH7PzsigvWNQDHe3bm5o/imHpjqRI52sqIspv0Qe+u2/SYKYZ5G70 +dd1e6lFZFhnYl1QW7pbU2kqTTUlEz5IUKMWIJd1TPRvlXO4VyeLu/0soagOUdh7j +wLHuB0Bthwbx1OarJkhH2Yo0DUemKS/6nwpItxY+xuGQNOkBlWJbXACprAQtSrSM +ZcW8TM3ZJIkK82qtaLRBkdQ2/UnCxc9Sn+QD0+ZSKDguE6sJ/SkQNdMJEy9MgmDt +C5Kx25hBXGoGQatCPLX2p9kzJDkHTC64ZNFNowIDAQABAoIBAAalZgEv2DuygXVZ +jNREtsf4vK/ific0dOaF5aLgAswcyXx6CQyhDmbxiUwU5FPJHeqq1ORgHiVSi1G4 +ZTPD3QwoP5BaQdm6wlliAcWEoKx0NGxbM6XNnxziF3lbRsR+k8IFyqCrM7gcRe+q +ohfHAfjzq4iLqPC+0Ar81niQ21Ld8xgck3t+UWtgoYdLAyA8aIa43k+I3wHEPhNv ++1w+/F/dOKcmCMBrnh3ff6mot/6J31MOecP8tU1ss5nWyJ3B+3tdHjETIcWWFhtG +w5XXlP+e39C/Haq8+h+3AgsCPVoLfVAEMDtwyax+a9S7tEie+F09ENecRPlDJLQi +cepy+uECgYEA0NQrwRFJGmaTi5zsgwXu04kbsx8vCdR0SlJeE++s7zhwH8SD66np +ZxjiAHTu6OxlIkxLR0C+YKKpP2c9sq2jpj4saJzxHtv+E9N6qSuPj1ULQ/yKQhog +y9bIBpznuTaK1k2nJ8naWoYJuiFN3LQhMmGyVRr4+MSbY0FkzWNRKVkCgYEA3NLl +1qlKPRvn3Q1oT4y9vkvtlVINZael2aZS+zM+yuZyZoo7ximOeYIMJ/YQGH1b7ygl +bLEnaCS+OBFRA4RkAwAeO9I7g57gJjoFKo4KCyF9T9oPEa5NYXAohvLhiJRZJgG/ +dhpwcQgMRUGC9nzj8wk8KJJ5rnWf+T18afVWE1sCgYEAztpr4NmTdRBIdJHjgUGe +OXFlu79W48DL1FbUk6Dkxy07e2w4VHbBGPt/2n35rUWERD4YjyLlsWlOhtxoNBZl +tSV+7b0P5sZ5XgAsT2gz0wGloBmGhkXFWMSO7GX97uvFCNRwkCwVG3gMKJAWxVi0 +TWiSslR+bESrutyq0fvgCDkCgYBCQqImvFuDZKk5QjmnjRKuVDgxExLkCt8QJQFH +UQQpe+ad8CKpfnS67xPYtdP0lUENzR0VtT6e2E+foUqO5J3h7Jol1xp2jyixL723 +HDHVTzI70LGu239qmm3+uEiGZAUwC1w5Awv0Trbn3RWAAs+fcIj1n6YVfEQJVLLN +VImEewKBgALnn48dFKSRPWcYJKnbWI5ujsggUZmabuWJKwiHeoTgJ8o8yFtWrFIW ++GVPqL2ZrKhrF+sYqbVX6yjF+0GzeGIjtaW9DifvimJ2kyhyncUEomDxRsl22/LG +P3w7PM0YzvAuo6muYqqhljhNpZUBRmCvpBaqsNwoJc04cYhfFvhn +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/builtin/credential/cert/test-fixtures/testkey2.pem b/builtin/credential/cert/test-fixtures/testkey2.pem new file mode 100644 index 0000000000..c8b16f98d2 --- /dev/null +++ b/builtin/credential/cert/test-fixtures/testkey2.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsM1lcKYC9Xs0fp6YVXXEiaQFwyKodAcgpTIvWa/YgxD50gKC +wGlypIZ/NSMsnbC9kR27fo41GhowX3fGOIm/9Gm4hjen6EdVjSFUROrWDCWelp7V +sj7Bq6jwqS1PT066LxhqldbuPfACTyT5j2B7xKHHh1BG0nvapbEIrPoY3fQrkH10 +WIYXAYwWUKOiEP/bnEuVTxdjO/nPuk45Zx4jvlDyiMBLa++EkUJ4BuIzFWMBvBiw +wQeqy5aoaFKsMZdZXeFJyIrW2+7ohtJZ0+JYk9JddaY1ctQ8TDOYOodrSCKjRAq4 +sAA9Q1ntvBlZoufRD8AU+sj7f9UJBnI9bpD7CQIDAQABAoIBAATt2wbEmBdGNbDU +hNh4GbBBLohx0Eq40qYMY8HPO1zvFZnvaDwLTI8N8WC2v/UPAv/3WV12Q0B8q63T +sebsXznGE0cJqPCawYW3YMkxl2FcEKNwHvLS2VUq9veue9QxFJOAzaLrDLYVGYlh +lWQUC2tQW9bXy/utCIvfR0fESrpwWwQgjFJQJnoiWs9RYG/crpaIZUZOsGcWWGwI +6qUKO/aqL0zVcb6+grwtppCgJKx7jx0bXj8LkhTUxzxx8IW0YK/lvJ/wxhfy5242 +DJLD2hBmxpW4FiAss26jKkaznzrLVrCUYWDSa//11dYnTZMNL8N5zqhYmnrnVd4N +Yju6/1ECgYEA1oHxreRvmYgYkMqY6r4qHT/cTHgQc0zwL1OXqIZrYFgHQqQ1VrHg +bdhGMXJAPhEtuPuVPqikv9bdVfvhf6bt3h5bGYnz3cKpi+ud70c88hOQCr33CCVN +54JQC0UDi7EQRqAhGaLpFah4S46kbLzpuPTsKpUR8lic/aAwdVV6o5kCgYEA0wBZ +zECi1yzwdKspoJwUJwdfSU1JJSwS2uWSMxRhkY1Avg8RNMQcb+3gM7Jt+BTL0dy7 +Fxr8kQ235NfY8rnJz0auNFpYjIRDb0KI82THDQovg+EvhdD5FaOJk5kS4jYfe2N4 +Iy6szO9NweoLO3xmZcYECuGtLqq4pVOxLqkfuPECgYEAi5LjwaU45GqEqXnaBCwW +VQ/fdTZOZeezBOhcbwB/z6GXn8ofFrkI8hBeo//WQ0yENrAkjS/IezcAr9kEAj6I +2hVga36y2iG2ll+KVU5CHrWR7RtsKLW1OiU1lg+i3fspPvskbnztMvV6yJcY79QA +NCPRo2d51PnJtNHNlhs3gEkCgYEAtXY1xA1KfldtrEiPkkroofAbKIVJBKj0xkBt +DXTXvD+IkGuQ1ppaAoDHMm6fWJ059JAqbmKNF4p+vlZLg+P4BUS6CNgyExakkAje +ksP20+YQmxCMuD7SGKP+a2tX7Cezx3/yD//SKKUdcEmBw3Tm81vqmhkfwWSdS8HA +PWrBl2ECgYAeZYrxrwWkelcbhJsxkOgeQhJkfUdv/VuDLT5pcJlH5jjvaFsEWDZW +wCtQz2KLrEK1u/HnfmjXgRURvDgf1qddGD/BV83AnBIHtXD9ia8dtbt/4rY+KaYU +/ROg406oZ7m55UhsUtuQkNAcAG7IvhHDGCp9dY2QaheeXpHvcDxe+w== +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/changelog/_11695.txt b/changelog/_11695.txt new file mode 100644 index 0000000000..0035da77af --- /dev/null +++ b/changelog/_11695.txt @@ -0,0 +1,3 @@ +```release-note:security +auth/cert: ensure that the certificate being renewed matches the certificate attached to the session. +```