/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed 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 io.undertow.server.security;
import io.undertow.testutils.category.UnitTest;
import io.undertow.security.idm.DigestAlgorithm;
import io.undertow.security.impl.DigestAuthorizationToken;
import io.undertow.security.impl.DigestQop;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.util.EnumMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
/**
* Test case to test the parsing of the Authorization header for Digest requests.
*
* The RFC defines which values are quoted and which ones are not, however different implementations interpret this differently.
* This test case tests different headers generated by supported browsers.
*
* Ordering of the values is not important, however the construction of the Map of expected values does match the header being
* tested for readability.
*
* @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a>
*/
@Category(UnitTest.class)
public class ParseDigestAuthorizationTokenTestCase {
private void doTest(final String header, final Map<DigestAuthorizationToken, String> expected) {
Map<DigestAuthorizationToken, String> parsedHeader = DigestAuthorizationToken.parseHeader(header);
assertEquals(expected, parsedHeader);
}
@Test
public void testChrome_22() {
final String header = "username=\"userTwo\", realm=\"Digest_Realm\", nonce=\"Yxmkh5liIOYNMTM1MTUyNjQzMTE4NJziT7YLEOEJ4QEN1py4Yog=\", uri=\"/\", algorithm=MD5, response=\"5b26e00233607e8a714cd1d910692e08\", opaque=\"00000000000000000000000000000000\", qop=auth, nc=00000001, cnonce=\"8c008c8ce43dc0a7\"";
Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class);
expected.put(DigestAuthorizationToken.USERNAME, "userTwo");
expected.put(DigestAuthorizationToken.REALM, "Digest_Realm");
expected.put(DigestAuthorizationToken.NONCE, "Yxmkh5liIOYNMTM1MTUyNjQzMTE4NJziT7YLEOEJ4QEN1py4Yog=");
expected.put(DigestAuthorizationToken.DIGEST_URI, "/");
expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken());
expected.put(DigestAuthorizationToken.RESPONSE, "5b26e00233607e8a714cd1d910692e08");
expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000");
expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken());
expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001");
expected.put(DigestAuthorizationToken.CNONCE, "8c008c8ce43dc0a7");
doTest(header, expected);
}
@Test
public void testCurl_7() {
final String header = "username=\"userTwo\", realm=\"Digest_Realm\", nonce=\"5CgZ39vhie0NMTM1MTUyNDc4ODkwNMwr6sWKVSGfhXB4jBtkupY=\", uri=\"/\", cnonce=\"MTYwOTQ4\", nc=00000001, qop=\"auth\", response=\"c3c1ce9945a0c36d54860eda7846018b\", opaque=\"00000000000000000000000000000000\", algorithm=\"MD5\"";
Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class);
expected.put(DigestAuthorizationToken.USERNAME, "userTwo");
expected.put(DigestAuthorizationToken.REALM, "Digest_Realm");
expected.put(DigestAuthorizationToken.NONCE, "5CgZ39vhie0NMTM1MTUyNDc4ODkwNMwr6sWKVSGfhXB4jBtkupY=");
expected.put(DigestAuthorizationToken.DIGEST_URI, "/");
expected.put(DigestAuthorizationToken.CNONCE, "MTYwOTQ4");
expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001");
expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken());
expected.put(DigestAuthorizationToken.RESPONSE, "c3c1ce9945a0c36d54860eda7846018b");
expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000");
expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken());
doTest(header, expected);
}
@Test
public void testFirefox_16() {
final String header = "username=\"userOne\", realm=\"Digest_Realm\", nonce=\"nBhFxtSS6rkNMTM1MTUyNjE2MjgyNWA/xW/LOH53vhXGq/2B/yQ=\", uri=\"/\", algorithm=MD5, response=\"b0adb1025da2de0d16f44131858bad6f\", opaque=\"00000000000000000000000000000000\", qop=auth, nc=00000001, cnonce=\"8127726535363b07\"";
Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class);
expected.put(DigestAuthorizationToken.USERNAME, "userOne");
expected.put(DigestAuthorizationToken.REALM, "Digest_Realm");
expected.put(DigestAuthorizationToken.NONCE, "nBhFxtSS6rkNMTM1MTUyNjE2MjgyNWA/xW/LOH53vhXGq/2B/yQ=");
expected.put(DigestAuthorizationToken.DIGEST_URI, "/");
expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken());
expected.put(DigestAuthorizationToken.RESPONSE, "b0adb1025da2de0d16f44131858bad6f");
expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000");
expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken());
expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001");
expected.put(DigestAuthorizationToken.CNONCE, "8127726535363b07");
doTest(header, expected);
}
@Test
public void testOpera_12() {
final String header = "username=\"userOne\", realm=\"Digest_Realm\", uri=\"/\", algorithm=MD5, nonce=\"D2floAc+FhkNMTM1MTUyMzY2ODc4Mhbi2Zrcuv1lvdgEaPXa+bg=\", cnonce=\"v722VYJEeG28C3SoXS8BEWThGHPDOlXgUCCts70i7Fc=\", opaque=\"00000000000000000000000000000000\", qop=auth, nc=00000001, response=\"8106a5d19bc67982527cbb576658f9d6\"";
Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class);
expected.put(DigestAuthorizationToken.USERNAME, "userOne");
expected.put(DigestAuthorizationToken.REALM, "Digest_Realm");
expected.put(DigestAuthorizationToken.DIGEST_URI, "/");
expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken());
expected.put(DigestAuthorizationToken.NONCE, "D2floAc+FhkNMTM1MTUyMzY2ODc4Mhbi2Zrcuv1lvdgEaPXa+bg=");
expected.put(DigestAuthorizationToken.CNONCE, "v722VYJEeG28C3SoXS8BEWThGHPDOlXgUCCts70i7Fc=");
expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000");
expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken());
expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001");
expected.put(DigestAuthorizationToken.RESPONSE, "8106a5d19bc67982527cbb576658f9d6");
doTest(header, expected);
}
}