Package org.tmatesoft.svn.core.internal.io.dav.http

Source Code of org.tmatesoft.svn.core.internal.io.dav.http.HTTPSSLKeyManager

/*
* ====================================================================
* Copyright (c) 2004-2009 TMate Software Ltd.  All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.  The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.io.dav.http;

import java.io.File;
import java.io.InputStream;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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

import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.auth.SVNSSLAuthentication;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.util.SVNDebugLog;
import org.tmatesoft.svn.util.SVNLogType;

/**
* @version 1.3
* @author  TMate Software Ltd.
*/
public final class HTTPSSLKeyManager implements X509KeyManager {

  public static KeyManager[] loadClientCertificate(File clientCertFile, String clientCertPassword) throws SVNException {
    char[] passphrase = null;
    if (clientCertPassword != null) {
      passphrase = clientCertPassword.toCharArray();
    }
    KeyStore keyStore = null;
    final InputStream is = SVNFileUtil.openFileForReading(clientCertFile, SVNLogType.NETWORK);
    try {
      keyStore = KeyStore.getInstance("PKCS12");
      if (keyStore != null) {
        keyStore.load(is, passphrase);
      }
    }
    catch (Throwable th) {
      SVNDebugLog.getDefaultLog().logFine(SVNLogType.NETWORK, th);
      throw new SVNException(SVNErrorMessage.create(SVNErrorCode.RA_NOT_AUTHORIZED, th.getMessage(), null, SVNErrorMessage.TYPE_ERROR, th), th);
    }
    finally {
      SVNFileUtil.closeFile(is);
    }
    KeyManagerFactory kmf = null;
    KeyManager[] result = null;
    if (keyStore != null) {
      try {
        kmf = KeyManagerFactory.getInstance("SunX509");
        if (kmf != null) {
          kmf.init(keyStore, passphrase);
          result = kmf.getKeyManagers();
        }
      }
      catch (Throwable th) {
        SVNDebugLog.getDefaultLog().logFine(SVNLogType.NETWORK, th);
        throw new SVNException(SVNErrorMessage.create(SVNErrorCode.RA_NOT_AUTHORIZED, th.getMessage()), th);
      }
    }
    return result;
  }

  private final ISVNAuthenticationManager authenticationManager;
  private final String realm;
  private final SVNURL url;

  private KeyManager[] myKeyManagers;
  private SVNSSLAuthentication myAuthentication;
  private Exception myException;

  public HTTPSSLKeyManager(ISVNAuthenticationManager authenticationManager, String realm, SVNURL url) {
    this.authenticationManager = authenticationManager;
    this.realm = realm;
    this.url = url;
  }

  public String[] getClientAliases(String location, Principal[] principals) {
    if (!initializeNoException()) {
      return null;
    }

    for (Iterator it = getX509KeyManagers(myKeyManagers).iterator(); it.hasNext();) {
      final X509KeyManager keyManager = (X509KeyManager)it.next();
      final String[] clientAliases = keyManager.getClientAliases(location, principals);
      if (clientAliases != null) {
        return clientAliases;
      }
    }

    return null;
  }

  public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
    if (!initializeNoException()) {
      return null;
    }

    for (Iterator it = getX509KeyManagers(myKeyManagers).iterator(); it.hasNext();) {
      final X509KeyManager keyManager = (X509KeyManager)it.next();
      final String clientAlias = keyManager.chooseClientAlias(strings, principals, socket);
      if (clientAlias != null) {
        return clientAlias;
      }
    }

