From a9a443a72905695d1c9411a2ea77ee413f6c2f9e Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Fri, 21 May 2021 13:32:45 +0200 Subject: [PATCH] Make SP check more certs in IDP metadata From https://www.oasis-open.org/committees/download.php/56785/sstc-saml-metadata-errata-2.0-wd-05.pdf ``` [E62]A use value of "signing" means that the contained key information is applicable to both signing and TLS/SSL operations performed by the entity when acting in the enclosing role. A use value of "encryption" means that the contained key information is suitable for use in wrapping encryption keys for use by the entity when acting in the enclosing role. If the use attribute is omitted, then the contained key information is applicable to both of the above uses. ``` We need to include certificates both when they have a "use" attribute of "signing" as well as when the "use" attribute is missing. Fixes #352 SAML input from @simmel. --- service_provider.go | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/service_provider.go b/service_provider.go index f76140ab..3c7b94f4 100644 --- a/service_provider.go +++ b/service_provider.go @@ -288,22 +288,15 @@ func (sp *ServiceProvider) GetSLOBindingLocation(binding string) string { // signed by the IDP in PEM format, or nil if no such certificate is found. func (sp *ServiceProvider) getIDPSigningCerts() ([]*x509.Certificate, error) { var certStrs []string + + // We need to include non-empty certs where the "use" attribute is + // either set to "signing" or is missing for _, idpSSODescriptor := range sp.IDPMetadata.IDPSSODescriptors { for _, keyDescriptor := range idpSSODescriptor.KeyDescriptors { - if keyDescriptor.Use == "signing" { - certStrs = append(certStrs, keyDescriptor.KeyInfo.Certificate) - } - } - } - - // If there are no explicitly signing certs, just return the first - // non-empty cert we find. - if len(certStrs) == 0 { - for _, idpSSODescriptor := range sp.IDPMetadata.IDPSSODescriptors { - for _, keyDescriptor := range idpSSODescriptor.KeyDescriptors { - if keyDescriptor.Use == "" && keyDescriptor.KeyInfo.Certificate != "" { + if keyDescriptor.KeyInfo.Certificate != "" { + switch keyDescriptor.Use { + case "", "signing": certStrs = append(certStrs, keyDescriptor.KeyInfo.Certificate) - break } } }