All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.integrations.oci.tls.certificates.DefaultOciCertificatesDownloader Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
/*
 * Copyright (c) 2023, 2024 Oracle and/or its affiliates.
 *
 * 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 io.helidon.integrations.oci.tls.certificates;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import io.helidon.common.Weight;
import io.helidon.common.Weighted;
import io.helidon.common.pki.PemReader;
import io.helidon.integrations.oci.tls.certificates.spi.OciCertificatesDownloader;
import io.helidon.service.registry.Service;

import com.oracle.bmc.auth.AbstractAuthenticationDetailsProvider;
import com.oracle.bmc.certificates.CertificatesClient;
import com.oracle.bmc.certificates.requests.GetCertificateAuthorityBundleRequest;
import com.oracle.bmc.certificates.requests.GetCertificateBundleRequest;
import com.oracle.bmc.certificates.responses.GetCertificateAuthorityBundleResponse;
import com.oracle.bmc.certificates.responses.GetCertificateBundleResponse;

import static io.helidon.integrations.oci.tls.certificates.spi.OciCertificatesDownloader.create;

/**
 * Implementation of the {@link OciCertificatesDownloader} that will use OCI's Certificates Service to download certs.
 */
@Service.Provider
@Weight(Weighted.DEFAULT_WEIGHT - 10)
class DefaultOciCertificatesDownloader implements OciCertificatesDownloader {
    private final AbstractAuthenticationDetailsProvider authProvider;

    DefaultOciCertificatesDownloader(AbstractAuthenticationDetailsProvider authProvider) {
        this.authProvider = authProvider;
    }

    @Override
    public Certificates loadCertificates(String certOcid) {
        Objects.requireNonNull(certOcid);
        try {
            return loadCerts(certOcid);
        } catch (RuntimeException e) {
            throw new IllegalStateException("Failed to load certificate ocid: " + certOcid, e);
        }
    }

    @Override
    public X509Certificate loadCACertificate(String caCertOcid) {
        Objects.requireNonNull(caCertOcid);
        try {
            return loadCACert(caCertOcid);
        } catch (RuntimeException e) {
            throw new IllegalStateException("Failed to load ca certificate ocid: " + caCertOcid, e);
        }
    }

    Certificates loadCerts(String certOcid) {
        try (CertificatesClient client = CertificatesClient.builder()
                .build(authProvider)) {
            GetCertificateBundleResponse res =
                    client.getCertificateBundle(GetCertificateBundleRequest.builder()
                                                        .certificateId(certOcid)
                                                        .build());
            ByteArrayInputStream chainIs = new ByteArrayInputStream(res.getCertificateBundle().getCertChainPem()
                                                                            .getBytes(StandardCharsets.US_ASCII));
            ByteArrayInputStream certIs = new ByteArrayInputStream(res.getCertificateBundle().getCertificatePem()
                                                                           .getBytes(StandardCharsets.US_ASCII));
            X509Certificate[] certs = toCertificates(chainIs, certIs);
            String version = toVersion(res.getEtag(), certs);
            return create(version, certs);
        }
    }

    X509Certificate loadCACert(String caCertOcid) {
        GetCertificateAuthorityBundleResponse res;
        try (CertificatesClient client = CertificatesClient.builder()
                .build(authProvider)) {
            res = client.getCertificateAuthorityBundle(GetCertificateAuthorityBundleRequest.builder()
                                                               .certificateAuthorityId(caCertOcid)
                                                               .build());

            ByteArrayInputStream certIs = new ByteArrayInputStream(res.getCertificateAuthorityBundle().getCertificatePem()
                    .getBytes(StandardCharsets.US_ASCII));
            return toCertificate(certIs);
        }
    }

    static X509Certificate[] toCertificates(InputStream chainIs,
                                            InputStream certIs) {
        ArrayList chain = new ArrayList<>();
        chain.addAll(PemReader.readCertificates(certIs));
        chain.addAll(PemReader.readCertificates(chainIs));
        return chain.toArray(new X509Certificate[0]);
    }

    static X509Certificate toCertificate(InputStream certIs) {
        List certs = PemReader.readCertificates(certIs);
        if (certs.size() != 1) {
            throw new IllegalStateException("Expected a single certificate in stream but found: " + certs.size());
        }
        return certs.getFirst();
    }

    // use the eTag, defaulting to the hash of the certs if not present
    static String toVersion(String eTag,
                            Certificate[] certs) {
        if (eTag != null && !eTag.isBlank()) {
            return eTag;
        }

        return String.valueOf(Arrays.hashCode(certs));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy