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 */
021 package com.unboundid.util.ssl;
022
023
024
025 import java.security.KeyStoreException;
026 import java.security.KeyStore;
027 import javax.net.ssl.KeyManager;
028 import javax.net.ssl.KeyManagerFactory;
029
030 import com.unboundid.util.NotMutable;
031 import com.unboundid.util.ThreadSafety;
032 import com.unboundid.util.ThreadSafetyLevel;
033
034 import static com.unboundid.util.Debug.*;
035 import 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)
045 public 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 }