001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2013 ForgeRock AS. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * http://forgerock.org/license/CDDLv1.0.html
013 * See the License for the specific language governing
014 * permission and limitations under the License.
015 *
016 * When distributing Covered Code, include this CDDL
017 * Header Notice in each file and include the License file
018 * at http://forgerock.org/license/CDDLv1.0.html
019 * If applicable, add the following below the CDDL Header,
020 * with the fields enclosed by brackets [] replaced by
021 * your own identifying information:
022 * "Portions Copyrighted [year] [name of copyright owner]"
023 */
024
025package org.forgerock.audit.secure;
026
027import java.io.BufferedInputStream;
028import java.io.BufferedOutputStream;
029import java.io.File;
030import java.io.FileInputStream;
031import java.io.FileOutputStream;
032import java.io.IOException;
033import java.io.InputStream;
034import java.io.OutputStream;
035import java.security.KeyStore;
036import java.security.KeyStoreException;
037import java.security.NoSuchAlgorithmException;
038import java.security.cert.CertificateException;
039
040/**
041 * Default implementation of a Keystore handler.
042 */
043public class JcaKeyStoreHandler implements KeyStoreHandler {
044
045    private final String location;
046    private final String password;
047    private final String type;
048    private KeyStore store;
049
050    /**
051     * Creates a new keystore handler.
052     *
053     * @param type
054     *          The type of keystore
055     * @param location
056     *          The path of the keystore
057     * @param password
058     *          The password to access the keystore
059     * @throws Exception
060     *          If an error occurs while initialising the keystore
061     */
062    public JcaKeyStoreHandler(String type, String location, String password) throws Exception {
063        this.location = location;
064        this.password = password;
065        this.type = type;
066        init();
067    }
068
069    private void init() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
070        File ksFile = new File(location);
071        store = KeyStore.getInstance(type);
072        if (ksFile.exists()) {
073            try (InputStream in = new BufferedInputStream(new FileInputStream(location))) {
074                store.load(in, password.toCharArray());
075            }
076        } else {
077            // Create an empty one
078            store.load(null, password.toCharArray());
079        }
080    }
081
082    @Override
083    public KeyStore getStore() {
084        return store;
085    }
086
087    @Override
088    public void setStore(KeyStore keystore) throws Exception {
089        store = keystore;
090        store();
091    }
092
093    @Override
094    public void store() throws Exception {
095        try (OutputStream out = new BufferedOutputStream(new FileOutputStream(location))) {
096            store.store(out, password.toCharArray());
097        }
098    }
099
100    @Override
101    public String getPassword() {
102        return password;
103    }
104
105    @Override
106    public String getLocation() {
107        return location;
108    }
109
110    @Override
111    public String getType() {
112        return type;
113    }
114}