001/* 002 * Copyright 2008-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2018 Ping Identity Corporation 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.Debug; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.StaticUtils; 033import com.unboundid.util.ThreadSafety; 034import com.unboundid.util.ThreadSafetyLevel; 035 036import static com.unboundid.util.ssl.SSLMessages.*; 037 038 039 040/** 041 * This class provides an SSL key manager that may be used to retrieve 042 * certificates from a PKCS#11 token. 043 */ 044@NotMutable() 045@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 046public final class PKCS11KeyManager 047 extends WrapperKeyManager 048{ 049 /** 050 * The key store type to use to access PKCS#11 tokens. 051 */ 052 private static final String PKCS11_KEY_STORE_TYPE = "PKCS11"; 053 054 055 056 /** 057 * Creates a new instance of this PKCS11 key manager that provides the ability 058 * to retrieve certificates from a PKCS#11 token. 059 * 060 * @param keyStorePIN The PIN to use to access the contents of the 061 * PKCS#11 token. It may be {@code null} if no PIN 062 * is required. 063 * @param certificateAlias The nickname of the certificate that should be 064 * selected. It may be {@code null} if any 065 * acceptable certificate found may be used. 066 * 067 * @throws KeyStoreException If a problem occurs while initializing this key 068 * manager. 069 */ 070 public PKCS11KeyManager(final char[] keyStorePIN, 071 final String certificateAlias) 072 throws KeyStoreException 073 { 074 super(getKeyManagers(keyStorePIN), certificateAlias); 075 } 076 077 078 079 /** 080 * Retrieves the set of key managers that will be wrapped by this key manager. 081 * 082 * @param keyStorePIN The PIN to use to access the contents of the PKCS#11 083 * token. It may be {@code null} if no PIN is required. 084 * 085 * @return The set of key managers that will be wrapped by this key manager. 086 * 087 * @throws KeyStoreException If a problem occurs while initializing this key 088 * manager. 089 */ 090 private static KeyManager[] getKeyManagers(final char[] keyStorePIN) 091 throws KeyStoreException 092 { 093 final KeyStore ks = KeyStore.getInstance(PKCS11_KEY_STORE_TYPE); 094 try 095 { 096 ks.load(null, keyStorePIN); 097 } 098 catch (final Exception e) 099 { 100 Debug.debugException(e); 101 102 throw new KeyStoreException( 103 ERR_PKCS11_CANNOT_ACCESS.get(StaticUtils.getExceptionMessage(e)), e); 104 } 105 106 try 107 { 108 final KeyManagerFactory factory = KeyManagerFactory.getInstance( 109 KeyManagerFactory.getDefaultAlgorithm()); 110 factory.init(ks, keyStorePIN); 111 return factory.getKeyManagers(); 112 } 113 catch (final Exception e) 114 { 115 Debug.debugException(e); 116 117 throw new KeyStoreException( 118 ERR_PKCS11_CANNOT_GET_KEY_MANAGERS.get( 119 StaticUtils.getExceptionMessage(e)), 120 e); 121 } 122 } 123}