Uploaded image for project: 'ServiceMix'
  1. ServiceMix
  2. SM-1823

JaasAuthenticationService not properly authenticating certificate chains.

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.2.2
    • Fix Version/s: 3.4.0
    • Component/s: servicemix-core
    • Labels:
      None
    • Patch Info:
      Patch Available

      Description

      When authenticating a certificate chain, the CallbackHandler defined in the provided JaasAuthenticationService throws an UnsupportedCallbackException. The implementation checks for credentials that are an instance of X509Certificate, but should also include a check for instance of X509Certificate[] in order to properly handle a certificate chain. To fix this, the CallbackHandler can be defined as follows:

      /*

      • Licensed to the Apache Software Foundation (ASF) under one or more
      • contributor license agreements. See the NOTICE file distributed with
      • this work for additional information regarding copyright ownership.
      • The ASF licenses this file to You under the Apache License, Version 2.0
      • (the "License"); you may not use this file except in compliance with
      • the License. You may obtain a copy of the License at
        *
      • http://www.apache.org/licenses/LICENSE-2.0
        *
      • Unless required by applicable law or agreed to in writing, software
      • distributed under the License is distributed on an "AS IS" BASIS,
      • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      • See the License for the specific language governing permissions and
      • limitations under the License.
        */
        package org.apache.servicemix.jbi.security.auth.impl;

      import java.io.IOException;
      import java.security.GeneralSecurityException;
      import java.security.cert.X509Certificate;

      import javax.security.auth.Subject;
      import javax.security.auth.callback.Callback;
      import javax.security.auth.callback.CallbackHandler;
      import javax.security.auth.callback.NameCallback;
      import javax.security.auth.callback.PasswordCallback;
      import javax.security.auth.callback.UnsupportedCallbackException;
      import javax.security.auth.login.LoginContext;

      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      import org.apache.servicemix.jbi.security.auth.AuthenticationService;
      import org.apache.servicemix.jbi.security.login.CertificateCallback;

      /**

      • Implementation of the authentication service using JAAS.
      • @org.apache.xbean.XBean element="authenticationService"
        */
        public class JAASAuthenticationService implements AuthenticationService {

      private static final Log LOG = LogFactory.getLog(JAASAuthenticationService.class);

      public void authenticate(Subject subject,
      String domain,
      final String user,
      final Object credentials) throws GeneralSecurityException {
      if (LOG.isDebugEnabled())

      { LOG.debug("Authenticating '" + user + "' with '" + credentials + "'"); }

      LoginContext loginContext = new LoginContext(domain, subject, new CallbackHandler() {
      public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
      for (int i = 0; i < callbacks.length; i++) {
      if (callbacks[i] instanceof NameCallback)

      { ((NameCallback) callbacks[i]).setName(user); }

      else if (callbacks[i] instanceof PasswordCallback && credentials instanceof String)

      { ((PasswordCallback) callbacks[i]).setPassword(((String) credentials).toCharArray()); }

      else if (callbacks[i] instanceof CertificateCallback && credentials instanceof X509Certificate)

      { ((CertificateCallback) callbacks[i]).setCertificate((X509Certificate) credentials); }

      else if (callbacks[i] instanceof CertificateCallback && credentials instanceof X509Certificate[]) { ((Certificatecallback) callbacks[i]).setCertificate((X509Certificate) credentials[0]); } else

      { throw new UnsupportedCallbackException(callbacks[i]); }

      }
      }
      });
      loginContext.login();
      if (LOG.isDebugEnabled())

      { LOG.debug("Authenticating " + user + " successfully"); }

      }

      }

        Activity

        Hide
        jb@nanthrax.net Jean-Baptiste Onofré added a comment -

        Hi Kurt,

        your patch is not correct. The authenticate() method takes a Object credentials as argument. It's not possible to cast an object into an array.
        We need to have an object representation of the array (such as ArrayList for example).

        Into ServiceMix, the JAASAuthenticationService is used in the JaasAuthenticator (in the authenticate() method that returns the JAAS Subject). So we can modify both JaasAuthenticator and JAASAuthenticationService to manager credentials array/list.

        Regards
        JB

        Show
        jb@nanthrax.net Jean-Baptiste Onofré added a comment - Hi Kurt, your patch is not correct. The authenticate() method takes a Object credentials as argument. It's not possible to cast an object into an array. We need to have an object representation of the array (such as ArrayList for example). Into ServiceMix, the JAASAuthenticationService is used in the JaasAuthenticator (in the authenticate() method that returns the JAAS Subject). So we can modify both JaasAuthenticator and JAASAuthenticationService to manager credentials array/list. Regards JB
        Hide
        ranger8214 Kurt Eisenzopf added a comment -

        Thank you for looking into the issue. I'm sorry, after looking at the above patch, I realized that I was sloppy in typing in the final else clause. It should read as follows:

        else if(callbacks[i] instanceof CertificateCallback && credentials instanceof X509Certificate[]) {
        ((CertificateCallback) callbacks[i]).setCertificate(((X509Certificate[]) credentials)[0]);
        }

        Regards,
        Kurt

        Show
        ranger8214 Kurt Eisenzopf added a comment - Thank you for looking into the issue. I'm sorry, after looking at the above patch, I realized that I was sloppy in typing in the final else clause. It should read as follows: else if(callbacks [i] instanceof CertificateCallback && credentials instanceof X509Certificate[]) { ((CertificateCallback) callbacks [i] ).setCertificate(((X509Certificate[]) credentials) [0] ); } Regards, Kurt
        Hide
        jbonofre Jean-Baptiste Onofré added a comment -

        Revision 1041297.

        Show
        jbonofre Jean-Baptiste Onofré added a comment - Revision 1041297.

          People

          • Assignee:
            jbonofre Jean-Baptiste Onofré
            Reporter:
            ranger8214 Kurt Eisenzopf
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development