Package com.sonatype.nexus.ssl.plugin.internal

Source Code of com.sonatype.nexus.ssl.plugin.internal.TrustStoreImpl

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package com.sonatype.nexus.ssl.plugin.internal;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import com.sonatype.nexus.ssl.model.TrustStoreKey;
import com.sonatype.nexus.ssl.plugin.SSLPlugin;
import com.sonatype.nexus.ssl.plugin.TrustStore;

import org.sonatype.sisu.goodies.common.ComponentSupport;
import org.sonatype.sisu.goodies.ssl.keystore.CertificateUtil;
import org.sonatype.sisu.goodies.ssl.keystore.KeyStoreManager;
import org.sonatype.sisu.goodies.ssl.keystore.KeystoreException;

import com.google.common.base.Throwables;
import com.google.common.collect.Sets;
import org.apache.http.conn.ssl.SSLSocketFactory;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* {@link TrustStore} implementation.
*
* @since ssl 1.0
*/
@Named
@Singleton
public class TrustStoreImpl
    extends ComponentSupport
    implements TrustStore
{

  public static final SecureRandom DEFAULT_RANDOM = null;

  private final KeyManager[] keyManagers;

  private final TrustManager[] trustManagers;

  private final Set<TrustStoreKey> enabledKeys;

  private final KeyStoreManager keyStoreManager;

  private volatile SSLContext sslcontext;

  @Inject
  public TrustStoreImpl(
      final @Named(SSLPlugin.ID_PREFIX) KeyStoreManager keyStoreManager)
      throws Exception
  {
    this.keyStoreManager = checkNotNull(keyStoreManager);
    keyManagers = getSystemKeyManagers();
    trustManagers = getTrustManagers(keyStoreManager);
    enabledKeys = Sets.newCopyOnWriteArraySet();
  }

  @Override
  public Certificate importTrustCertificate(final Certificate certificate, final String alias)
      throws KeystoreException
  {
    keyStoreManager.importTrustCertificate(certificate, alias);
    return certificate;
  }

  @Override
  public Certificate importTrustCertificate(final String certificateInPEM, final String alias)
      throws KeystoreException, CertificateParsingException
  {
    final Certificate certificate = CertificateUtil.decodePEMFormattedCertificate(certificateInPEM);
    keyStoreManager.importTrustCertificate(certificate, alias);
    return certificate;
  }

  @Override
  public Certificate getTrustedCertificate(final String alias)
      throws KeystoreException
  {
    return keyStoreManager.getTrustedCertificate(alias);
  }

  @Override
  public Collection<Certificate> getTrustedCertificates()
      throws KeystoreException
  {
    return keyStoreManager.getTrustedCertificates();
  }

  @Override
  public void removeTrustCertificate(final String alias)
      throws KeystoreException
  {
    keyStoreManager.removeTrustCertificate(alias);
    sslcontext = null;
  }

  @Override
  public void enableFor(final TrustStoreKey key) {
    enabledKeys.add(key);
    log.info("Nexus SSL Trust Store enabled for {}", key);
  }

  @Override
  public void disableFor(final TrustStoreKey key) {
    enabledKeys.remove(key);
    log.info("Nexus SSL Trust Store disabled for {}", key);
  }

  @Override
  public SSLContext getSSLContext() {
    SSLContext _sslcontext = this.sslcontext; // local variable allows concurrent removeTrustCertificate
    if (_sslcontext == null) {
      try {
        _sslcontext = SSLContext.getInstance(SSLSocketFactory.TLS);
        _sslcontext.init(keyManagers, trustManagers, DEFAULT_RANDOM);
        this.sslcontext = _sslcontext;
      }
      catch (Exception e) {
        log.debug("Could not create SSL context", e);
        throw Throwables.propagate(e);
      }
    }
    return _sslcontext;
  }

  @Override
  public SSLContext getSSLContextFor(final TrustStoreKey key) {
    if (enabledKeys.contains(key)) {
      return getSSLContext();
    }
    return null;
  }

  private static TrustManager[] getTrustManagers(final KeyStoreManager keyStoreManager)
      throws Exception
  {
    final X509TrustManager managedTrustManager = getManagedTrustManager(checkNotNull(keyStoreManager));
    final TrustManager[] systemTrustManagers = getSystemTrustManagers();

    if (systemTrustManagers != null && managedTrustManager != null) {
      final TrustManager[] trustManagers = new TrustManager[systemTrustManagers.length];
      for (int i = 0; i < systemTrustManagers.length; i++) {
        final TrustManager tm = trustManagers[i] = systemTrustManagers[i];
        if (tm instanceof X509TrustManager) {
          trustManagers[i] = new X509TrustManager()
          {

            @Override
            public void checkClientTrusted(final X509Certificate[] chain, final String authType)
                throws CertificateException
            {
              ((X509TrustManager) tm).checkClientTrusted(chain, authType);
            }

            @Override
            public void checkServerTrusted(final X509Certificate[] chain, final String authType)
                throws CertificateException
            {
              try {
                ((X509TrustManager) tm).checkServerTrusted(chain, authType);
              }
              catch (CertificateException e) {
                try {
                  managedTrustManager.checkServerTrusted(chain, authType);
                }
                catch (CertificateException ignore) {
                  throw e;
                }
              }
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
              return ((X509TrustManager) tm).getAcceptedIssuers();
            }
          };
        }
      }
      return trustManagers;
    }
    return null;
  }

  private static X509TrustManager getManagedTrustManager(final KeyStoreManager keyStoreManager)
      throws KeystoreException
  {
    final TrustManager[] managedTrustManagers = keyStoreManager.getTrustManagers();
    if (managedTrustManagers != null) {
      for (TrustManager tm : managedTrustManagers) {
        if (tm instanceof X509TrustManager) {
          return (X509TrustManager) tm;
        }
      }
    }
    return null;
  }

  private static KeyManager[] getSystemKeyManagers()
      throws Exception
  {
    KeyManagerFactory keyManagerFactory;

    String keyAlgorithm = System.getProperty("ssl.KeyManagerFactory.algorithm");
    if (keyAlgorithm == null) {
      keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
    }
    String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
    if (keyStoreType == null) {
      keyStoreType = KeyStore.getDefaultType();
    }
    if ("none".equalsIgnoreCase(keyStoreType)) {
      keyManagerFactory = KeyManagerFactory.getInstance(keyAlgorithm);
    }
    else {
      final String keyStoreFileName = System.getProperty("javax.net.ssl.keyStore");
      if (keyStoreFileName != null) {
        File keyStoreFile = new File(keyStoreFileName);
        keyManagerFactory = KeyManagerFactory.getInstance(keyAlgorithm);
        String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider");
        KeyStore keyStore;
        if (keyStoreProvider != null) {
          keyStore = KeyStore.getInstance(keyStoreType, keyStoreProvider);
        }
        else {
          keyStore = KeyStore.getInstance(keyStoreType);
        }
        String password = System.getProperty("javax.net.ssl.keyStorePassword");
        FileInputStream in = new FileInputStream(keyStoreFile);
        try {
          keyStore.load(in, password != null ? password.toCharArray() : null);
        }
        finally {
          in.close();
        }
        keyManagerFactory.init(keyStore, password != null ? password.toCharArray() : null);
      }
      else {
        return null;
      }
    }

    return keyManagerFactory.getKeyManagers();
  }

  private static TrustManager[] getSystemTrustManagers()
      throws Exception
  {
    TrustManagerFactory trustManagerFactory;

    String trustAlgorithm = System.getProperty("ssl.TrustManagerFactory.algorithm");
    if (trustAlgorithm == null) {
      trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    }
    String trustStoreType = System.getProperty("javax.net.ssl.trustStoreType");
    if (trustStoreType == null) {
      trustStoreType = KeyStore.getDefaultType();
    }
    if ("none".equalsIgnoreCase(trustStoreType)) {
      trustManagerFactory = TrustManagerFactory.getInstance(trustAlgorithm);
    }
    else {
      File trustStoreFile;
      KeyStore trustStore;

      String trustStoreFileName = System.getProperty("javax.net.ssl.trustStore");
      if (trustStoreFileName != null) {
        trustStoreFile = new File(trustStoreFileName);
        trustManagerFactory = TrustManagerFactory.getInstance(trustAlgorithm);
        final String trustStoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider");
        if (trustStoreProvider != null) {
          trustStore = KeyStore.getInstance(trustStoreType, trustStoreProvider);
        }
        else {
          trustStore = KeyStore.getInstance(trustStoreType);
        }
      }
      else {
        File javaHome = new File(System.getProperty("java.home"));
        File file = new File(javaHome, "lib/security/jssecacerts");
        if (!file.exists()) {
          file = new File(javaHome, "lib/security/cacerts");
          trustStoreFile = file;
        }
        else {
          trustStoreFile = file;
        }

        trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
      }
      final String password = System.getProperty("javax.net.ssl.trustStorePassword");
      final FileInputStream in = new FileInputStream(trustStoreFile);
      try {
        trustStore.load(in, password != null ? password.toCharArray() : null);
      }
      finally {
        in.close();
      }
      trustManagerFactory.init(trustStore);
    }
    return trustManagerFactory.getTrustManagers();
  }

}
TOP

Related Classes of com.sonatype.nexus.ssl.plugin.internal.TrustStoreImpl

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.