/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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 org.apache.harmony.xnet.provider.jsse;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import junit.framework.TestCase;
import libcore.java.security.TestKeyStore;
public class TrustManagerImplTest extends TestCase {
/**
* Ensure that our non-standard behavior of learning to trust new
* intermediate CAs does not regress. http://b/3404902
*/
public void testLearnIntermediate() throws Exception {
// chain3 should be server/intermediate/root
KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
X509Certificate root = chain3[2];
X509Certificate intermediate = chain3[1];
X509Certificate server = chain3[0];
X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
X509Certificate[] chain1 = new X509Certificate[] { server };
// Normal behavior
assertValid(chain3, trustManager(root));
assertValid(chain2, trustManager(root));
assertInvalid(chain1, trustManager(root));
assertValid(chain3, trustManager(intermediate));
assertValid(chain2, trustManager(intermediate));
assertValid(chain1, trustManager(intermediate));
assertValid(chain3, trustManager(server));
assertValid(chain2, trustManager(server));
assertValid(chain1, trustManager(server));
// non-standard behavior
X509TrustManager tm = trustManager(root);
// fail on short chain with only root trusted
assertInvalid(chain1, tm);
// succeed on longer chain, learn intermediate
assertValid(chain2, tm);
// now we can validate the short chain
assertValid(chain1, tm);
}
private X509TrustManager trustManager(X509Certificate ca) throws Exception {
KeyStore keyStore = TestKeyStore.createKeyStore();
keyStore.setCertificateEntry("alias", ca);
String algorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
tmf.init(keyStore);
return (X509TrustManager) tmf.getTrustManagers()[0];
}
private void assertValid(X509Certificate[] chain, X509TrustManager tm) throws Exception {
tm.checkClientTrusted(chain, "RSA");
tm.checkServerTrusted(chain, "RSA");
}
private void assertInvalid(X509Certificate[] chain, X509TrustManager tm) {
try {
tm.checkClientTrusted(chain, "RSA");
fail();
} catch (CertificateException expected) {
}
try {
tm.checkServerTrusted(chain, "RSA");
fail();
} catch (CertificateException expected) {
}
}
}