001/*
002 * **** BEGIN LICENSE BLOCK *****
003 *  Version: MPL 1.1/GPL 2.0/LGPL 2.1
004 *
005 *  The contents of this file are subject to the Mozilla Public License Version
006 *  1.1 (the "License"); you may not use this file except in compliance with
007 *  the License. You may obtain a copy of the License at
008 *  http://www.mozilla.org/MPL/
009 *
010 *  Software distributed under the License is distributed on an "AS IS" basis,
011 *  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012 *  for the specific language governing rights and limitations under the
013 *  License.
014 *
015 *  The Original Code is part of dcm4che, an implementation of DICOM(TM) in
016 *  Java(TM), hosted at https://github.com/gunterze/dcm4che.
017 *
018 *  The Initial Developer of the Original Code is
019 *  Agfa Healthcare.
020 *  Portions created by the Initial Developer are Copyright (C) 2014
021 *  the Initial Developer. All Rights Reserved.
022 *
023 *  Contributor(s):
024 *  See @authors listed below
025 *
026 *  Alternatively, the contents of this file may be used under the terms of
027 *  either the GNU General Public License Version 2 or later (the "GPL"), or
028 *  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
029 *  in which case the provisions of the GPL or the LGPL are applicable instead
030 *  of those above. If you wish to allow use of your version of this file only
031 *  under the terms of either the GPL or the LGPL, and not to allow others to
032 *  use your version of this file under the terms of the MPL, indicate your
033 *  decision by deleting the provisions above and replace them with the notice
034 *  and other provisions required by the GPL or the LGPL. If you do not delete
035 *  the provisions above, a recipient may use your version of this file under
036 *  the terms of any one of the MPL, the GPL or the LGPL.
037 *
038 *  ***** END LICENSE BLOCK *****
039 */
040package org.dcm4che3.conf.core.adapters;
041
042import org.dcm4che3.conf.core.api.internal.ConfigProperty;
043import org.dcm4che3.conf.core.context.LoadingContext;
044import org.dcm4che3.conf.core.context.ProcessingContext;
045import org.dcm4che3.conf.core.context.SavingContext;
046import org.dcm4che3.conf.core.api.internal.ConfigTypeAdapter;
047import org.dcm4che3.conf.core.api.ConfigurationException;
048import org.dcm4che3.util.Base64;
049
050import java.io.ByteArrayInputStream;
051import java.security.cert.CertificateEncodingException;
052import java.security.cert.CertificateException;
053import java.security.cert.CertificateFactory;
054import java.security.cert.X509Certificate;
055import java.util.HashMap;
056import java.util.Map;
057
058/**
059 * @author Roman K
060 */
061public class X509CertificateAdapter implements ConfigTypeAdapter<X509Certificate, String> {
062
063    private CertificateFactory certificateFactory;
064
065    @Override
066    public X509Certificate fromConfigNode(String configNode, ConfigProperty property, LoadingContext ctx, Object parent) throws ConfigurationException {
067        try {
068            final byte[] base64 = Base64.fromBase64(configNode);
069            return (X509Certificate) getX509Factory().generateCertificate(new ByteArrayInputStream(base64));
070        } catch (CertificateException e) {
071            throw new ConfigurationException("Cannot initialize X509 certificate converter", e);
072        } catch (Exception e) {
073            throw new ConfigurationException("Cannot read the X509 certificate", e);
074        }
075    }
076
077    private CertificateFactory getX509Factory() throws CertificateException {
078        if (certificateFactory == null) certificateFactory = CertificateFactory.getInstance("X509");
079        return certificateFactory;
080    }
081
082    @Override
083    public String toConfigNode(X509Certificate object, ConfigProperty property, SavingContext ctx) throws ConfigurationException {
084        try {
085            return Base64.toBase64(object.getEncoded());
086        } catch (CertificateEncodingException e) {
087            throw new ConfigurationException("Cannot encode X509 certificate", e);
088        }
089    }
090
091    @Override
092    public Map<String, Object> getSchema(ConfigProperty property, ProcessingContext ctx) throws ConfigurationException {
093        Map<String, Object> metadata = new HashMap<String, Object>();
094        metadata.put("type", "string");
095        metadata.put("class", "Base64,X509");
096        return metadata;
097    }
098
099    @Override
100    public String normalize(Object configNode, ConfigProperty property, ProcessingContext ctx) throws ConfigurationException {
101        return (String) configNode;
102    }
103}