001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2014-2015 ForgeRock AS. 015 */ 016 017package org.forgerock.openig.security; 018 019import static java.lang.String.*; 020import static org.forgerock.openig.util.JsonValues.*; 021 022import java.security.KeyStore; 023 024import javax.net.ssl.KeyManager; 025import javax.net.ssl.KeyManagerFactory; 026 027import org.forgerock.json.JsonValue; 028import org.forgerock.openig.heap.GenericHeaplet; 029import org.forgerock.openig.heap.HeapException; 030 031/** 032 * Represents an SSL Java {@link KeyManager}. 033 * <pre> 034 * {@code 035 * { 036 * "name": "MyKeyManager", 037 * "type": "KeyManager", 038 * "config": { 039 * "keystore": "MyKeyStore", 040 * "password": "secret", 041 * "alg": "SunX509" 042 * } 043 * } 044 * } 045 * </pre> 046 * <ul> 047 * <li>{@literal keystore}: Reference a KeyStore heap object (string, required).</li> 048 * <li>{@literal password}: credential required to read private keys from the key store (expression, required).</li> 049 * <li>{@literal alg}: key manager algorithm (defaults to platform's default type) (string, optional).</li> 050 * </ul> 051 * @since 3.1 052 */ 053public class KeyManagerHeaplet extends GenericHeaplet { 054 055 @Override 056 public Object create() throws HeapException { 057 JsonValue storeRef = config.get("keystore").required(); 058 KeyStore keyStore = heap.resolve(storeRef, KeyStore.class); 059 String password = evaluate(config.get("password").required()); 060 String algorithm = config.get("alg").defaultTo(KeyManagerFactory.getDefaultAlgorithm()).asString(); 061 062 // Initialize a KeyManagerFactory 063 KeyManagerFactory factory; 064 try { 065 factory = KeyManagerFactory.getInstance(algorithm); 066 factory.init(keyStore, password.toCharArray()); 067 } catch (Exception e) { 068 throw new HeapException(loadingError(algorithm, storeRef), e); 069 } 070 071 // Retrieve manager 072 KeyManager[] managers = factory.getKeyManagers(); 073 if (managers.length == 1) { 074 return managers[0]; 075 } else if (managers.length > 1) { 076 logger.warning("Only the first KeyManager will be selected"); 077 return managers[0]; 078 } 079 throw new HeapException(loadingError(algorithm, storeRef)); 080 } 081 082 private String loadingError(final String algorithm, final JsonValue reference) { 083 return format("Cannot build KeyManager[alg:%s] from KeyStore %s", 084 algorithm, 085 reference.asString()); 086 } 087}