org.midonet.api.auth.vsphere.FingerprintTrustManager.java Source code

Java tutorial

Introduction

Here is the source code for org.midonet.api.auth.vsphere.FingerprintTrustManager.java

Source

/*
 * Copyright 2014 Midokura SARL
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.midonet.api.auth.vsphere;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.X509TrustManager;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An {@code X509TrustManager} that trust the server certificates based on
 * a configured fingerprint.
 * The security of this method depends on the security of the cryptographic
 * hash chosen, in this case SHA-1: stronger then MD5, keep the configuration
 * simple and although not the strongest (some weaknesses have been proved
 * compared to the SHA-2 family) it's reasonably strong within the context of a
 * private cloud
 */
public class FingerprintTrustManager implements X509TrustManager {

    private static final Logger log = LoggerFactory.getLogger(FingerprintTrustManager.class);

    private final String trustedFingerprint;

    /**
     * @param trustedFingerprint
     *        The server certificate fingerprint in the form of an hex SHA-1
     *        hash, eg:
     *        "20:4D:FB:4E:07:D8:E3:7F:67:AD:93:1A:8A:64:65:49:12:E8:50:88"
     */
    public FingerprintTrustManager(String trustedFingerprint) {
        this.trustedFingerprint = trustedFingerprint;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        Preconditions.checkArgument(chain != null && chain.length > 0);
        Preconditions.checkArgument(!StringUtils.isEmpty(authType));
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        Preconditions.checkArgument(chain != null && chain.length > 0);
        Preconditions.checkArgument(!StringUtils.isEmpty(authType));

        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            throw new CertificateException(e);
        }

        for (X509Certificate certificate : chain) {
            final byte[] rawCertificateFingerprint = messageDigest.digest(certificate.getEncoded());

            final List<String> hexCertificateFingerprint = new ArrayList<>();

            for (byte aByte : rawCertificateFingerprint) {
                hexCertificateFingerprint.add(String.format("%02X", aByte));
            }

            final String fullCertificateFingerprint = Joiner.on(":").join(hexCertificateFingerprint);

            log.debug(String.format("Checking fingerprint %s for certificate %s", fullCertificateFingerprint,
                    certificate.getSubjectDN()));

            if (trustedFingerprint.equalsIgnoreCase(fullCertificateFingerprint)) {
                log.debug(String.format("Found a the trusted fingerprint %s " + "for certificate %s",
                        fullCertificateFingerprint, certificate.getSubjectDN()));
                return;
            }
        }

        throw new CertificateException("No trusted certificate found");
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[] {};
    }
}