org.opcfoundation.ua.transport.https.HttpsSettings.java Source code

Java tutorial

Introduction

Here is the source code for org.opcfoundation.ua.transport.https.HttpsSettings.java

Source

/* Copyright (c) 1996-2015, OPC Foundation. All rights reserved.
   The source code in this file is covered under a dual-license scenario:
 - RCL: for OPC Foundation members in good-standing
 - GPL V2: everybody else
   RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/
   GNU General Public License as published by the Free Software Foundation;
   version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2
   This source code 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.
*/
package org.opcfoundation.ua.transport.https;

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStore.PasswordProtection;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.KeyStore.TrustedCertificateEntry;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509KeyManager;

import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.params.HttpParams;
import org.opcfoundation.ua.common.ServiceResultException;
import org.opcfoundation.ua.transport.security.Cert;
import org.opcfoundation.ua.transport.security.CertValidatorTrustManager;
import org.opcfoundation.ua.transport.security.CertificateValidator;
import org.opcfoundation.ua.transport.security.HttpsSecurityPolicy;
import org.opcfoundation.ua.transport.security.KeyPair;

public class HttpsSettings {

    /** Key Managers */
    X509KeyManager keyManager;
    /** Trust managers */
    TrustManager trustManager;
    /** Verifies whether the target hostname matches the names stored inside 
     * the server's X.509 certificate, once the connection has been established. 
     * This verification can provide additional guarantees of authenticity of 
     * the server trust material. */
    X509HostnameVerifier hostnameVerifier;
    /** Authentication info */
    String username;
    String password;
    /** http params */
    HttpParams httpParams;
    private HttpsSecurityPolicy[] httpsSecurityPolicies;

    public HttpsSettings() {

    }

    public HttpsSettings(KeyPair keypair, CertificateValidator certValidator,
            X509HostnameVerifier hostnameVerifier) {
        super();
        setKeyPair(keypair);
        setCertificateValidator(certValidator);
        this.hostnameVerifier = hostnameVerifier;
    }

    public HttpsSettings(X509KeyManager keyManager, TrustManager trustManager,
            X509HostnameVerifier hostnameVerifier) {
        super();
        this.keyManager = keyManager;
        this.trustManager = trustManager;
        this.hostnameVerifier = hostnameVerifier;
    }

    public HttpsSettings(X509KeyManager keyManager, TrustManager trustManager,
            X509HostnameVerifier hostnameVerifier, String username, String password) {
        super();
        this.keyManager = keyManager;
        this.trustManager = trustManager;
        this.hostnameVerifier = hostnameVerifier;
        this.username = username;
        this.password = password;
    }

