summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/type3/mmtp/MMTPTrustManager.java
blob: 4748a84186da295d2c9522d063eafb66f909a604 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* $Id$ */
package org.noreply.fancydress.type3.mmtp;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.math.BigInteger;
import org.bouncycastle.util.encoders.Base64;
import org.noreply.fancydress.misc.*;
import org.noreply.fancydress.crypto.*;

public class MMTPTrustManager implements X509TrustManager {
	/**
	 * Hash of the expected identity key.
	 */
	private byte[] identity;

	/**
	 * Create a new MMTPTrustManager instance.
	 *
	 * @param keyid fingerprint (== keyid, == hash of the key) of the identity key.
	 */
	public MMTPTrustManager(byte[] identity) {
		this.identity = identity;
	}

	/**
	 * Given the partial or complete certificate chain provided by the
	 * peer, build a certificate path to a trusted root and return if it
	 * can be validated and is trusted for client SSL authentication based
	 * on the authentication type.
	 *
	 * @param chain the peer certificate chain
	 * @param authType the authentication type based on the client certificate
	 * @throws IllegalArgumentException if null or zero-length chain is
	 *                                  passed in for the chain parameter
	 *                                  or if null or zero-length string is
	 *                                  passed in for the authType
	 *                                  parameter 
	 * @throws CertificateException  if the certificate chain is not
	 *                               trusted by this TrustManager.
	 */
	public void checkClientTrusted(X509Certificate[] chain, String authType)
		throws CertificateException
	{
		throw new Error("Not needed\n");
	}

	/**
	 * Given the partial or complete certificate chain provided by the
	 * peer, build a certificate path to a trusted root and return if it
	 * can be validated and is trusted for server SSL authentication based
	 * on the authentication type.
	 *
	 * @param chain the peer certificate chain
	 * @param authType the key exchange algorithm used
	 * @throws IllegalArgumentException if null or zero-length chain is
	 *                                  passed in for the chain parameter
	 *                                  or if null or zero-length string is
	 *                                  passed in for the authType
	 *                                  parameter 
	 * @throws CertificateException  if the certificate chain is not
	 *                               trusted by this TrustManager.
	 */
	public void checkServerTrusted(X509Certificate[] chain, String authType)
		throws CertificateException
	{
		/* Make sure we got two keys */
		if (chain.length != 2)
			throw new CertificateException("Did not get excatly 2 certificates in cert chain.");

		/* Verify, that the first cert is signed by the second cert */
		java.security.interfaces.RSAPublicKey identityCertKey = (java.security.interfaces.RSAPublicKey) chain[1].getPublicKey();
		try {
			chain[0].verify(identityCertKey);
		} catch (NoSuchAlgorithmException e) {
			throw new CertificateException("Could not verify chain.  Caused by NoSuchAlgorithmException,");
		} catch (InvalidKeyException e) {
			throw new CertificateException("Could not verify chain.  Caused by InvalidKeyException,");
		} catch (NoSuchProviderException e) {
			throw new CertificateException("Could not verify chain.  Caused by NoSuchProviderException,");
		} catch (SignatureException e) {
			throw new CertificateException("Could not verify chain.  Caused by SignatureException,");
		};

		/* Verify, that the second cert is the identity key */
		BigInteger modulus = identityCertKey.getModulus();
		BigInteger exp = identityCertKey.getPublicExponent();
		RSAPublicKey rsa = new RSAPublicKey(modulus,exp);
		byte[] fpr = rsa.getFingerprint();
		if (!Util.equal(identity, fpr))
			throw new CertificateException("Identity key's fingerprint does not match expected value.");
	}

	/**
	 * Return an array of certificate authority certificates which are
	 * trusted for authenticating peers.
	 *
	 * @return a non-null (possibly empty) array of acceptable CA issuer
	 *         certificates.
	 */
	public X509Certificate[] getAcceptedIssuers() {
		throw new Error("Not needed\n");
	}
}