    return null;
  }

  public String[] getServerAliases(String location, Principal[] principals) {
    if (!initializeNoException()) {
      return null;
    }

    for (Iterator it = getX509KeyManagers(myKeyManagers).iterator(); it.hasNext();) {
      final X509KeyManager keyManager = (X509KeyManager)it.next();
      final String[] serverAliases = keyManager.getServerAliases(location, principals);
      if (serverAliases != null) {
        return serverAliases;
      }
    }

    return null;
  }

  public String chooseServerAlias(String location, Principal[] principals, Socket socket) {
    if (!initializeNoException()) {
      return null;
    }

    for (Iterator it = getX509KeyManagers(myKeyManagers).iterator(); it.hasNext();) {
      final X509KeyManager keyManager = (X509KeyManager)it.next();
      final String serverAlias = keyManager.chooseServerAlias(location, principals, socket);
      if (serverAlias != null) {
        return serverAlias;
      }
    }

    return null;
  }

  public X509Certificate[] getCertificateChain(String location) {
    if (!initializeNoException()) {
      return null;
    }

    for (Iterator it = getX509KeyManagers(myKeyManagers).iterator(); it.hasNext();) {
      final X509KeyManager keyManager = (X509KeyManager)it.next();
      final X509Certificate[] certificateChain = keyManager.getCertificateChain(location);
      if (certificateChain != null) {
        return certificateChain;
      }
    }

    return null;
  }

  public PrivateKey getPrivateKey(String string) {
    if (!initializeNoException()) {
      return null;
    }

    for (Iterator it = getX509KeyManagers(myKeyManagers).iterator(); it.hasNext();) {
      final X509KeyManager keyManager = (X509KeyManager)it.next();
      final PrivateKey privateKey = keyManager.getPrivateKey(string);
      if (privateKey != null) {
        return privateKey;
      }
    }

    return null;
  }

  public Exception getException() {
    return myException;
  }

  public void acknowledgeAndClearAuthentication(SVNErrorMessage errorMessage) throws SVNException {
    if (myAuthentication != null) {
      authenticationManager.acknowledgeAuthentication(errorMessage == null, ISVNAuthenticationManager.SSL, realm, errorMessage, myAuthentication);
    }

    myAuthentication = null;

    if (errorMessage != null) {
      myKeyManagers = null;
    }

    final Exception exception = myException;
    myException = null;
    if (exception instanceof SVNException) {
      throw (SVNException)exception;
    }
    else if (exception != null) {
      throw new SVNException(SVNErrorMessage.UNKNOWN_ERROR_MESSAGE, exception);
    }
  }

  private boolean initializeNoException() {
    try {
      final boolean result = initialize();
      myException = null;
      return result;
    }
    catch (Exception exception) {
      myException = exception;
      return false;
    }
  }

  private boolean initialize() throws SVNException {
    if (myKeyManagers != null) {
      return true;
    }

    boolean isFirstAuthentication = true;
    for (; ;) {
      if (isFirstAuthentication) {
        myAuthentication = (SVNSSLAuthentication)authenticationManager.getFirstAuthentication(ISVNAuthenticationManager.SSL, realm, url);
        isFirstAuthentication = false;
      }
      else {
        myAuthentication = (SVNSSLAuthentication)authenticationManager.getNextAuthentication(ISVNAuthenticationManager.SSL, realm, url);
      }

      if (myAuthentication == null) {
        SVNErrorManager.cancel("SSL authentication with client certificate cancelled", SVNLogType.NETWORK);
      }

      final KeyManager[] keyManagers;
      try {
        keyManagers = loadClientCertificate(myAuthentication.getCertificateFile(), myAuthentication.getPassword());
      }
      catch (SVNException ex) {
        final SVNErrorMessage sslErr = SVNErrorMessage.create(SVNErrorCode.RA_NOT_AUTHORIZED, "SSL handshake failed: ''{0}''", new Object[] { ex.getMessage() }, SVNErrorMessage.TYPE_ERROR, ex.getCause());
        authenticationManager.acknowledgeAuthentication(false, ISVNAuthenticationManager.SSL, realm, sslErr, myAuthentication);
        continue;
      }

      myKeyManagers = keyManagers;
      return true;
    }
  }

  private static List getX509KeyManagers(KeyManager[] keyManagers) {
    final List x509KeyManagers = new ArrayList();
    for (int index = 0; index < keyManagers.length; index++) {
      final KeyManager keyManager = keyManagers[index];
      if (keyManager instanceof X509KeyManager) {
        x509KeyManagers.add(keyManager);
      }
    }
    return x509KeyManagers;
  }
}
TOP

Related Classes of org.tmatesoft.svn.core.internal.io.dav.http.HTTPSSLKeyManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.