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 ForgeRock AS. 015 */ 016 017package org.forgerock.openig.security; 018 019import static java.lang.String.*; 020import static org.forgerock.openig.util.Json.*; 021 022import java.security.KeyStore; 023 024import javax.net.ssl.KeyManager; 025import javax.net.ssl.KeyManagerFactory; 026 027import org.forgerock.json.fluent.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 * { 035 * "name": "MyKeyManager", 036 * "type": "KeyManager", 037 * "config": { 038 * "keystore": "MyKeyStore", 039 * "password": "secret", 040 * "alg": "SunX509" 041 * } 042 * } 043 * </pre> 044 * <ul> 045 * <li>{@literal keystore}: Reference a KeyStore heap object (string, required).</li> 046 * <li>{@literal password}: credential required to read private keys from the key store (expression, required).</li> 047 * <li>{@literal alg}: key manager algorithm (defaults to platform's default type) (string, optional).</li> 048 * </ul> 049 * @since 3.1 050 */ 051public class KeyManagerHeaplet extends GenericHeaplet { 052 053 @Override 054 public Object create() throws HeapException { 055 JsonValue storeRef = config.get("keystore").required(); 056 KeyStore keyStore = heap.resolve(storeRef, KeyStore.class); 057 String password = evaluate(config.get("password").required()); 058 String algorithm = config.get("alg").defaultTo(KeyManagerFactory.getDefaultAlgorithm()).asString(); 059 060 // Initialize a KeyManagerFactory 061 KeyManagerFactory factory; 062 try { 063 factory = KeyManagerFactory.getInstance(algorithm); 064 factory.init(keyStore, password.toCharArray()); 065 } catch (Exception e) { 066 throw new HeapException(loadingError(algorithm, storeRef), e); 067 } 068 069 // Retrieve manager 070 KeyManager[] managers = factory.getKeyManagers(); 071 if (managers.length == 1) { 072 return managers[0]; 073 } else if (managers.length > 1) { 074 logger.warning("Only the first KeyManager will be selected"); 075 return managers[0]; 076 } 077 throw new HeapException(loadingError(algorithm, storeRef)); 078 } 079 080 private String loadingError(final String algorithm, final JsonValue reference) { 081 return format("Cannot build KeyManager[alg:%s] from KeyStore %s", 082 algorithm, 083 reference.asString()); 084 } 085}