001/*
002 * Copyright 2008-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2014 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.util.ssl;
022
023
024
025import java.security.KeyStoreException;
026import java.security.KeyStore;
027import javax.net.ssl.KeyManager;
028import javax.net.ssl.KeyManagerFactory;
029
030import com.unboundid.util.NotMutable;
031import com.unboundid.util.ThreadSafety;
032import com.unboundid.util.ThreadSafetyLevel;
033
034import static com.unboundid.util.Debug.*;
035import static com.unboundid.util.ssl.SSLMessages.*;
036
037
038
039/**
040 * This class provides an SSL key manager that may be used to retrieve
041 * certificates from a PKCS#11 token.
042 */
043@NotMutable()
044@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
045public final class PKCS11KeyManager
046       extends WrapperKeyManager
047{
048  /**
049   * The key store type to use to access PKCS#11 tokens.
050   */
051  private static final String PKCS11_KEY_STORE_TYPE = "PKCS11";
052
053
054
055  /**
056   * Creates a new instance of this PKCS11 key manager that provides the ability
057   * to retrieve certificates from a PKCS#11 token.
058   *
059   * @param  keyStorePIN       The PIN to use to access the contents of the
060   *                           PKCS#11 token.  It may be {@code null} if no PIN
061   *                           is required.
062   * @param  certificateAlias  The nickname of the certificate that should be
063   *                           selected.  It may be {@code null} if any
064   *                           acceptable certificate found may be used.
065   *
066   * @throws  KeyStoreException  If a problem occurs while initializing this key
067   *                             manager.
068   */
069  public PKCS11KeyManager(final char[] keyStorePIN,
070                          final String certificateAlias)
071         throws KeyStoreException
072  {
073    super(getKeyManagers(keyStorePIN), certificateAlias);
074  }
075
076
077
078  /**
079   * Retrieves the set of key managers that will be wrapped by this key manager.
080   *
081   * @param  keyStorePIN  The PIN to use to access the contents of the PKCS#11
082   *                      token.  It may be {@code null} if no PIN is required.
083   *
084   * @return  The set of key managers that will be wrapped by this key manager.
085   *
086   * @throws  KeyStoreException  If a problem occurs while initializing this key
087   *                             manager.
088   */
089  private static KeyManager[] getKeyManagers(final char[] keyStorePIN)
090          throws KeyStoreException
091  {
092    final KeyStore ks = KeyStore.getInstance(PKCS11_KEY_STORE_TYPE);
093    try
094    {
095      ks.load(null, keyStorePIN);
096    }
097    catch (Exception e)
098    {
099      debugException(e);
100
101      throw new KeyStoreException(
102           ERR_PKCS11_CANNOT_ACCESS.get(String.valueOf(e)), e);
103    }
104
105    try
106    {
107      final KeyManagerFactory factory = KeyManagerFactory.getInstance(
108           KeyManagerFactory.getDefaultAlgorithm());
109      factory.init(ks, keyStorePIN);
110      return factory.getKeyManagers();
111    }
112    catch (Exception e)
113    {
114      debugException(e);
115
116      throw new KeyStoreException(
117           ERR_PKCS11_CANNOT_GET_KEY_MANAGERS.get(String.valueOf(e)), e);
118    }
119  }
120}