blob: 7cf12b545c934725f22624efa49446097f277f0d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* @author Alexander V. Astapchuk
* @version $Revision$
*/
package org.apache.harmony.security.tests.java.security;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import java.io.File;
import java.net.URL;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
import org.apache.harmony.security.tests.support.TestCertUtils;
import junit.framework.TestCase;
@TestTargetClass(CodeSource.class)
/**
* Unit test for CodeSource.
*
*/
public class CodeSourceTest extends TestCase {
private java.security.cert.Certificate[] chain = null;
/* Below are various URLs used during the testing */
private static URL urlSite;
private static URL urlDir; // must NOT end with '/'
private static URL urlDirOtherSite; // same as urlDir, but another site
private static URL urlDir_port80, urlDir_port81;
/* must be exactly the same as urlDir, but with slash added */
private static URL urlDirWithSlash;
//private static URL urlDirFtp;
private static URL urlDir_FileProtocol;
private static URL urlDirIP;
private static URL urlFile, urlFileWithAdditionalDirs, urlFileDirOtherDir;
private static URL urlFileDirMinus;
private static URL urlFileDirStar;
private static URL urlRef1, urlRef2;
private boolean init = false;
private void init() {
if (!init) {
try {
String siteName = "www.intel.com";
InetAddress addr = InetAddress.getByName(siteName);
String siteIP = addr.getHostAddress();
urlSite = new URL("http://"+siteName+"");
urlDir = new URL("http://"+siteName+"/drl_test");
urlDirOtherSite = new URL("http://www.any-other-site-which-is-not-siteName.com/drl_test");
urlDir_port80 = new URL("http://"+siteName+":80/drl_test");
urlDir_port81 = new URL("http://"+siteName+":81/drl_test");
urlDirWithSlash = new URL(urlDir + "/");
//urlDirFtp = new URL("ftp://www.intel.com/drl_test");
urlDir_FileProtocol = new URL("file://"+siteName+"/drl_test");
urlDirIP = new URL("http://"+siteIP+"/drl_test");
urlFile = new URL("http://"+siteName+"/drl_test/empty.jar");
urlFileWithAdditionalDirs = new URL(
"http://"+siteName+"/drl_test/what/ever/here/empty.jar");
urlFileDirMinus = new URL("http://"+siteName+"/drl_test/-");
urlFileDirStar = new URL("http://"+siteName+"/drl_test/*");
urlFileDirOtherDir = new URL("http://"+siteName+"/_test_drl_/*");
urlRef1 = new URL("http://"+siteName+"/drl_test/index.html#ref1");
urlRef2 = new URL("http://"+siteName+"/drl_test/index.html#ref2");
} catch (MalformedURLException ex) {
throw new Error(ex);
} catch (UnknownHostException ex) {
throw new Error(ex);
} finally {
init = true;
}
}
}
protected void setUp() throws Exception {
super.setUp();
init();
chain = TestCertUtils.getCertChain();
}
/**
* Tests hashCode().<br>
* javadoc says nothing, so test DRL-specific implementation.
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "hashCode",
args = {}
)
public void testHashCode() {
// when nothing is specified, then hashCode obviously must be 0.
assertTrue(new CodeSource(null, (Certificate[]) null).hashCode() == 0);
// only URL.hashCode is taken into account...
assertTrue(new CodeSource(urlSite, (Certificate[]) null).hashCode() == urlSite
.hashCode());
// ... and certs[] does not affect it
assertTrue(new CodeSource(urlSite, chain).hashCode() == urlSite
.hashCode());
}
/**
* Tests CodeSource(URL, Certificate[]).
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "CodeSource",
args = {java.net.URL.class, java.security.cert.Certificate[].class}
)
public void testCodeSourceURLCertificateArray() {
new CodeSource(null, (Certificate[]) null);
new CodeSource(urlSite, (Certificate[]) null);
new CodeSource(null, chain);
new CodeSource(urlSite, chain);
}
/**
* Tests CodeSource(URL, CodeSigner[]).
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Verifies method with null parameters only",
method = "CodeSource",
args = {java.net.URL.class, java.security.CodeSigner[].class}
)
public void testCodeSourceURLCodeSignerArray() {
if (!has_15_features()) {
return;
}
new CodeSource(null, (CodeSigner[]) null);
}
/**
* equals(Object) must return <code>false</code> for null
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Null parameter checked",
method = "equals",
args = {java.lang.Object.class}
)
public void testEqualsObject_00() {
CodeSource thiz = new CodeSource(urlSite, (Certificate[]) null);
assertFalse(thiz.equals(null));
}
/**
* equals(Object) must return <code>true</code> for the same object
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Same objects checked",
method = "equals",
args = {java.lang.Object.class}
)
public void testEqualsObject_01() {
CodeSource thiz = new CodeSource(urlSite, (Certificate[]) null);
assertTrue(thiz.equals(thiz));
}
/**
* Test for equals(Object)<br>
* The signer certificate chain must contain the same set of certificates, but
* the order of the certificates is not taken into account.
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "equals",
args = {java.lang.Object.class}
)
public void testEqualsObject_02() {
Certificate cert0 = new TestCertUtils.TestCertificate();
Certificate cert1 = new TestCertUtils.TestCertificate();
Certificate[] certs0 = new Certificate[] { cert0, cert1 };
Certificate[] certs1 = new Certificate[] { cert1, cert0 };
CodeSource thiz = new CodeSource(urlSite, certs0);
CodeSource that = new CodeSource(urlSite, certs1);
assertTrue(thiz.equals(that));
}
/**
* Test for equals(Object)<br>
* Checks that both 'null' and not-null URLs are taken into account - properly.
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "equals",
args = {java.lang.Object.class}
)
public void testEqualsObject_04() {
CodeSource thiz = new CodeSource(urlSite, (Certificate[]) null);
CodeSource that = new CodeSource(null, (Certificate[]) null);
assertFalse(thiz.equals(that));
assertFalse(that.equals(thiz));
that = new CodeSource(urlFile, (Certificate[]) null);
assertFalse(thiz.equals(that));
assertFalse(that.equals(thiz));
}
/**
* Tests CodeSource.getCertificates().
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "getCertificates",
args = {}
)
public void testGetCertificates_00() {
assertNull(new CodeSource(null, (Certificate[]) null).getCertificates());
java.security.cert.Certificate[] got = new CodeSource(null, chain)
.getCertificates();
// The returned array must be clone()-d ...
assertNotSame(got, chain);
// ... but must represent the same set of certificates
assertTrue(checkEqual(got, chain));
}
/**
* Tests whether the getCertificates() returns certificates obtained from
* the signers.
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "getCertificates",
args = {}
)
public void testGetCertificates_01() {
if (!has_15_features()) {
return;
}
CertPath cpath = TestCertUtils.getCertPath();
Certificate[] certs = (Certificate[]) cpath.getCertificates().toArray();
CodeSigner[] signers = { new CodeSigner(cpath, null) };
CodeSource cs = new CodeSource(null, signers);
Certificate[] got = cs.getCertificates();
// The set of certificates must be exactly the same,
// but the order is not specified
assertTrue(presented(certs, got));
assertTrue(presented(got, certs));
}
/**
* Checks whether two arrays of certificates represent the same same set of
* certificates - in the same order.
* @param one first array
* @param two second array
* @return <code>true</code> if both arrays represent the same set of
* certificates,
* <code>false</code> otherwise.
*/
private static boolean checkEqual(java.security.cert.Certificate[] one,
java.security.cert.Certificate[] two) {
if (one == null) {
return two == null;
}
if (two == null) {
return false;
}
if (one.length != two.length) {
return false;
}
for (int i = 0; i < one.length; i++) {
if (one[i] == null) {
if (two[i] != null) {
return false;
}
} else {
if (!one[i].equals(two[i])) {
return false;
}
}
}
return true;
}
/**
* Performs a test whether the <code>what</code> certificates are all
* presented in <code>where</code> certificates.
*
* @param what - first array of Certificates
* @param where - second array of Certificates
* @return <code>true</code> if each and every certificate from 'what'
* (including null) is presented in 'where' <code>false</code> otherwise
*/
private static boolean presented(Certificate[] what, Certificate[] where) {
boolean whereHasNull = false;
for (int i = 0; i < what.length; i++) {
if (what[i] == null) {
if (whereHasNull) {
continue;
}
for (int j = 0; j < where.length; j++) {
if (where[j] == null) {
whereHasNull = true;
break;
}
}
if (!whereHasNull) {
return false;
}
} else {
boolean found = false;
for (int j = 0; j < where.length; j++) {
if (what[i].equals(where[j])) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
}
return true;
}
/**
* Tests CodeSource.getCodeSigners().
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "getCodeSigners",
args = {}
)
public void testGetCodeSigners_00() {
if (!has_15_features()) {
return;
}
CodeSigner[] signers = { new CodeSigner(TestCertUtils.getCertPath(),
null) };
CodeSource cs = new CodeSource(null, signers);
CodeSigner[] got = cs.getCodeSigners();
assertNotNull(got);
assertTrue(signers.length == got.length);
// not sure whether they must be in the same order
for (int i = 0; i < signers.length; i++) {
CodeSigner s = signers[i];
boolean found = false;
for (int j = 0; j < got.length; j++) {
if (got[j] == s) {
found = true;
break;
}
}
assertTrue(found);
}
}
/**
* Tests CodeSource.getCodeSigners() for null.
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "getCodeSigners",
args = {}
)
public void testGetCoderSignersNull() throws Exception{
assertNull(new CodeSource(new URL("http://url"), (Certificate[])null).getCodeSigners());
}
/**
* Tests CodeSource.getLocation()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getLocation",
args = {}
)
public void testGetLocation() {
assertTrue(new CodeSource(urlSite, (Certificate[]) null).getLocation() == urlSite);
assertTrue(new CodeSource(urlSite, chain).getLocation() == urlSite);
assertNull(new CodeSource(null, (Certificate[]) null).getLocation());
assertNull(new CodeSource(null, chain).getLocation());
}
/**
* Tests CodeSource.toString()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "toString",
args = {}
)
public void testToString() {
// Javadoc keeps silence about String's format,
// just make sure it can be invoked.
new CodeSource(urlSite, chain).toString();
new CodeSource(null, chain).toString();
new CodeSource(null, (Certificate[]) null).toString();
}
/**
* Tests whether we are running with the 1.5 features.<br>
* The test is preformed by looking for (via reflection) the CodeSource's
* constructor {@link CodeSource#CodeSource(URL, CodeSigner[])}.
* @return <code>true</code> if 1.5 feature is presented, <code>false</code>
* otherwise.
*/
private static boolean has_15_features() {
Class klass = CodeSource.class;
Class[] ctorArgs = { URL.class, new CodeSigner[] {}.getClass() };
try {
klass.getConstructor(ctorArgs);
} catch (NoSuchMethodException ex) {
// NoSuchMethod == Not RI.v1.5 and not DRL
return false;
}
return true;
}
/**
* must not imply null CodeSource
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_00() {
CodeSource cs0 = new CodeSource(null, (Certificate[]) null);
assertFalse(cs0.implies(null));
}
/**
* CodeSource with location=null && Certificate[] == null implies any other
* CodeSource
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_01() throws Exception {
CodeSource thizCS = new CodeSource(urlSite, (Certificate[]) null);
CodeSource thatCS = new CodeSource(null, (Certificate[]) null);
assertTrue(thatCS.implies(thizCS));
assertTrue(thatCS.implies(thatCS));
assertFalse(thizCS.implies(thatCS));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_02() throws Exception {
CodeSource thizCS = new CodeSource(urlSite, (Certificate[]) null);
CodeSource thatCS = new CodeSource(thizCS.getLocation(),
(Certificate[]) null);
assertTrue(thizCS.implies(thatCS));
assertTrue(thatCS.implies(thizCS));
}
/*
* FIXME
* commented out for temporary, as there is no FTP:// protocol supported yet.
* to be uncommented back.
public void testImplies_03() throws Exception {
CodeSource thizCS = new CodeSource(urlDir, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlDirFtp, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
assertFalse(thatCS.implies(thizCS));
}
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_03_tmp() throws Exception {
CodeSource thizCS = new CodeSource(urlDir, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlDir_FileProtocol,
(Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
assertFalse(thatCS.implies(thizCS));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_04() throws Exception {
CodeSource thizCS = new CodeSource(urlDir, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlDirIP, (Certificate[]) null);
assertTrue(thizCS.implies(thatCS));
assertTrue(thatCS.implies(thizCS));
//
// Check for another site - force to create SocketPermission
//
thatCS = new CodeSource(urlDirOtherSite, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
//
// also check for getHost() == null
//
thizCS = new CodeSource(new URL("http", null, "file1"),
(Certificate[]) null);
thatCS = new CodeSource(new URL("http", "another.host.com", "file1"),
(Certificate[]) null);
// well, yes, this is accordint to the spec...
assertTrue(thizCS.implies(thatCS));
assertFalse(thatCS.implies(thizCS));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_05() throws Exception {
CodeSource thizCS = new CodeSource(urlDir_port80, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlDir, (Certificate[]) null);
assertTrue(thizCS.implies(thatCS));
assertTrue(thatCS.implies(thizCS));
thizCS = new CodeSource(urlDir, (Certificate[]) null);
thatCS = new CodeSource(urlDir_port81, (Certificate[]) null);
//assert*True* because thizCS has 'port=-1'
assertTrue(thizCS.implies(thatCS));
thizCS = new CodeSource(urlDir_port81, (Certificate[]) null);
thatCS = new CodeSource(urlDir, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
//
thizCS = new CodeSource(urlDir_port80, (Certificate[]) null);
thatCS = new CodeSource(urlDir_port81, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_06() throws Exception {
CodeSource thizCS = new CodeSource(urlFile, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlFile, (Certificate[]) null);
assertTrue(thizCS.implies(thatCS));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_07() throws Exception {
CodeSource thiz = new CodeSource(urlFileDirMinus, (Certificate[]) null);
CodeSource that = new CodeSource(urlFile, (Certificate[]) null);
assertTrue(thiz.implies(that));
that = new CodeSource(urlFileWithAdditionalDirs, (Certificate[]) null);
assertTrue(thiz.implies(that));
that = new CodeSource(urlFileDirOtherDir, (Certificate[]) null);
assertFalse(thiz.implies(that));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_08() throws Exception {
CodeSource thiz = new CodeSource(urlFileDirStar, (Certificate[]) null);
CodeSource that = new CodeSource(urlFile, (Certificate[]) null);
assertTrue(thiz.implies(that));
that = new CodeSource(urlFileWithAdditionalDirs, (Certificate[]) null);
assertFalse(thiz.implies(that));
//
that = new CodeSource(urlFileDirOtherDir, (Certificate[]) null);
assertFalse(thiz.implies(that));
// must not have any further '/'
that = new CodeSource(new URL(urlFile.toString() + "/"),
(Certificate[]) null);
assertFalse(thiz.implies(that));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_09() throws Exception {
CodeSource thizCS = new CodeSource(urlDir, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlDirWithSlash,
(Certificate[]) null);
assertTrue(thizCS.implies(thatCS));
assertFalse(thatCS.implies(thizCS));
}
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_0A() throws Exception {
CodeSource thizCS = new CodeSource(urlRef1, (Certificate[]) null);
CodeSource thatCS = new CodeSource(urlRef1, (Certificate[]) null);
assertTrue(thizCS.implies(thatCS));
thizCS = new CodeSource(urlRef1, (Certificate[]) null);
thatCS = new CodeSource(urlRef2, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
}
/**
* If this certificates are not null, then all of this certificates should
* be presented in certificates of that codesource.
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_0B() {
Certificate c0 = new TestCertUtils.TestCertificate("00");
Certificate c1 = new TestCertUtils.TestCertificate("01");
Certificate c2 = new TestCertUtils.TestCertificate("02");
Certificate[] thizCerts = { c0, c1 };
Certificate[] thatCerts = { c1, c0, c2 };
CodeSource thiz = new CodeSource(urlSite, thizCerts);
CodeSource that = new CodeSource(urlSite, thatCerts);
// two CodeSource-s with different set of certificates
assertTrue(thiz.implies(that));
//
that = new CodeSource(urlSite, (Certificate[]) null);
// 'thiz' has set of certs, while 'that' has no certs. URL-s are the
// same.
assertFalse(thiz.implies(that));
assertTrue(that.implies(thiz));
}
/**
* Testing with special URLs like 'localhost', 'file://' scheme ...
* These special URLs have a special processing in implies(),
* so they need to be covered and performance need to be checked
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_0C() throws Exception {
URL url0 = new URL("http://localhost/someDir");
URL url1 = new URL("http://localhost/someOtherDir");
CodeSource thizCS = new CodeSource(url0, (Certificate[]) null);
CodeSource thatCS = new CodeSource(url1, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
assertFalse(thatCS.implies(thizCS));
}
/**
* Testing with special URLs like 'localhost', 'file://' scheme ...
* These special URLs have a special processing in implies(),
* so they need to be covered and performance need to be checked
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "implies",
args = {java.security.CodeSource.class}
)
public void testImplies_0D() throws Exception {
URL url0 = new URL("file:///" + System.getProperty("java.io.tmpdir")
+ File.separator + "someDir");
URL url1 = new URL("file:///" + System.getProperty("java.io.tmpdir")
+ File.separator + "someOtherDir");
CodeSource thizCS = new CodeSource(url0, (Certificate[]) null);
CodeSource thatCS = new CodeSource(url1, (Certificate[]) null);
assertFalse(thizCS.implies(thatCS));
assertFalse(thatCS.implies(thizCS));
}
}