Announcement Announcement Module
Collapse
No announcement yet.
PKIX path construction failed for untrusted credential Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • PKIX path construction failed for untrusted credential

    I get the following error in my logs after I am returned back to the web application after SSO:
    Code:
    ERROR 24.01.2013 14:38:10:219 (CertPathPKIXTrustEvaluator.java:validate:81) - PKIX path construction failed for untrusted credential: [subjectName='CN=*.difi.no,O=DIREKTORATET FOR FORVALTNING OG IKT,L=Oslo,ST=Oslo,C=NO' |credential entityID='idporten-ver2.difi.no']: unable to find valid certification path to requested target
    To me, it seems that this belongs to the IdP's server certificate and not the public key of the metadata/IdP certificate which I have added to my keystore. I have received the server's SSL certificate and tried to add that to my keystore as well, but the error message is still there.

    Everything works, but I want to get rid of this error message which fills up my log.

    Do I have to change some settings in ExtendedMetadata?

    Additional information:
    • My (SP) metadata is hand written and I have skipped <ds:Signature... </ds:Signature>. My public key for signing and encryption is included, of course.
    • SP's public and private keys are generated by using openssl with AES algorithm.
    • I'm using the IdP's test server, that's why I have generated the SP key pair by myself.

    Regarding ExtendedMetadata, should I place an ExtendedMetadataDelegate block around my SP metadata settings and change some settings regarding securityProfile properties since I have skipped signature of my SP metadata?

    My settings so far:

    Code:
        <!-- IDP Metadata configuration - paths to metadata of IDPs in circle of trust is here -->
        <!-- Do no forget to call iniitalize method on providers -->
        <bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
            <constructor-arg>
                <list>
                	<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
                        <constructor-arg>
    						<bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
                        		<constructor-arg>
                            		<value type="java.io.File">${nettskjema.saml.minid_xml_path}</value>
                        		</constructor-arg>
                        		<property name="parserPool" ref="parserPool"/>
                    		</bean>
                        </constructor-arg>
                        <constructor-arg>
                            <bean class="org.springframework.security.saml.metadata.ExtendedMetadata"/>
                        </constructor-arg>
                    </bean>
                    <bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
                        <constructor-arg>
                            <value type="java.io.File">${nettskjema.saml.metadata_provider_path}</value>
                        </constructor-arg>
                        <property name="parserPool" ref="parserPool"/>
                    </bean>
                </list>
            </constructor-arg>
            <property name="hostedSPName" value="${nettskjema.saml.hostedSPName}"/>
            <!-- OPTIONAL property: can tell the system which IDP should be used for authenticating user by default. -->
            <property name="defaultIDP" value="${nettskjema.saml.defaultIDP}"/>
        </bean>
    Regarding the last placeholder, here's the correct value from my property file:
    nettskjema.saml.defaultIDP=idporten-ver2.difi.no (this entityID shows up in the error message).

  • #2
    Hi,

    As you say, the error is likely coming from the verification of SSL/TLS certificate during Artifact resolution. System first tries to check it for trust with public keys from metadata (and this likely reports the error) and then with keys from the keystore which probably succeeds (by default with all keys available there).

    You can manually add the root CA certiticate of the SSL/TLS endpoint to the IDP metadata as another key which should make the error go away. The other - more difficult - way is to modify ExtendedMetadata of your SP and set property sslSecurityProfile to metaiop. Then download the leaf (not the CA or intermediary CA one) certificate of the SSL/TLS endpoint (e.g. using ssl-extractor) and add it to the keystore with a custom alias. Then set property tlsKey to the selected alias in ExtendedMetadata of the IDP. The downside of this approach is that in case IDP renews the certificate you'd need to make a modification to your settings.

    In case this wouldn't help please run the SSO process with debug on and send me the result.

    Vladimír Schäfer

    Comment


    • #3
      Thanks a lot for your help, Vladimír!

      This is what I have tried so far.
      1. Added the leaf to the global Java keystore, but the error message is still there.

      2. Added the leaf to the SAML keystore, added the alias by using the tlsKey parameter, which made the annoying error message to disappear. Here is my updated settings:
      Code:
      <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
        <property name="securityProfile" value="metaiop"/>
        <property name="tlsKey" value="difissl" />
      </bean>
      3. Removed the leaf from SAML keystore and the tlsKey parameter (kept the securityProfile setting). The error message shows up again.

      Anyway, this solution is not ideal. We only want to maintain our own certificates and update the IDP's public key before it expires. We do not want to be dependent on the endpoint SSL certificates as it complicates everything since we must detect when the certificate is going to expire at the endpoint.

      You can manually add the root CA certiticate of the SSL/TLS endpoint to the IDP metadata as another key which should make the error go away.
      You mean the DigiCert CA which is stored in Java's keystore by default? As long as this does not cause an extra maintenance work. Since it is a CA and not a leaf, it sounds like a one-time action.

      Or should we just ignore this error message as it seems to work anyway, even in production mode? My wish is that this behaviour is changed in the SAML module. I don't think it is a good idea that an error message shows up when everything is configured normally, or what do you think? I can always create a ticket for this if you agree.

      Comment


      • #4
        Adding the CA cert to IDP metadata is a one-time operation with no maintenance. The metadata should look something like this:

        Code:
        <IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
            ..... other keys .....
            <KeyDescriptor>
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <ds:X509Data>
                        <ds:X509Certificate>
        MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
        bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
        ZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw
        CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK
        BgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B
        AQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+
        RkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY
        Js0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U
        QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
        cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
        /FfwWigmrW0Y0Q==
                        </ds:X509Certificate>
                    </ds:X509Data>
                </ds:KeyInfo>
            </KeyDescriptor>
        ......
        Where the newly added key has the "use" attribute ommited and the key itself is the issuer CA of the SSL certificate you have.

        But, please go ahead and open a Jira issue. I agree that system shouldn't complain in this case, so let's fix it.

        Comment


        • #5
          Thanks!

          I have opened:
          https://jira.springsource.org/browse/SES-117

          Comment


          • #6
            The fix is now in. If you have a moment please retest the issue and let me know whether everything works as expected.

            Cheers, Vladi

            Comment


            • #7
              Thanks a zillion, Vladimír!

              We do not longer see the error message in our logs, so your fix works as it should.

              Have a nice weekend!

              Comment


              • #8
                After we began to use MetadataGeneratorFilter, it seems that we have this issue again. This is what shows up in our logs. To me this has something to do with the SSL/TLS certificate to the endpoint.

                Code:
                [2013-02-07 15:21:57.778] {resin-port-127.0.0.1:6845-189} org.opensaml.common.SAMLRuntimeException: Error decoding incoming SAML message
                                                                                at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:91)
                                                                                at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
                                                                                at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
                                                                                at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
                                                                                at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166)
                                                                                at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
                                                                                at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
                                                                                at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
                                                                                at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
                                                                                at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
                                                                                at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
                                                                                at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
                                                                                at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:78)
                                                                                at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
                                                                                at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
                                                                                at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
                                                                                at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
                                                                                at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
                                                                                at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
                                                                                at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:152)
                                                                                at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
                                                                                at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
                                                                                at com.caucho.server.webapp.WebAppListenerFilterChain.doFilter(WebAppListenerFilterChain.java:114)
                                                                                at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:156)
                                                                                at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:289)
                                                                                at com.caucho.server.hmux.HmuxRequest.handleInvocation(HmuxRequest.java:473)
                                                                                at com.caucho.server.hmux.HmuxRequest.handleRequestImpl(HmuxRequest.java:374)
                                                                                at com.caucho.server.hmux.HmuxRequest.handleRequest(HmuxRequest.java:341)
                                                                                at com.caucho.network.listen.TcpSocketLink.dispatchRequest(TcpSocketLink.java:1345)
                                                                                at com.caucho.network.listen.TcpSocketLink.handleRequest(TcpSocketLink.java:1301)
                                                                                at com.caucho.network.listen.TcpSocketLink.handleRequestsImpl(TcpSocketLink.java:1285)
                                                                                at com.caucho.network.listen.TcpSocketLink.handleRequests(TcpSocketLink.java:1193)
                                                                                at com.caucho.network.listen.TcpSocketLink.handleAcceptTaskImpl(TcpSocketLink.java:992)
                                                                                at com.caucho.network.listen.TcpSocketLink.handleAcceptTask(TcpSocketLink.java:944)
                                                                                at com.caucho.network.listen.ConnectionTask.runThread(ConnectionTask.java:114)
                                                                                at com.caucho.network.listen.ConnectionTask.run(ConnectionTask.java:93)
                                                                                at com.caucho.network.listen.SocketLinkThreadLauncher.handleTasks(SocketLinkThreadLauncher.java:169)
                                                                                at com.caucho.network.listen.TcpSocketResumeThread.run(TcpSocketResumeThread.java:62)
                                                                                at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
                                                                                at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
                                                                          Caused by: org.opensaml.ws.message.decoder.MessageDecodingException: Could not decode artifact response message.
                                                                                at org.springframework.security.saml.websso.ArtifactResolutionProfileBase.resolveArtifact(ArtifactResolutionProfileBase.java:123)
                                                                                at org.opensaml.saml2.binding.decoding.HTTPArtifactDecoderImpl.doDecode(HTTPArtifactDecoderImpl.java:94)
                                                                                at org.opensaml.ws.message.decoder.BaseMessageDecoder.decode(BaseMessageDecoder.java:79)
                                                                                at org.opensaml.saml2.binding.decoding.BaseSAML2MessageDecoder.decode(BaseSAML2MessageDecoder.java:70)
                                                                                at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:105)
                                                                                at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:172)
                                                                                at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:77)
                                                                                ... 39 more
                                                                          Caused by: org.opensaml.ws.message.decoder.MessageDecodingException: Error when sending request to artifact resolution service.
                                                                                at org.springframework.security.saml.websso.ArtifactResolutionProfileImpl.getArtifactResponse(ArtifactResolutionProfileImpl.java:109)
                                                                                at org.springframework.security.saml.websso.ArtifactResolutionProfileBase.resolveArtifact(ArtifactResolutionProfileBase.java:98)
                                                                                ... 45 more
                                                                          Caused by: javax.net.ssl.SSLHandshakeException: org.springframework.security.saml.trust.UntrustedCertificateException: Peer SSL/TLS certificate 'CN=*.difi.no, O=DIREKTORATET FOR FORVALTNING OG IKT, L=Oslo, ST=Oslo, C=NO' issued by 'CN=DigiCert High Assurance CA-3, OU=www.digicert.com, O=DigiCert Inc, C=US' is not trusted, add the certificate or it's CA to your trust store and optionally update tlsKey in extended metadata with the certificate's alias

                Comment


                • #9
                  But this time the trust of your IDP's SSL certificate doesn't get verified at all, right - in other words the SSO fails? Has something else changed? Is the CA certificate of the SSL endpoint (CN=DigiCert High Assurance CA-3, OU=www.digicert.com, O=DigiCert Inc, C=US) still in your keystore?

                  Vladi

                  Comment


                  • #10
                    My fault.

                    Yes, you are absolutely right. I created an empty keystore without any CAs defined. After I imported the cacerts into samlKeystore.jks by using keytool -importkeystore, everything works as it should. Only one more issue, and we are ready for production.

                    Comment


                    • #11
                      Uf, glad to hear, it got me worried

                      Comment


                      • #12
                        Thanks Vladi! It took me a little more digging to find that the following command dumps the cert in the expected format:

                        Code:
                        keytool -printcert -rfc -file somename.crt
                        Originally posted by vsch View Post
                        Adding the CA cert to IDP metadata is a one-time operation with no maintenance. The metadata should look something like this:

                        Code:
                        <IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
                            ..... other keys .....
                            <KeyDescriptor>
                                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                                    <ds:X509Data>
                                        <ds:X509Certificate>
                        MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
                        bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
                        ZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw
                        CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK
                        BgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B
                        AQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+
                        RkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY
                        Js0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U
                        QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
                        cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
                        /FfwWigmrW0Y0Q==
                                        </ds:X509Certificate>
                                    </ds:X509Data>
                                </ds:KeyInfo>
                            </KeyDescriptor>
                        ......
                        Where the newly added key has the "use" attribute ommited and the key itself is the issuer CA of the SSL certificate you have.

                        But, please go ahead and open a Jira issue. I agree that system shouldn't complain in this case, so let's fix it.

                        Comment

                        Working...
                        X