Java tutorial
/* * Copyright (c) 2018 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.mica.dataset.service; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyStoreException; import java.security.cert.Certificate; import java.util.Optional; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.security.auth.callback.CallbackHandler; import javax.validation.constraints.NotNull; import org.bouncycastle.openssl.PEMWriter; import org.obiba.mica.micaConfig.service.MicaConfigService; import org.obiba.security.KeyStoreManager; import org.obiba.security.KeyStoreRepository; import org.springframework.stereotype.Service; import com.google.common.base.Strings; import static java.util.Optional.ofNullable; /** * */ @Service public class KeyStoreService { public static final String SYSTEM_KEY_STORE = "system"; private static final String PATH_KEYSTORE = "${MICA_HOME}/data/keystores"; @Inject private MicaConfigService micaConfigService; @Inject private CallbackHandler callbackHandler; private File keystoresRoot; private final KeyStoreRepository keyStoreRepository = new KeyStoreRepository(); @PostConstruct public void init() { if (keystoresRoot == null) { keystoresRoot = new File(PATH_KEYSTORE.replace("${MICA_HOME}", System.getProperty("MICA_HOME"))); } keyStoreRepository.setKeyStoresDirectory(keystoresRoot); keyStoreRepository.setCallbackHandler(callbackHandler); } @NotNull public KeyStoreManager getSystemKeyStore() { return keyStoreRepository.getOrCreateKeyStore(SYSTEM_KEY_STORE); } public void saveKeyStore(@NotNull KeyStoreManager keyStore) { keyStoreRepository.saveKeyStore(keyStore); } @NotNull public KeyStoreManager getKeyStore(@NotNull String name) { return keyStoreRepository.getOrCreateKeyStore(name); } @NotNull public String getPEMCertificate(@NotNull String name, String alias) throws KeyStoreException, IOException { Certificate certificate = ofNullable(getKeyStore(name).getKeyStore().getCertificate(alias)) .orElseThrow(() -> new IllegalArgumentException("Cannot find certificate for alias: " + alias)); StringWriter writer = new StringWriter(); PEMWriter pemWriter = new PEMWriter(writer); pemWriter.writeObject(certificate); pemWriter.flush(); return writer.getBuffer().toString(); } public void createOrUpdateCertificate(String name, String alias, String publicCertificate) { KeyStoreManager ksm = getKeyStore(name); ksm.importCertificate(alias, new ByteArrayInputStream(publicCertificate.getBytes())); saveKeyStore(ksm); } public void createOrUpdateCertificate(String name, String alias, String algo, int size, String cn, String ou, String o, String locality, String state, String country) { KeyStoreManager ksm = getKeyStore(name); ksm.createOrUpdateKey(alias, algo, size, getCertificateInfo(cn, ou, o, locality, state, country)); saveKeyStore(ksm); } public void createOrUpdateCertificate(String name, String alias, String privateKey, String cn, String ou, String o, String locality, String state, String country) { KeyStoreManager ksm = getKeyStore(name); ksm.importKey(alias, new ByteArrayInputStream(privateKey.getBytes()), getCertificateInfo(cn, ou, o, locality, state, country)); saveKeyStore(ksm); } public void createOrUpdateCertificate(String name, String alias, String privateKey, String publicCertificate) { KeyStoreManager ksm = getKeyStore(name); ksm.importKey(alias, new ByteArrayInputStream(privateKey.getBytes()), new ByteArrayInputStream(publicCertificate.getBytes())); saveKeyStore(ksm); } public void deleteKeyPair(String name, String alias) { KeyStoreManager ksm = getKeyStore(name); if (ksm.hasKeyPair(alias)) { ksm.deleteKey(alias); saveKeyStore(ksm); } } private String getCertificateInfo(String cn, String ou, String o, String locality, String state, String country) { return validateNameAndOrganizationInfo(cn, ou, o) + ", L=" + ofNullable(locality).orElse("") + ", ST=" + ofNullable(state).orElse("") + ", C=" + ofNullable(country).orElse(""); } private String validateNameAndOrganizationInfo(String cn, String ou, String o) { Optional<String> hostname = Optional.empty(); if (Strings.isNullOrEmpty(cn) || Strings.isNullOrEmpty(o)) { try { hostname = Optional.of(new URL(micaConfigService.getConfig().getPublicUrl()).getHost()); } catch (MalformedURLException e) { //ignore } } return String.format("CN=%s, OU=%s, O=%s", Strings.isNullOrEmpty(cn) ? hostname.orElse("") : cn, Strings.isNullOrEmpty(ou) ? "mica" : ou, ofNullable(o).orElse("")); } }