<commit_before>/* This file is part of the University of Cambridge Web Authentication
 * System Java Toolkit
 *
 * Copyright 2005 University of Cambridge
 *
 * This toolkit is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * The toolkit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this toolkit; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * $Id: WebauthValidatorTest.java,v 1.9 2005/03/31 15:06:55 jw35 Exp $
 *
 */

package uk.ac.cam.ucs.webauth;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.ParseException;

import junit.framework.TestCase;

public class WebauthValidatorTest extends TestCase {

	// private static int TEST_TIMEOUT = 30000;
	// private static int TEST_MAX_SKEW = 0;

	private static final String RESPONSE_V2_FIRSTHAND = "2!200!!20050317T151310Z!1111072390-26663-9!http://raven.cam.ac.uk/d"
			+ "ebug.html!jw35!pwd!!36000!For babies!2!r9LDRfDhqaOXLWo3ERATEhzCsRFv"
			+ "PDmRP2krjGjUylpkh9rdnK1knnf1z8P4JWDVQxsMKilnXfPZ-D9G-arghDd-Hgr9JTC"
			+ "gnbttwikvL.yYAHvUCnhBY75QCRmBPZ1iQQcKdh2gzxX-HsJhmZ4uTn0vce4IlLFdQL"
			+ "CbALj1nqw_";

	private static final String RESPONSE_V2_SSO = "2!200!!20050317T151424Z!1111072462-26473-5!http://raven.cam.ac.uk/d"
			+ "ebug.html!jw35!!pwd!3<PASSWORD>!For babies!2!aCwEktN6X7A-.mloMNOhsfaMbsgM"
			+ "z9TxpZ2D9yLt-0XMP8K-9VKttn1Ot.-dkpoEE2TbXt0mJE5y4udjv-Qo4EjtaZxTcUB"
			+ "lqaRwFcZGR3C2GoQeUWQaHHJdvRi2MwglnbTP6m7sT-o6Xlvnt3RcTgf-ncrkdFN.vN"
			+ "ShVM1RhyU_";

	private static final String RESPONSE_V1 = "1!200!!20050317T151538Z!1111072536-26473-6!http://raven.cam.ac.uk/d"
			+ "ebug.html!jw35!!pwd!3<PASSWORD>!For babies!2!Xmm01Vu95g3t2iKCF.QkrTOCEkfz"
			+ "QWpEsC90u5s8o5o9EYrrUljMAQMo0S-wxpdH4zXQWRfeS.rjk4-YWEbcr1qjzKm14.b"
			+ "6iYP6rEagaHK1CCkL-V.8lUzWFjB3MacvJtfu1nP0-pw.kzP6ERIfMEYMEW37aReRSt"
			+ "0LEnDJkO4_";

	private static final String RESPONSE_ERROR = "1!530!Missing required parameter 'ver'!20050317T151628Z!1111072588-"
			+ "26568-7!http://raven.cam.ac.uk/debug.html!!!!!!2!ZUcFzGfEPyVhYqHYK9"
			+ "gDfewP6xSOKNvdOcAp3ZpzGoDAmY1eG704aw1aDTOh6nTYtZAoGNqio33CCGWT29fjY"
			+ "10phtSEe8xCNP9WgpohOze9SOYUXJ10uuVRXBXE.1DCiCPZxUODZPEaeOv8P0zgm3Jf"
			+ "RsVdDy9SnDjFvQQ43O8_";

	private static final String RESPONSE_SUMMER = "2!200!!20050331T145628Z!1112280988-1756-8!http://raven.cam.ac.uk/de"
			+ "bug.html!jw35!pwd!!36000!!2!EpqdT4YZLfn-YtE8QA2bg0i1rnAXO9v5dTjiFgD"
			+ "k9.C5XJ99D4KR9WOZniHzkaE79vSLeW-OqtM1Up6RXXap.1hWLH3Mk5ZKhulh1KSRE3"
			+ "b2raTUqwx5smqnNVGgY0mA9VSTpGM4mJ7rGm5Hkh1aDsOSNiQ0XL6sm8EwsfcKoSI_";

	// The signatures on the following won't validate

	private static final String RESPONSE_FORGED = "2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!jw99!pwd!!<PASSWORD>!<PASSWORD>!2!VB4vcoeQSln<PASSWORD>JGT7RauhLna"
			+ "<KEY>"
			+ "<KEY>.<KEY>"
			+ "XwoRn4f.lXtU_";

