/**
* OnionCoffee - Anonymous Communication through TOR Network
* Copyright (C) 2005-2007 RWTH Aachen University, Informatik IV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package TorJava;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.X509TrustManager;
class TorX509TrustManager implements X509TrustManager {
static Pattern cnPattern = Pattern.compile("CN=(.*?),.*",
Pattern.UNIX_LINES + Pattern.CASE_INSENSITIVE + Pattern.DOTALL);
public TorX509TrustManager() {
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
if (false)
throw new CertificateException();
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// if(false) throw new CertificateException();
if (true) return;
if (chain.length != 2)
throw new CertificateException("Certificate Chain length != 2");
String dnName0 = chain[0].getSubjectDN().getName();
String dnName1 = chain[1].getSubjectDN().getName();
Matcher dnName0Match = cnPattern.matcher(dnName0);
Matcher dnName1Match = cnPattern.matcher(dnName1);
if (!dnName0Match.matches() || !dnName1Match.matches()) {
Logger.logTLS(Logger.WARNING,"TorX509TrustManager.checkServerTrusted(): not matched");
throw new CertificateException("Name field of Certificate does not have the right format");
}
dnName0 = dnName0Match.group(1);
dnName1 = dnName1Match.group(1);
if (dnName1.indexOf(dnName0) > 1)
throw new CertificateException(
"Certifier and Certificate owner don't have the same name");
// XXX: It seems that the string has changed to <signing>, though
// the second chapter of main-tor-spec still says <identity>
Logger.logTLS(Logger.RAW_DATA, "dnName0 = "+dnName0.toString()+", dnName1 = "+dnName1.toString());
if (dnName1.indexOf("<identity>") != -1 && dnName1.indexOf("<signing>") != -1)
throw new CertificateException("Certifier Field does not have the required form");
Date now = new Date();
if (now.before(chain[0].getNotBefore()))
throw new CertificateException("Certificate is not valid yet");
if (now.after(chain[0].getNotAfter()))
throw new CertificateException("Certificate has expired");
// TODO: the subject unique ID has to be extracted from the ASN1
// stuff of the Directory entry and compared to the one given here.
}
public X509Certificate[] getAcceptedIssuers() {
Logger.logTLS(Logger.VERBOSE,"X509Certificate[] getAcceptedIssuers()");
return new X509Certificate[0];
}
}