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 2013-2016 ForgeRock AS.
015 */
016
017package org.forgerock.audit.secure;
018
019import java.io.BufferedInputStream;
020import java.io.BufferedOutputStream;
021import java.io.File;
022import java.io.FileInputStream;
023import java.io.FileOutputStream;
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.OutputStream;
027import java.security.KeyStore;
028import java.security.KeyStoreException;
029import java.security.NoSuchAlgorithmException;
030import java.security.cert.CertificateException;
031
032/**
033 * Default implementation of a Keystore handler.
034 */
035public class JcaKeyStoreHandler implements KeyStoreHandler {
036
037    private final String location;
038    private final String password;
039    private final String type;
040    private KeyStore store;
041
042    /**
043     * Creates a new keystore handler.
044     *
045     * @param type
046     *          The type of keystore
047     * @param location
048     *          The path of the keystore
049     * @param password
050     *          The password to access the keystore
051     * @throws Exception
052     *          If an error occurs while initialising the keystore
053     */
054    public JcaKeyStoreHandler(String type, String location, String password) throws Exception {
055        this.location = location;
056        this.password = password;
057        this.type = type;
058        init();
059    }
060
061    private void init() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
062        File ksFile = new File(location);
063        store = KeyStore.getInstance(type);
064        if (ksFile.exists()) {
065            try (InputStream in = new BufferedInputStream(new FileInputStream(location))) {
066                store.load(in, password.toCharArray());
067            }
068        } else {
069            // Create an empty one
070            store.load(null, password.toCharArray());
071        }
072    }
073
074    @Override
075    public KeyStore getStore() {
076        return store;
077    }
078
079    @Override
080    public void setStore(KeyStore keystore) throws Exception {
081        store = keystore;
082        store();
083    }
084
085    @Override
086    public void store() throws Exception {
087        try (OutputStream out = new BufferedOutputStream(new FileOutputStream(location))) {
088            store.store(out, password.toCharArray());
089        }
090    }
091
092    @Override
093    public String getPassword() {
094        return password;
095    }
096
097    @Override
098    public String getLocation() {
099        return location;
100    }
101
102    @Override
103    public String getType() {
104        return type;
105    }
106}