	private static final String MISS_VER = "!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>!2!VB4vcoeQSln6SKJGT7RauhLna"
			+ "<KEY>"
			+ "<KEY>.<KEY>"
			+ "XwoRn4f.lXtU_";

	private static final String BAD_VER = "A!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>!<PASSWORD>h<PASSWORD>"
			+ "<KEY>"
			+ "C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.<KEY>"
			+ "XwoRn4f.lXtU_";

	private static final String MISS_STATUS = "2!!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>coe<PASSWORD>"
			+ "<KEY>"
			+ "<KEY>"
			+ "XwoRn4f.lXtU_";

	private static final String SMALL_STATUS = "2!1!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>!2!VB4vcoeQSln6SKJGT7RauhLna"
			+ "aVmNBtWZ8Ra5tzYv0-0GRNHBxrZxQK9SNwg0lw3eV6SPyWbDJwjSlgNAh9FvOVzxjOx"
			+ "C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq"
			+ "XwoRn4f.lXtU_";

	private static final String MISS_ID = "2!200!!20050314T140111Z!!http://raven.cam.ac.u"
			+ "k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>"
			+ "<KEY>"
			+ "C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq"
			+ "XwoRn4f.lXtU_";

	private static final String MISS_URL = "2!200!!20050314T140111Z!1110808871-12726-166!"
			+ "!jw35!pwd!!<PASSWORD>!<PASSWORD>!2!<PASSWORD>"
			+ "<KEY>"
			+ "C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq"
			+ "XwoRn4f.lXtU_";

	private static final String MISS_PRINCIPAL = "2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!!pwd!!36000!Foo babies!2!VB4vcoeQSln6SKJGT7RauhLna"<commit_msg>I had a merge conflict with this file so I've chosen the version with more tests in it....<commit_after>/* This file is part of the University of Cambridge Web Authentication
 * System Java Toolkit
 *
 * Copyright 2005 University of Cambridge
 *
 * This toolkit is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * The toolkit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this toolkit; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * $Id: WebauthValidatorTest.java,v 1.9 2005/03/31 15:06:55 jw35 Exp $
 *
 */

package uk.ac.cam.ucs.webauth;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.ParseException;
import java.util.TimeZone;

import junit.framework.TestCase;

public class WebauthValidatorTest extends TestCase {

    private static int TEST_TIMEOUT = 30000;
    private static int TEST_MAX_SKEW = 0;

    private static final String RESPONSE_V2_FIRSTHAND = 
	"2!200!!20050317T151310Z!1111072390-26663-9!http://raven.cam.ac.uk/d" +
	"ebug.html!jw35!pwd!!3<PASSWORD>!For babies!2!r9LDRfDhqaOXLWo3ERATEhzCsRFv" +
	"PDmRP2krjGjUylpkh9rdnK1knnf1z8P4JWDVQxsMKilnXfPZ-D9G-arghDd-Hgr9JTC" +
	"gnbttwikvL.yYAHvUCnhBY75QCRmBPZ1iQQcKdh2gzxX-HsJhmZ4uTn0vce4IlLFdQL" +
	"CbALj1nqw_";

    private static final String RESPONSE_V2_SSO =
	"2!200!!20050317T151424Z!1111072462-26473-5!http://raven.cam.ac.uk/d" +
	"ebug.html!jw35!!pwd!35<PASSWORD>!For babies!2!aCwEktN6X7A-.mloMNOhsfaMbsgM" +
	"z9TxpZ2D9yLt-0XMP8K-9VKttn1Ot.-dkpoEE2TbXt0mJE5y4udjv-Qo4EjtaZxTcUB" +
	"lqaRwFcZGR3C2GoQeUWQaHHJdvRi2MwglnbTP6m7sT-o6Xlvnt3RcTgf-ncrkdFN.vN" +
	"ShVM1RhyU_";

    private static final String RESPONSE_V1 =
	"1!200!!20050317T151538Z!1111072536-26473-6!http://raven.cam.ac.uk/d" +
	"ebug.html!jw35!!pwd!35854!For babies!2!Xmm01Vu95g3t2iKCF.QkrTOCEkfz" +
	"QWpEsC90u5s8o5o9EYrrUljMAQMo0S-wxpdH4zXQWRfeS.rjk4-YWEbcr1qjzKm14.b" +
	"6iYP6rEagaHK1CCkL-V.8lUzWFjB3MacvJtfu1nP0-pw.kzP6ERIfMEYMEW37aReRSt" +
	"0LEnDJkO4_";

