/* $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.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateExpiredException; 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."); /* Check, if the certs are valid. Certs are valid if * ValidAfter already passed and ValidUntil is still in the * future */ try { chain[0].checkValidity(); } catch (CertificateExpiredException e) { throw new CertificateException("Cert 0 not valid. Caused by CertificateExpiredException."); } catch (CertificateNotYetValidException e) { throw new CertificateException("Cert 0 not valid. Caused by CertificateNotYetValidException."); } try { chain[1].checkValidity(); } catch (CertificateExpiredException e) { throw new CertificateException("Cert 1 not valid. Caused by CertificateExpiredException."); } catch (CertificateNotYetValidException e) { throw new CertificateException("Cert 1 not valid. Caused by CertificateNotYetValidException."); } /* 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"); } }