You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2013/03/11 19:34:59 UTC
svn commit: r1455280 -
/directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java
Author: elecharny
Date: Mon Mar 11 18:34:59 2013
New Revision: 1455280
URL: http://svn.apache.org/r1455280
Log:
Fixed the way we select the Encryptiontype : we are now selecting the strongest algorithm
Modified:
directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java
Modified: directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java?rev=1455280&r1=1455279&r2=1455280&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java (original)
+++ directory/apacheds/trunk/kerberos-codec/src/main/java/org/apache/directory/shared/kerberos/KerberosUtils.java Mon Mar 11 18:34:59 2013
@@ -19,6 +19,7 @@
*/
package org.apache.directory.shared.kerberos;
+
import static org.apache.directory.shared.kerberos.codec.types.EncryptionType.DES3_CBC_MD5;
import static org.apache.directory.shared.kerberos.codec.types.EncryptionType.DES3_CBC_SHA1;
import static org.apache.directory.shared.kerberos.codec.types.EncryptionType.DES3_CBC_SHA1_KD;
@@ -87,24 +88,24 @@ public class KerberosUtils
* names in the descending order of strength
*/
private static final Map<String, String> cipherAlgoMap = new LinkedHashMap<String, String>();
-
+
public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
/** Defines a default date format with a "yyyyMMddHHmmss'Z'" pattern */
public static final SimpleDateFormat UTC_DATE_FORMAT = new SimpleDateFormat( "yyyyMMddHHmmss'Z'" );
private static final Set<EncryptionType> oldEncTypes = new HashSet<EncryptionType>();
-
+
static
{
UTC_DATE_FORMAT.setTimeZone( UTC_TIME_ZONE );
-
+
cipherAlgoMap.put( "rc4", "ArcFourHmac" );
cipherAlgoMap.put( "aes256", "AES256" );
cipherAlgoMap.put( "aes128", "AES128" );
cipherAlgoMap.put( "des3", "DESede" );
cipherAlgoMap.put( "des", "DES" );
-
+
oldEncTypes.add( DES_CBC_CRC );
oldEncTypes.add( DES_CBC_MD4 );
oldEncTypes.add( DES_CBC_MD5 );
@@ -120,7 +121,8 @@ public class KerberosUtils
oldEncTypes.add( RSAES_OAEP_ENV_OID );
oldEncTypes.add( RC4_HMAC );
}
-
+
+
/**
* Parse a KerberosPrincipal instance and return the names. The Principal name
* is described in RFC 1964 : <br/>
@@ -311,11 +313,12 @@ public class KerberosUtils
* @param configuredTypes The configured encryption types
* @return The first matching encryption type.
*/
- public static EncryptionType getBestEncryptionType( Set<EncryptionType> requestedTypes, Set<EncryptionType> configuredTypes )
+ public static EncryptionType getBestEncryptionType( Set<EncryptionType> requestedTypes,
+ Set<EncryptionType> configuredTypes )
{
- for ( EncryptionType encryptionType : requestedTypes )
+ for ( EncryptionType encryptionType : configuredTypes )
{
- if ( configuredTypes.contains( encryptionType ) )
+ if ( requestedTypes.contains( encryptionType ) )
{
return encryptionType;
}
@@ -376,39 +379,46 @@ public class KerberosUtils
public static String getAlgoNameFromEncType( EncryptionType encType )
{
String cipherName = encType.getName().toLowerCase();
-
- for( String c : cipherAlgoMap.keySet() )
+
+ for ( String c : cipherAlgoMap.keySet() )
{
if ( cipherName.startsWith( c ) )
{
return cipherAlgoMap.get( c );
}
}
-
+
throw new IllegalArgumentException( "Unknown algorithm name for the encryption type " + encType );
}
-
+
+ /**
+ * Order a list of EncryptionType in a decreasing strength order
+ *
+ * @param etypes The ETypes to order
+ * @return A list of ordered ETypes. he strongest is on the left.
+ */
public static Set<EncryptionType> orderEtypesByStrength( Set<EncryptionType> etypes )
{
Set<EncryptionType> ordered = new LinkedHashSet<EncryptionType>( etypes.size() );
-
- for( String algo : cipherAlgoMap.values() )
+
+ for ( String algo : cipherAlgoMap.values() )
{
- for( EncryptionType encType : etypes )
+ for ( EncryptionType encType : etypes )
{
String foundAlgo = getAlgoNameFromEncType( encType );
-
+
if ( algo.equals( foundAlgo ) )
{
ordered.add( encType );
}
}
}
-
+
return ordered;
}
+
/**
* Get a PrincipalStoreEntry given a principal. The ErrorType is used to indicate
* whether any resulting error pertains to a server or client.
@@ -417,7 +427,7 @@ public class KerberosUtils
throws KerberosException
{
PrincipalStoreEntry entry = null;
-
+
try
{
entry = store.getPrincipal( principal );
@@ -426,20 +436,21 @@ public class KerberosUtils
{
throw new KerberosException( errorType, e );
}
-
+
if ( entry == null )
{
throw new KerberosException( errorType );
}
-
+
if ( entry.getKeyMap() == null || entry.getKeyMap().isEmpty() )
{
throw new KerberosException( ErrorType.KDC_ERR_NULL_KEY );
}
-
+
return entry;
}
+
/**
* Verifies an AuthHeader using guidelines from RFC 1510 section A.10., "KRB_AP_REQ verification."
*
@@ -456,123 +467,127 @@ public class KerberosUtils
* @return The authenticator.
* @throws KerberosException
*/
- public static Authenticator verifyAuthHeader( ApReq authHeader, Ticket ticket, EncryptionKey serverKey,
- long clockSkew, ReplayCache replayCache, boolean emptyAddressesAllowed, InetAddress clientAddress,
- CipherTextHandler lockBox, KeyUsage authenticatorKeyUsage, boolean isValidate ) throws KerberosException
+ public static Authenticator verifyAuthHeader( ApReq authHeader, Ticket ticket, EncryptionKey serverKey,
+ long clockSkew, ReplayCache replayCache, boolean emptyAddressesAllowed, InetAddress clientAddress,
+ CipherTextHandler lockBox, KeyUsage authenticatorKeyUsage, boolean isValidate ) throws KerberosException
+ {
+ if ( authHeader.getProtocolVersionNumber() != KerberosConstants.KERBEROS_V5 )
{
- if ( authHeader.getProtocolVersionNumber() != KerberosConstants.KERBEROS_V5 )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_BADVERSION );
- }
-
- if ( authHeader.getMessageType() != KerberosMessageType.AP_REQ )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_MSG_TYPE );
- }
-
- if ( authHeader.getTicket().getTktVno() != KerberosConstants.KERBEROS_V5 )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_BADVERSION );
- }
-
- EncryptionKey ticketKey = null;
-
- if ( authHeader.getOption( ApOptions.USE_SESSION_KEY ) )
- {
- ticketKey = authHeader.getTicket().getEncTicketPart().getKey();
- }
- else
- {
- ticketKey = serverKey;
- }
-
- if ( ticketKey == null )
- {
- // TODO - check server key version number, skvno; requires store
- // if ( false )
- // {
- // throw new KerberosException( ErrorType.KRB_AP_ERR_BADKEYVER );
- // }
-
- throw new KerberosException( ErrorType.KRB_AP_ERR_NOKEY );
- }
-
- byte[] encTicketPartData = lockBox.decrypt( ticketKey, ticket.getEncPart(), KeyUsage.AS_OR_TGS_REP_TICKET_WITH_SRVKEY );
- EncTicketPart encPart = KerberosDecoder.decodeEncTicketPart( encTicketPartData );
- ticket.setEncTicketPart( encPart );
-
- byte[] authenticatorData = lockBox.decrypt( ticket.getEncTicketPart().getKey(), authHeader.getAuthenticator(), authenticatorKeyUsage );
-
- Authenticator authenticator = KerberosDecoder.decodeAuthenticator( authenticatorData );
-
- if ( !authenticator.getCName().getNameString().equals( ticket.getEncTicketPart().getCName().getNameString() ) )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_BADMATCH );
- }
-
- if ( ticket.getEncTicketPart().getClientAddresses() != null )
- {
- if ( !ticket.getEncTicketPart().getClientAddresses().contains( new HostAddress( clientAddress ) ) )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_BADADDR );
- }
- }
- else
+ throw new KerberosException( ErrorType.KRB_AP_ERR_BADVERSION );
+ }
+
+ if ( authHeader.getMessageType() != KerberosMessageType.AP_REQ )
+ {
+ throw new KerberosException( ErrorType.KRB_AP_ERR_MSG_TYPE );
+ }
+
+ if ( authHeader.getTicket().getTktVno() != KerberosConstants.KERBEROS_V5 )
+ {
+ throw new KerberosException( ErrorType.KRB_AP_ERR_BADVERSION );
+ }
+
+ EncryptionKey ticketKey = null;
+
+ if ( authHeader.getOption( ApOptions.USE_SESSION_KEY ) )
+ {
+ ticketKey = authHeader.getTicket().getEncTicketPart().getKey();
+ }
+ else
+ {
+ ticketKey = serverKey;
+ }
+
+ if ( ticketKey == null )
+ {
+ // TODO - check server key version number, skvno; requires store
+ // if ( false )
+ // {
+ // throw new KerberosException( ErrorType.KRB_AP_ERR_BADKEYVER );
+ // }
+
+ throw new KerberosException( ErrorType.KRB_AP_ERR_NOKEY );
+ }
+
+ byte[] encTicketPartData = lockBox.decrypt( ticketKey, ticket.getEncPart(),
+ KeyUsage.AS_OR_TGS_REP_TICKET_WITH_SRVKEY );
+ EncTicketPart encPart = KerberosDecoder.decodeEncTicketPart( encTicketPartData );
+ ticket.setEncTicketPart( encPart );
+
+ byte[] authenticatorData = lockBox.decrypt( ticket.getEncTicketPart().getKey(), authHeader.getAuthenticator(),
+ authenticatorKeyUsage );
+
+ Authenticator authenticator = KerberosDecoder.decodeAuthenticator( authenticatorData );
+
+ if ( !authenticator.getCName().getNameString().equals( ticket.getEncTicketPart().getCName().getNameString() ) )
+ {
+ throw new KerberosException( ErrorType.KRB_AP_ERR_BADMATCH );
+ }
+
+ if ( ticket.getEncTicketPart().getClientAddresses() != null )
+ {
+ if ( !ticket.getEncTicketPart().getClientAddresses().contains( new HostAddress( clientAddress ) ) )
{
- if ( !emptyAddressesAllowed )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_BADADDR );
- }
+ throw new KerberosException( ErrorType.KRB_AP_ERR_BADADDR );
}
-
- KerberosPrincipal serverPrincipal = getKerberosPrincipal( ticket.getSName(), ticket.getRealm() );
- KerberosPrincipal clientPrincipal = getKerberosPrincipal( authenticator.getCName(), authenticator.getCRealm() );
- KerberosTime clientTime = authenticator.getCtime();
- int clientMicroSeconds = authenticator.getCusec();
-
- if ( replayCache != null )
+ }
+ else
+ {
+ if ( !emptyAddressesAllowed )
{
- if ( replayCache.isReplay( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds ) )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_REPEAT );
- }
-
- replayCache.save( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds );
+ throw new KerberosException( ErrorType.KRB_AP_ERR_BADADDR );
}
-
- if ( !authenticator.getCtime().isInClockSkew( clockSkew ) )
+ }
+
+ KerberosPrincipal serverPrincipal = getKerberosPrincipal( ticket.getSName(), ticket.getRealm() );
+ KerberosPrincipal clientPrincipal = getKerberosPrincipal( authenticator.getCName(), authenticator.getCRealm() );
+ KerberosTime clientTime = authenticator.getCtime();
+ int clientMicroSeconds = authenticator.getCusec();
+
+ if ( replayCache != null )
+ {
+ if ( replayCache.isReplay( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds ) )
{
- throw new KerberosException( ErrorType.KRB_AP_ERR_SKEW );
+ throw new KerberosException( ErrorType.KRB_AP_ERR_REPEAT );
}
-
- /*
- * "The server computes the age of the ticket: local (server) time minus
- * the starttime inside the Ticket. If the starttime is later than the
- * current time by more than the allowable clock skew, or if the INVALID
- * flag is set in the ticket, the KRB_AP_ERR_TKT_NYV error is returned."
- */
- KerberosTime startTime = ( ticket.getEncTicketPart().getStartTime() != null ) ? ticket.getEncTicketPart().getStartTime() : ticket.getEncTicketPart().getAuthTime();
-
- KerberosTime now = new KerberosTime();
- boolean isValidStartTime = startTime.lessThan( now );
-
- if ( !isValidStartTime || ( ticket.getEncTicketPart().getFlags().isInvalid() && !isValidate ) )
- {
- // it hasn't yet become valid
- throw new KerberosException( ErrorType.KRB_AP_ERR_TKT_NYV );
- }
-
- // TODO - doesn't take into account skew
- if ( !ticket.getEncTicketPart().getEndTime().greaterThan( now ) )
- {
- throw new KerberosException( ErrorType.KRB_AP_ERR_TKT_EXPIRED );
- }
-
- authHeader.getApOptions().set( ApOptions.MUTUAL_REQUIRED );
-
- return authenticator;
+
+ replayCache.save( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds );
+ }
+
+ if ( !authenticator.getCtime().isInClockSkew( clockSkew ) )
+ {
+ throw new KerberosException( ErrorType.KRB_AP_ERR_SKEW );
}
+ /*
+ * "The server computes the age of the ticket: local (server) time minus
+ * the starttime inside the Ticket. If the starttime is later than the
+ * current time by more than the allowable clock skew, or if the INVALID
+ * flag is set in the ticket, the KRB_AP_ERR_TKT_NYV error is returned."
+ */
+ KerberosTime startTime = ( ticket.getEncTicketPart().getStartTime() != null ) ? ticket.getEncTicketPart()
+ .getStartTime() : ticket.getEncTicketPart().getAuthTime();
+
+ KerberosTime now = new KerberosTime();
+ boolean isValidStartTime = startTime.lessThan( now );
+
+ if ( !isValidStartTime || ( ticket.getEncTicketPart().getFlags().isInvalid() && !isValidate ) )
+ {
+ // it hasn't yet become valid
+ throw new KerberosException( ErrorType.KRB_AP_ERR_TKT_NYV );
+ }
+
+ // TODO - doesn't take into account skew
+ if ( !ticket.getEncTicketPart().getEndTime().greaterThan( now ) )
+ {
+ throw new KerberosException( ErrorType.KRB_AP_ERR_TKT_EXPIRED );
+ }
+
+ authHeader.getApOptions().set( ApOptions.MUTUAL_REQUIRED );
+
+ return authenticator;
+ }
+
+
/**
* checks if the given encryption type is *new* (ref sec#3.1.3 of rfc4120)
*
@@ -583,7 +598,7 @@ public class KerberosUtils
{
return !oldEncTypes.contains( eType );
}
-
+
/**
* Verifies an AuthHeader using guidelines from RFC 1510 section A.10., "KRB_AP_REQ verification."
*