    private static final String RESPONSE_ERROR =
	"1!530!Missing required parameter 'ver'!20050317T151628Z!1111072588-" +
	"26568-7!http://raven.cam.ac.uk/debug.html!!!!!!2!ZUcFzGfEPyVhYqHYK9" +
	"gDfewP6xSOKNvdOcAp3ZpzGoDAmY1eG704aw1aDTOh6nTYtZAoGNqio33CCGWT29fjY" +
	"10phtSEe8xCNP9WgpohOze9SOYUXJ10uuVRXBXE.1DCiCPZxUODZPEaeOv8P0zgm3Jf" +
	"RsVdDy9SnDjFvQQ43O8_";

    private static final String RESPONSE_SUMMER = 
        "2!200!!20050331T145628Z!1112280988-1756-8!http://raven.cam.ac.uk/de" +
	"bug.html!jw35!pwd!!36000!!2!EpqdT4YZLfn-YtE8QA2bg0i1rnAXO9v5dTjiFgD" +
	"k9.C5XJ99D4KR9WOZniHzkaE79vSLeW-OqtM1Up6RXXap.1hWLH3Mk5ZKhulh1KSRE3" +
	"b2raTUqwx5smqnNVGgY0mA9VSTpGM4mJ7rGm5Hkh1aDsOSNiQ0XL6sm8EwsfcKoSI_";

    // The signatures on the following won't validate

    private static final String RESPONSE_FORGED = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw99!pwd!!<PASSWORD>!<PASSWORD>!2!VB4vcoeQSln6SKJGT7RauhLna" +
	"aVmNBtWZ8Ra5tzYv0-0GRNHBxrZxQK9SNwg0lw3eV6SPyWbDJwjSlgNAh9FvOVzxjOx" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";

    private static final String MISS_VER = 
	"!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!<PASSWORD>!<PASSWORD>!!<PASSWORD>!<PASSWORD>" +
	"aVmNBtWZ8Ra5tzYv0-0GRNHBxrZxQK9SNwg0lw3eV6SPyWbDJwjSlgNAh9FvOVzxjOx" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";
    
    private static final String BAD_VER = 
	"A!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>!VB4vcoeQSln6SKJGT7Rauh<PASSWORD>" +
	"<KEY>" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";

    private static final String MISS_STATUS = 
	"2!!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>!VB4vcoeQSln6SKJGT7RauhLna" +
	"aVmNBtWZ8Ra5tzYv0-0GRNHB<KEY>" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";
    
    private static final String SMALL_STATUS = 
	"2!1!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!<PASSWORD>!pwd!!<PASSWORD>!<PASSWORD>!2!VB<PASSWORD>" +
	"<KEY>" +
	"<KEY>.<KEY>" +
	"XwoRn4f.lXtU_";
    
    private static final String MISS_ID = 
	"2!200!!20050314T140111Z!!http://raven.cam.ac.u" +
	"k/debug.html!<PASSWORD>!pwd!!<PASSWORD>!<PASSWORD>!2!VB4vcoeQSln<PASSWORD>" +
	"<KEY>" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-<KEY>UDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";

    private static final String MISS_URL = 
	"2!200!!20050314T140111Z!1110808871-12726-166!" +
	"!jw35!pwd!!<PASSWORD>!<PASSWORD>!<PASSWORD>" +
	"<KEY>" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.<KEY>" +
	"XwoRn4f.lXtU_";

    private static final String MISS_PRINCIPAL = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!!pwd!!<PASSWORD>!<PASSWORD>!2!VB4vcoeQSln6SKJGT7RauhLna" +
	"<KEY>" +
	"<KEY>.<KEY>" +
	"XwoRn4f.lXtU_";

    private static final String NO_AUTH_SSO = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw35!!!36000!Foo babies!2!VB4vcoeQSln6SKJGT7RauhLna" +
	"aVmNBtWZ8Ra5tzYv0-0GRNHBxrZxQK9SNwg0lw3eV6SPyWbDJwjSlgNAh9FvOVzxjOx" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";
    
    private static final String BAD_AUTH_SSO = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw35!pw!pw!36000!Foo babies!2!VB4vcoeQSln6SKJGT7RauhLna" +
	"aVmNBtWZ8Ra5tzYv0-0GRNHBxrZxQK9SNwg0lw3eV6SPyWbDJwjSlgNAh9FvOVzxjOx" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";

    private static final String MISS_KID = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw35!pwd!!36000!Foo babies!!VB4vcoeQSln6SKJGT7RauhLna" +
	"<KEY>" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";