    /**
     * Verifies whether the target hostname matches the names stored inside 
     * the server's X.509 certificate, once the connection has been established. 
     * This verification can provide additional guarantees of authenticity of 
     * the server trust material. 
     * 
     * @param hostnameVerifier
     */
    public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
        this.hostnameVerifier = hostnameVerifier;
    }

    public X509HostnameVerifier getHostnameVerifier() {
        return hostnameVerifier;
    }

    /**
     * Set keypair of a https application. This replaces a keyManager.
     * Additional CA certifications can be attached. 
     * 
     * @param keypair
     * @param caCerts
     * @throws KeyStoreException
     * @throws UnrecoverableKeyException
     * @throws NoSuchAlgorithmException
     */
    public void setKeyPair(KeyPair keypair, Cert... caCerts) {
        if (keypair != null)
            try {
                KeyStore keystore = KeyStore.getInstance("jks");
                Certificate[] certs = new Certificate[] { keypair.certificate.certificate };
                PrivateKeyEntry entry = new PrivateKeyEntry(keypair.privateKey.getPrivateKey(), certs);
                String password = "";
                keystore.load(null);
                keystore.setEntry("myentry-" + keypair.hashCode(), entry,
                        new PasswordProtection(password.toCharArray()));
                int count = caCerts.length;
                for (int i = 0; i < count; i++) {
                    String id = "cacert-" + (i + 1);
                    keystore.setEntry(id, new TrustedCertificateEntry(caCerts[i].certificate), null);
                }
                setKeyStore(keystore, "");
            } catch (KeyStoreException e) {
                // Expected if JKS is not available (e.g. in Android)

            } catch (NoSuchAlgorithmException e) {
                // Unexpected
                throw new RuntimeException(e);
            } catch (CertificateException e) {
                // Unexpected
                throw new RuntimeException(e);
            } catch (IOException e) {
                // Unexpected
                throw new RuntimeException(e);
            } catch (ServiceResultException e) {
                // Unexpected
                throw new RuntimeException(e);
            }
    }

    /**
     * Set keypairs to a https application. This replaces previous keyManager.
     * Additional CA certifications can be attached. 
     * 
     * @param keypairs
     * @param caCerts
     * @throws KeyStoreException
     * @throws UnrecoverableKeyException
     * @throws NoSuchAlgorithmException
     */
    public void setKeyPairs(KeyPair[] keypairs, Cert... caCerts) {
        try {
            KeyStore keystore = KeyStore.getInstance("jks");
            String password = "";
            PasswordProtection prot = new PasswordProtection(password.toCharArray());
            keystore.load(null);
            for (int i = 0; i < keypairs.length; i++) {
                Certificate[] certs = new Certificate[1 + caCerts.length];
                certs[0] = keypairs[i].certificate.certificate;
                for (int j = 0; j < caCerts.length; j++) {
                    certs[j + 1] = caCerts[j].certificate;
                }
                PrivateKeyEntry entry = new PrivateKeyEntry(keypairs[i].privateKey.privateKey, certs);
                keystore.setEntry("my-key-pair-entry-" + (i + 1), entry, prot);
            }
            int count = caCerts.length;
            for (int i = 0; i < count; i++) {
                String id = "cacert-" + (i + 1);
                keystore.setEntry(id, new TrustedCertificateEntry(caCerts[i].certificate), null);
            }
            setKeyStore(keystore, "");
        } catch (KeyStoreException e) {
            // Unexpected
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            // Unexpected
            throw new RuntimeException(e);
        } catch (CertificateException e) {
            // Unexpected
            throw new RuntimeException(e);
        } catch (IOException e) {
            // Unexpected
            throw new RuntimeException(e);
        } catch (ServiceResultException e) {
            // Unexpected
            throw new RuntimeException(e);
        }
    }

    /**
     * Set keystore as the key manager for a https application.   
     *  
     * @param keystore
     * @param password
     * @throws NoSuchAlgorithmException
     * @throws UnrecoverableKeyException
     * @throws KeyStoreException
     */
    public void setKeyStore(KeyStore keystore, String password) throws ServiceResultException {
        try {
            KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmfactory.init(keystore, password.toCharArray());
            KeyManager kms[] = kmfactory.getKeyManagers();
            keyManager = kms.length == 0 ? null : (X509KeyManager) kms[0];
        } catch (NoSuchAlgorithmException e) {
            throw new ServiceResultException(e);
        } catch (UnrecoverableKeyException e) {
            throw new ServiceResultException(e);
        } catch (KeyStoreException e) {
            throw new ServiceResultException(e);
        }
    }

    /**
     * Set keymanager for a https application.
     * 
     * @param keyManager
     * @throws ServiceResultException 
     */
    public void setKeyManager(X509KeyManager keyManager) throws ServiceResultException {
        this.keyManager = keyManager;
    }

    /**
     * Set the trust manager for a https application. 
     * Trust manager validates peer's certificates and certificate issuers.
     * 
     * @param trustManager
     * @throws ServiceResultException 
     */
    public void setTrustManager(TrustManager trustManager) throws ServiceResultException {
        this.trustManager = trustManager;
    }

    /**
     * Set an implementation of CertificateValidator as TrustManager.
     * Trust manager validates peer's certificates and certificate issuers.
     * 
     * @param certValidator
     */
    public void setCertificateValidator(CertificateValidator certValidator) {
        this.trustManager = new CertValidatorTrustManager(certValidator);
    }

    /**
     * Set SSL Authentication information. Must be set before #initialization.
     * 
     * @param username
     * @param password
     */
    public void setHttpsAuth(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public TrustManager[] getTrustManagers() {
        return trustManager == null ? new TrustManager[0] : new TrustManager[] { trustManager };
    }

    public KeyManager[] getKeyManagers() {
        return keyManager == null ? new KeyManager[0] : new KeyManager[] { keyManager };
    }

    public TrustManager getTrustManager() {
        return trustManager;
    }

    public X509KeyManager getKeyManager() {
        return keyManager;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public HttpParams getHttpParams() {
        return httpParams;
    }

    public void setHttpParams(HttpParams httpParams) {
        this.httpParams = httpParams;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void readFrom(HttpsSettings src) {
        if (src.hostnameVerifier != null)
            hostnameVerifier = src.hostnameVerifier;
        if (src.trustManager != null)
            this.trustManager = src.trustManager;
        if (src.keyManager != null)
            this.keyManager = src.keyManager;
        if (src.username != null && src.password != null) {
            username = src.username;
            password = src.password;
        }
        if (src.httpParams != null)
            this.httpParams = src.httpParams;
        if (src.httpsSecurityPolicies != null)
            this.httpsSecurityPolicies = src.httpsSecurityPolicies;
    }

    @Override
    public HttpsSettings clone() {
        HttpsSettings result = new HttpsSettings();

        result.hostnameVerifier = hostnameVerifier;
        result.trustManager = trustManager;
        result.keyManager = keyManager;
        result.username = username;
        result.password = password;
        result.httpParams = httpParams;
        result.httpsSecurityPolicies = httpsSecurityPolicies;

        return result;
    }

    public HttpsSecurityPolicy[] getHttpsSecurityPolicies() {
        return httpsSecurityPolicies;
    }

    public void setHttpsSecurityPolicies(HttpsSecurityPolicy... httpsSecurityPolicy) {
        this.httpsSecurityPolicies = httpsSecurityPolicy;
    }

}