private static void verifyEncryptedTimestamp( AuthenticationContext authContext ) throws KerberosException,
InvalidTicketException
{
LOG_KRB.debug( "--> Verifying using encrypted timestamp." );
KerberosConfig config = authContext.getConfig();
KdcReq request = authContext.getRequest();
CipherTextHandler cipherTextHandler = authContext.getCipherTextHandler();
PrincipalStoreEntry clientEntry = authContext.getClientEntry();
String clientName = clientEntry.getPrincipal().getName();
EncryptionKey clientKey = null;
if ( clientEntry.getSamType() == null )
{
LOG_KRB.debug(
"Entry for client principal {} has no SAM type. Proceeding with standard pre-authentication.",
clientName );
EncryptionType encryptionType = authContext.getEncryptionType();
clientKey = clientEntry.getKeyMap().get( encryptionType );
if ( clientKey == null )
{
LOG_KRB.error( "No key for client {}", clientEntry.getDistinguishedName() );
throw new KerberosException( ErrorType.KDC_ERR_NULL_KEY );
}
if ( config.isPaEncTimestampRequired() )
{
List<PaData> preAuthData = request.getPaData();
if ( preAuthData == null )
{
LOG_KRB.debug( "PRE_AUTH required..." );
throw new KerberosException( ErrorType.KDC_ERR_PREAUTH_REQUIRED,
preparePreAuthenticationError( authContext.getEncryptionType(), config.getEncryptionTypes() ) );
}
PaEncTsEnc timestamp = null;
for ( PaData paData : preAuthData )
{
if ( paData.getPaDataType().equals( PaDataType.PA_ENC_TIMESTAMP ) )
{
EncryptedData dataValue = KerberosDecoder.decodeEncryptedData( paData.getPaDataValue() );
byte[] decryptedData = cipherTextHandler.decrypt( clientKey, dataValue,
KeyUsage.AS_REQ_PA_ENC_TIMESTAMP_WITH_CKEY );
timestamp = KerberosDecoder.decodePaEncTsEnc( decryptedData );
}
}
if ( timestamp == null )
{
LOG_KRB.error( "No timestamp found" );
throw new KerberosException( ErrorType.KDC_ERR_PREAUTH_REQUIRED,
preparePreAuthenticationError( authContext.getEncryptionType(), config.getEncryptionTypes() ) );
}
if ( !timestamp.getPaTimestamp().isInClockSkew( config.getAllowableClockSkew() ) )
{
LOG_KRB.error( "Timestamp not in delay" );
throw new KerberosException( ErrorType.KDC_ERR_PREAUTH_FAILED );
}