in redback-integrations/redback-common-integrations/src/main/java/org/apache/archiva/redback/integration/filter/authentication/digest/HttpDigestHeader.java [62:147]
public void parseClientHeader( String rawHeader, String expectedRealm, String digestKey )
throws HttpAuthenticationException
{
Properties authHeaderProps = HttpUtils.complexHeaderToProperties( rawHeader, ",", "=" );
username = authHeaderProps.getProperty( "username" );
realm = authHeaderProps.getProperty( "realm" );
nonce = authHeaderProps.getProperty( "nonce" );
uri = authHeaderProps.getProperty( "uri" );
response = authHeaderProps.getProperty( "response" );
qop = authHeaderProps.getProperty( "qop" );
nc = authHeaderProps.getProperty( "nc" );
cnonce = authHeaderProps.getProperty( "cnonce" );
// [RFC 2067] Validate all required values
if ( StringUtils.isEmpty( username ) || StringUtils.isEmpty( realm ) || StringUtils.isEmpty( nonce )
|| StringUtils.isEmpty( uri ) || StringUtils.isEmpty( response ) )
{
log.debug( "Missing mandatory fields: Raw Digest Header : [{}]", rawHeader );
throw new HttpAuthenticationException( "Missing mandatory digest fields per RFC2069." );
}
// [RFC 2617] Validate realm.
if ( !StringUtils.equals( expectedRealm, realm ) )
{
log.debug( "Realm name is invalid: expected [{}] but got [{}]", expectedRealm, realm );
throw new HttpAuthenticationException( "Response realm does not match expected realm." );
}
// [RFC 2617] Validate "auth" qop
if ( StringUtils.equals( "auth", qop ) )
{
if ( StringUtils.isEmpty( nc ) || StringUtils.isEmpty( cnonce ) )
{
log.debug( "Missing mandatory qop fields: nc [{}] cnonce [{}]", nc, cnonce );
throw new HttpAuthenticationException( "Missing mandatory qop digest fields per RFC2617." );
}
}
// [RFC 2617] Validate nonce
if ( !Base64.isBase64( nonce.getBytes() ) )
{
log.debug( "Nonce is not encoded in Base64: nonce [{}]", nonce );
throw new HttpAuthenticationException( "Response nonce is not encoded in Base64." );
}
// Decode nonce
String decodedNonce = new String( Base64.decodeBase64( nonce.getBytes() ) );
String nonceTokens[] = StringUtils.split( decodedNonce, ":" );
// Validate nonce format
if ( nonceTokens.length != 2 )
{
log.debug( "Nonce format expected [2] elements, but got [{}] instead. Decoded nonce [{}]",
nonceTokens.length, decodedNonce );
throw new HttpAuthenticationException(
"Nonce format is invalid. " + "Received an unexpected number of sub elements." );
}
// Extract nonce timestamp
long nonceTimestamp = 0;
try
{
nonceTimestamp = Long.parseLong( nonceTokens[0] );
}
catch ( NumberFormatException e )
{
throw new HttpAuthenticationException( "Unexpected nonce timestamp." );
}
// Extract nonce signature
String expectedSignature = Digest.md5Hex( nonceTimestamp + ":" + digestKey );
if ( !StringUtils.equals( expectedSignature, nonceTokens[1] ) )
{
log.error( "Nonce parameter has been compromised." );
throw new HttpAuthenticationException( "Nonce parameter has been compromised." );
}
}