1 Reply Latest reply on Jul 18, 2018 3:33 PM by nephri

    [Wildfly 13] Writing an Elytron SecurityRealm handling SASL mechanisms like DIGEST-MD5 or SCRAM-SHA1

    nephri

      Hi,

       

      I'm wrote a SecurityRealm that handle authentication like this:

       

      public class TestRealm implements SecurityRealm {

       

         public SupportLevel getCredentialAcquireSupport(Class<? extends Credential> type, String algorithm, AlgorithmParameterSpec spec) throws RealmUnavailableException {

                return SupportLevel.UNSUPPORTED;

         }

       

         public SupportLevel getEvidenceVerifySupport(Class<? extends Evidence> type, String algorithm) throws RealmUnavailableException {

           if( !type.isAssignableFrom( PasswordGuessEvidence.class ) ) return SupportLevel.UNSUPPORTED;

           return SupportLevel.SUPPORTED;

         }

       

         public RealmIdentity getRealmIdentity(Principal principal) throws RealmUnavailableException {

            return new TestRealmIdentity( principal );

         }

       

         private static class TestRealmIdentity implements RealmIdentity {

       

          private      Principal principal                 = null;

       

          public TestRealmIdentity( Principal p ) {

               this.principal = p;

          }

       

          public Principal getRealmIdentityPrincipal() {

              return this.principal;

          }

       

          public boolean exists() throws RealmUnavailableException {

             if( this.principal == null )           return false;

             if( this.principal.getName() == null ) return false;

             return getExpectedSha1Password( this.principal ) != null;

          }

       

          public SupportLevel getCredentialAcquireSupport(Class<? extends Credential> type, String algorithm, AlgorithmParameterSpec spec) throws RealmUnavailableException {

             return SupportLevel.UNSUPPORTED;

          }

       

          public SupportLevel getEvidenceVerifySupport(Class<? extends Evidence> type, String algorithm) throws RealmUnavailableException {

             if( !type.isAssignableFrom( PasswordGuessEvidence.class ) )    return SupportLevel.UNSUPPORTED;

             return SupportLevel.SUPPORTED;

          }

       

          public <C extends Credential> C getCredential(Class<C> type) throws RealmUnavailableException {

            return null;

          }

       

          public boolean verifyEvidence(Evidence evidence) throws RealmUnavailableException {

              Principal p                    = this.principal;

              byte[]    expectedSha1Password = getExpectedSha1Password(p);

              System.out.println("Verify Password for " + ( p == null ? "null" : p.getName() ) );

       

             if( expectedSha1Password == null ) {

                 if( evidence instanceof PasswordGuessEvidence ) ((PasswordGuessEvidence)evidence).destroy();

                 return false;

             }

       

             if (evidence instanceof PasswordGuessEvidence) {

                 PasswordGuessEvidence guess = (PasswordGuessEvidence) evidence;

                 byte[]                sha1  = null;

                 try {

                      sha1  = sha1( guess.getGuess() );

                    

                      boolean result = Arrays.equals( expectedSha1Password ,  sha1 );

                      if( !result ) {

                           System.err.println("Password rejected for [" + p.getName() + "]");

                      }

                      return result;

                 }

                 finally {

                     guess.destroy();

                     if( sha1 != null ) Arrays.fill( sha1 , (byte) 0);

                 }

            }

            return false;

         }

       

         private String getExpectedSha1Password( Principal p ) {

             // IMPL

         }

       

         private byte[] sha1( byte[] plain ) {

             // IMPL

         }

      }

      }

       

      It works fine if we use the mechanism PLAIN.

      But when i try to use DIGEST-MD5, the authentication fails.

       

      I'm think i'm missing implementations about Credential acquire methods but i didn't really understand concepts in Credential and Evidence objetcs and Acquire vs Verify processes !

      Can you clarify the situation and providing a way to support theses SASL mechanism ?

       

      Thanks in advance,

      Best Regards,

      Sébastien.