    private static final String BAD_KID = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!jw35!pwd!!<PASSWORD>!<PASSWORD>!3!VB4vcoeQSln<PASSWORD>auh<PASSWORD>" +
	"<KEY>" +
	"C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq" +
	"XwoRn4f.lXtU_";

    private static final String MISS_SIG = 
	"2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u" +
	"k/debug.html!<PASSWORD>!pwd!!<PASSWORD>!<PASSWORD>!2!";

    private WebauthRequest   request;
    private WebauthResponse  response_v2_firsthand, response_v2_sso,
	response_v1, response_error, response_forged, response_summer;
    private long response_v2_firsthand_date, response_v2_sso_date,
	response_v1_date, response_error_date, response_forged_date,
	response_summer_date;
    private WebauthValidator validator;

    // ----------------------------------------------------------- Housekeeping
	
    public static void main(String args[]) {
	junit.textui.TestRunner.run(WebauthValidatorTest.class);
    }

    // --------------------------------------------------------------- Fixtures

    @Override
    protected void setUp()
	throws WebauthException, MalformedURLException, ParseException, 
	       KeyStoreException, FileNotFoundException, IOException,
	       NoSuchAlgorithmException, CertificateException {

      // These tests fail if done not in the Europe/London timezone
      TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
	// A request

	request = new WebauthRequest();
	request.set("ver",2);
	request.set("url","http://raven.cam.ac.uk/debug.html");

	// Some responses 

	response_v2_firsthand = new WebauthResponse(RESPONSE_V2_FIRSTHAND);
	response_v2_firsthand_date = response_v2_firsthand.getDate("issue");

	response_v2_sso = new WebauthResponse(RESPONSE_V2_SSO);
	response_v2_sso_date = response_v2_sso.getDate("issue");

	response_v1 = new WebauthResponse(RESPONSE_V1);
	response_v1_date = response_v1.getDate("issue");

	response_error = new WebauthResponse(RESPONSE_ERROR);
	response_error_date = response_error.getDate("issue");

	response_forged = new WebauthResponse(RESPONSE_FORGED);
	response_forged_date = response_forged.getDate("issue");
	 
	response_summer = new WebauthResponse(RESPONSE_SUMMER);
	response_summer_date = response_summer.getDate("issue");


	// A key store and a validator using it

	KeyStore ks = KeyStore.getInstance("JKS");
	ks.load(this.getClass().getResourceAsStream("/keystore"),
		"keystore password".toCharArray());
	validator = new WebauthValidator(ks);

    }

    @Override
    protected void tearDown() {
      TimeZone.setDefault(null);// Undo the change we did in setup (hopefully)
    }

    // ----------------------------------------------------------------- Tests

    // Note that passing WebauthResponse.get("ssue") as a date to
    // validate is normally a silly thing to do (you want to pass the
    // current date/time) but it's useful here becasue it means we can
    // run tests with response messages that were actually created
    // some time ago...

    public void testV2Date() {
	assertEquals(response_v2_firsthand_date, 1111072390000L);
    }

    public void testSummerDate() {
	assertEquals(response_summer_date, 1112280988000L);
    }

    // Basic tests - accept a valid response, reject a forged one

    public void testDefaults() {
	assertEquals(30000,validator.getTimeout());
	assertEquals(500,validator.getMaxSkew());
	assertEquals("webauth-pubkey",validator.getKeyPrefix());
    }

    public void testBasic() throws WebauthException {
	validator.validate(request, 
			   response_v2_firsthand, 
			   response_v2_firsthand_date);
    }

	private static final String MISS_URL = "2!200!!20050314T140111Z!1110808871-12726-166!"
			+ "!jw35!pwd!!<PASSWORD>"
			+ "aVmNBtWZ8Ra5tzYv0-0GRNHBxrZxQK9SNwg0lw3eV6SPyWbDJwjSlgNAh9FvOVzxjOx"
			+ "C30SgS8802dPjqnratjAKDqZBfBv004pslSdWsoE-CiHfAXAMUDzE9I.TH-RCKkqtMq"
			+ "XwoRn4f.lXtU_";

	private static final String MISS_PRINCIPAL = "2!200!!20050314T140111Z!1110808871-12726-166!http://raven.cam.ac.u"
			+ "k/debug.html!!pwd!!3<PASSWORD>!Foo <PASSWORD>!2!VB<PASSWORD>"
{'fraction_non_alphanumeric': 0.1319580078125, 'fraction_numerical': 0.11651611328125, 'mean_word_length': 5.2158573596358115, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2141548', 'n_tokens_mistral': 8782, 'n_tokens_neox': 7511, 'n_words': 926}