/**
 *     Copyright (C) 2014 Henix
 *
 *     See the NOTICE file distributed with this work for additional
 *     information regarding copyright ownership.
 *
 *     All rights reserved, please contact Henix to get a license.
 *
 */
package fr.asipsante.mss.connectkit.connection;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.HashSet;
import java.util.Set;

import javax.net.ssl.KeyManagerFactory;

/**
 * {@link fr.asipsante.mss.connectkit.connection.HttpsConnectionFactory} basée sur l'utilisation de certificats
 * logiciels X509 pour l'authentification client.
 * 
 * @author edegenetais
 * 
 */
public class SoftwareClientAuthHttpsConnectionFactory extends
		HttpsConnectionFactory {

	private URL keystoreURL;
	private String keypassword;

	/**
	 * @param keystoreURL URL du fichier JKS contenant les certificats clients.
	 * 
	 * @param keystorePasswd
	 *            du fichier JKS contenant les certificats clients.
	 * @param truststoreURL
	 * @see HttpsConnectionFactory#HttpsConnectionFactory(Set, URL, String)
	 * @param truststorePasswd
	 * @see HttpsConnectionFactory#HttpsConnectionFactory(Set, URL, String)
	 */
	public SoftwareClientAuthHttpsConnectionFactory(URL truststoreURL,
			URL keystoreURL, String keystorePasswd, String truststorePasswd) {
		this(truststoreURL, keystoreURL, new HashSet<RequestProperty>(),
				keystorePasswd, truststorePasswd);
	}

	/**
	 * @param keystoreURL URL du fichier JKS contenant les certificats clients.
	 * @param keystorePasswd du fichier JKS contenant les certificats clients.
	 * @param truststoreURL
	 * @see HttpsConnectionFactory#HttpsConnectionFactory(Set, URL, String)
	 * @param truststorePasswd
	 * @see HttpsConnectionFactory#HttpsConnectionFactory(Set, URL, String)
	 * @param requestHeaders headers HTTP pour les connexions.
	 */
	public SoftwareClientAuthHttpsConnectionFactory(URL truststoreURL,
			URL keystoreURL, Set<RequestProperty> requestHeaders,
			String keystorePasswd, String truststorePasswd) {
		super(requestHeaders, truststoreURL, truststorePasswd);
		this.keystoreURL = keystoreURL;
		this.keypassword = keystorePasswd;
	}

        /**
         * @return une fabrique de gestionnaires de clefs basée sur un magasin de certificats logiciels, 
         * base de l'authentification SSL du client dans cette stratégie.
         * @throws SSLSecurityException si le chargement du magasin échoue (ex: l'URL enregistrée n'est pas un magasin JKS valide).
         */
	@Override
	protected KeyManagerFactory getKeyManagerFactory() throws SSLSecurityException{
		try {
			KeyStore keyStore = KeyStore.getInstance("jks");
			InputStream keysStream = keystoreURL.openStream();
			keyStore.load(keysStream, keypassword.toCharArray());
			KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
			kmf.init(keyStore, keypassword.toCharArray());
			return kmf;
		} catch (KeyStoreException 
                        |IOException 
                        |NoSuchAlgorithmException 
                        |CertificateException 
                        |UnrecoverableKeyException e) {
			throw new SSLSecurityException("Echech d'activation des clefs d'authentification SSL client.", e);
		}
	}
}