1 package org.cacert.gigi.ping;
3 import static org.junit.Assert.*;
5 import java.io.IOException;
6 import java.net.Socket;
8 import java.net.URLEncoder;
9 import java.security.GeneralSecurityException;
10 import java.security.KeyManagementException;
11 import java.security.KeyPair;
12 import java.security.NoSuchAlgorithmException;
13 import java.security.Principal;
14 import java.security.PrivateKey;
15 import java.security.SecureRandom;
16 import java.security.cert.CertificateException;
17 import java.security.cert.X509Certificate;
18 import java.sql.SQLException;
19 import java.util.regex.Matcher;
20 import java.util.regex.Pattern;
22 import javax.net.ssl.KeyManager;
23 import javax.net.ssl.SSLContext;
24 import javax.net.ssl.SSLServerSocket;
25 import javax.net.ssl.SSLServerSocketFactory;
26 import javax.net.ssl.TrustManager;
27 import javax.net.ssl.X509KeyManager;
28 import javax.net.ssl.X509TrustManager;
30 import org.cacert.gigi.Certificate;
31 import org.cacert.gigi.CertificateProfile;
32 import org.cacert.gigi.Certificate.CSRType;
33 import org.cacert.gigi.GigiApiException;
34 import org.cacert.gigi.pages.account.DomainOverview;
35 import org.cacert.gigi.testUtils.IOUtils;
36 import org.cacert.gigi.testUtils.PingTest;
37 import org.cacert.gigi.testUtils.TestEmailReciever.TestMail;
38 import org.junit.Test;
40 public class TestSSL extends PingTest {
44 private Certificate c;
47 public void sslAndMailSuccess() throws IOException, InterruptedException, SQLException, GeneralSecurityException, GigiApiException {
48 testEmailAndSSL(0, 0, true);
52 public void sslWongTypeAndMailSuccess() throws IOException, InterruptedException, SQLException, GeneralSecurityException, GigiApiException {
53 testEmailAndSSL(1, 0, true);
57 public void sslOneMissingAndMailSuccess() throws IOException, InterruptedException, SQLException, GeneralSecurityException, GigiApiException {
58 testEmailAndSSL(2, 0, true);
62 public void sslBothMissingAndMailSuccess() throws IOException, InterruptedException, SQLException, GeneralSecurityException, GigiApiException {
63 testEmailAndSSL(3, 0, true);
67 public void sslWrongTypeAndMailFail() throws IOException, InterruptedException, SQLException, GeneralSecurityException, GigiApiException {
68 testEmailAndSSL(1, 1, false);
74 * <li>0= all valid</li>
75 * <li>1= wrong type</li>
76 * <li>2= one server missing</li>
77 * <li>3= both servers missing</li>
83 * @throws InterruptedException
84 * @throws SQLException
85 * @throws GeneralSecurityException
86 * @throws GigiApiException
89 private void testEmailAndSSL(int sslVariant, int emailVariant, boolean successMail) throws IOException, InterruptedException, SQLException, GeneralSecurityException, GigiApiException {
90 String test = getTestProps().getProperty("domain.local");
92 URL u = new URL("https://" + getServerName() + DomainOverview.PATH);
94 initailizeDomainForm(u);
96 createCertificate(test, CertificateProfile.getByName(sslVariant == 1 ? "client" : "server"));
97 SSLServerSocket sss = createSSLServer(kp.getPrivate(), c.cert());
98 int port = sss.getLocalPort();
99 SSLServerSocket sss2 = createSSLServer(kp.getPrivate(), c.cert());
100 int port2 = sss2.getLocalPort();
101 if (sslVariant == 3 || sslVariant == 2) {
103 if (sslVariant == 3) {
107 String content = "newdomain=" + URLEncoder.encode(test, "UTF-8") + //
108 "&emailType=y&email=2&SSLType=y" + //
109 "&ssl-type-0=direct&ssl-port-0=" + port + //
110 "&ssl-type-1=direct&ssl-port-1=" + port2 + //
111 "&ssl-type-2=direct&ssl-port-2=" + //
112 "&ssl-type-3=direct&ssl-port-3=" + //
113 "&adddomain&csrf=" + csrf;
114 URL u2 = sendDomainForm(u, content);
115 boolean firstSucceeds = sslVariant != 0 && sslVariant != 2;
116 assertTrue(firstSucceeds ^ acceptSSLServer(sss));
117 boolean secondsSucceeds = sslVariant != 0;
118 assertTrue(secondsSucceeds ^ acceptSSLServer(sss2));
120 TestMail mail = getMailReciever().recieve();
121 if (emailVariant == 0) {
122 String link = mail.extractLink();
123 new URL(link).openConnection().getHeaderField("");
127 String newcontent = IOUtils.readURL(cookie(u2.openConnection(), cookie));
128 Pattern pat = Pattern.compile("<td>ssl</td>\\s*<td>success</td>");
129 Matcher matcher = pat.matcher(newcontent);
130 assertTrue(newcontent, firstSucceeds ^ matcher.find());
131 assertTrue(newcontent, secondsSucceeds ^ matcher.find());
132 assertFalse(newcontent, matcher.find());
133 pat = Pattern.compile("<td>email</td>\\s*<td>success</td>");
134 assertTrue(newcontent, !successMail ^ pat.matcher(newcontent).find());
137 private void createCertificate(String test, CertificateProfile profile) throws GeneralSecurityException, IOException, SQLException, InterruptedException, GigiApiException {
138 kp = generateKeypair();
139 String csr = generatePEMCSR(kp, "CN=" + test);
140 c = new Certificate(userid, "/CN=" + test, "sha256", csr, CSRType.CSR, profile);
141 c.issue(null, "2y").waitFor(60000);
144 private boolean acceptSSLServer(SSLServerSocket sss) throws IOException {
146 Socket s = sss.accept();
147 s.getOutputStream().write('b');
148 s.getOutputStream().close();
150 } catch (IOException e) {
155 private SSLServerSocket createSSLServer(final PrivateKey priv, final X509Certificate cert) throws Error, IOException {
158 sc = SSLContext.getInstance("SSL");
159 sc.init(new KeyManager[] {
160 new X509KeyManager() {
163 public String[] getServerAliases(String keyType, Principal[] issuers) {
164 return new String[] {
170 public PrivateKey getPrivateKey(String alias) {
175 public String[] getClientAliases(String keyType, Principal[] issuers) {
180 public X509Certificate[] getCertificateChain(String alias) {
181 return new X509Certificate[] {
187 public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
192 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
197 }, new TrustManager[] {
198 new X509TrustManager() {
201 public X509Certificate[] getAcceptedIssuers() {
206 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
209 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
211 }, new SecureRandom());
212 } catch (NoSuchAlgorithmException e) {
215 } catch (KeyManagementException e) {
220 SSLServerSocketFactory sssf = sc.getServerSocketFactory();
221 return (SSLServerSocket) sssf.createServerSocket(0);