alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (PemX509Certificate.java)

This example Java source code file (PemX509Certificate.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

bytebuf, certificate-----\n, certificateencodingexception, certificateexception, certificateexpiredexception, date, math, nosuchproviderexception, override, pemencoded, pemvalue, pemx509certificate, principal, security, string, unsupportedoperationexception, util

The PemX509Certificate.java Java example source code

/*
 * Copyright 2016 The Netty Project
 *
 * The Netty Project licenses this file to you 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.netty.handler.ssl;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.Set;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import io.netty.util.IllegalReferenceCountException;
import io.netty.util.internal.ObjectUtil;

/**
 * This is a special purpose implementation of a {@link X509Certificate} which allows
 * the user to pass PEM/PKCS#8 encoded data straight into {@link OpenSslContext} without
 * having to parse and re-encode bytes in Java land.
 *
 * All methods other than what's implemented in {@link PemEncoded}'s throw
 * {@link UnsupportedOperationException}s.
 *
 * @see PemEncoded
 * @see OpenSslContext
 * @see #valueOf(byte[])
 * @see #valueOf(ByteBuf)
 */
public final class PemX509Certificate extends X509Certificate implements PemEncoded {

    private static final byte[] BEGIN_CERT = "-----BEGIN CERTIFICATE-----\n".getBytes(CharsetUtil.US_ASCII);
    private static final byte[] END_CERT = "\n-----END CERTIFICATE-----\n".getBytes(CharsetUtil.US_ASCII);

    /**
     * Creates a {@link PemEncoded} value from the {@link X509Certificate}s.
     */
    static PemEncoded toPEM(ByteBufAllocator allocator, boolean useDirect,
            X509Certificate... chain) throws CertificateEncodingException {

        if (chain == null || chain.length == 0) {
            throw new IllegalArgumentException("X.509 certificate chain can't be null or empty");
        }

        // We can take a shortcut if there is only one certificate and
        // it already happens to be a PemEncoded instance. This is the
        // ideal case and reason why all this exists. It allows the user
        // to pass pre-encoded bytes straight into OpenSSL without having
        // to do any of the extra work.
        if (chain.length == 1) {
            X509Certificate first = chain[0];
            if (first instanceof PemEncoded) {
                return ((PemEncoded) first).retain();
            }
        }

        boolean success = false;
        ByteBuf pem = null;
        try {
            for (X509Certificate cert : chain) {

                if (cert == null) {
                    throw new IllegalArgumentException("Null element in chain: " + Arrays.toString(chain));
                }

                if (cert instanceof PemEncoded) {
                    pem = append(allocator, useDirect, (PemEncoded) cert, chain.length, pem);
                } else {
                    pem = append(allocator, useDirect, cert, chain.length, pem);
                }
            }

            PemValue value = new PemValue(pem, false);
            success = true;
            return value;
        } finally {
            // Make sure we never leak the PEM's ByteBuf in the event of an Exception
            if (!success && pem != null) {
                pem.release();
            }
        }
    }

    /**
     * Appends the {@link PemEncoded} value to the {@link ByteBuf} (last arg) and returns it.
     * If the {@link ByteBuf} didn't exist yet it'll create it using the {@link ByteBufAllocator}.
     */
    private static ByteBuf append(ByteBufAllocator allocator, boolean useDirect,
            PemEncoded encoded, int count, ByteBuf pem) {

        ByteBuf content = encoded.content();

        if (pem == null) {
            // see the other append() method
            pem = newBuffer(allocator, useDirect, content.readableBytes() * count);
        }

        pem.writeBytes(content.slice());
        return pem;
    }

    /**
     * Appends the {@link X509Certificate} value to the {@link ByteBuf} (last arg) and returns it.
     * If the {@link ByteBuf} didn't exist yet it'll create it using the {@link ByteBufAllocator}.
     */
    private static ByteBuf append(ByteBufAllocator allocator, boolean useDirect,
            X509Certificate cert, int count, ByteBuf pem) throws CertificateEncodingException {

        ByteBuf encoded = Unpooled.wrappedBuffer(cert.getEncoded());
        try {
            ByteBuf base64 = SslUtils.toBase64(allocator, encoded);
            try {
                if (pem == null) {
                    // We try to approximate the buffer's initial size. The sizes of
                    // certificates can vary a lot so it'll be off a bit depending
                    // on the number of elements in the array (count argument).
                    pem = newBuffer(allocator, useDirect,
                            (BEGIN_CERT.length + base64.readableBytes() + END_CERT.length) * count);
                }

                pem.writeBytes(BEGIN_CERT);
                pem.writeBytes(base64);
                pem.writeBytes(END_CERT);
            } finally {
                base64.release();
            }
        } finally {
            encoded.release();
        }

        return pem;
    }

    private static ByteBuf newBuffer(ByteBufAllocator allocator, boolean useDirect, int initialCapacity) {
        return useDirect ? allocator.directBuffer(initialCapacity) : allocator.buffer(initialCapacity);
    }

    /**
     * Creates a {@link PemX509Certificate} from raw {@code byte[]}.
     *
     * ATTENTION: It's assumed that the given argument is a PEM/PKCS#8 encoded value.
     * No input validation is performed to validate it.
     */
    public static PemX509Certificate valueOf(byte[] key) {
        return valueOf(Unpooled.wrappedBuffer(key));
    }

    /**
     * Creates a {@link PemX509Certificate} from raw {@code ByteBuf}.
     *
     * ATTENTION: It's assumed that the given argument is a PEM/PKCS#8 encoded value.
     * No input validation is performed to validate it.
     */
    public static PemX509Certificate valueOf(ByteBuf key) {
        return new PemX509Certificate(key);
    }

    private final ByteBuf content;

    private PemX509Certificate(ByteBuf content) {
        this.content = ObjectUtil.checkNotNull(content, "content");
    }

    @Override
    public boolean isSensitive() {
        // There is no sensitive information in a X509 Certificate
        return false;
    }

    @Override
    public int refCnt() {
        return content.refCnt();
    }

    @Override
    public ByteBuf content() {
        int count = refCnt();
        if (count <= 0) {
            throw new IllegalReferenceCountException(count);
        }

        return content;
    }

    @Override
    public PemX509Certificate copy() {
        return replace(content.copy());
    }

    @Override
    public PemX509Certificate duplicate() {
        return replace(content.duplicate());
    }

    @Override
    public PemX509Certificate retainedDuplicate() {
        return replace(content.retainedDuplicate());
    }

    @Override
    public PemX509Certificate replace(ByteBuf content) {
        return new PemX509Certificate(content);
    }

    @Override
    public PemX509Certificate retain() {
        content.retain();
        return this;
    }

    @Override
    public PemX509Certificate retain(int increment) {
        content.retain(increment);
        return this;
    }

    @Override
    public PemX509Certificate touch() {
        content.touch();
        return this;
    }

    @Override
    public PemX509Certificate touch(Object hint) {
        content.touch(hint);
        return this;
    }

    @Override
    public boolean release() {
        return content.release();
    }

    @Override
    public boolean release(int decrement) {
        return content.release(decrement);
    }

    @Override
    public byte[] getEncoded() throws CertificateEncodingException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean hasUnsupportedCriticalExtension() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set<String> getCriticalExtensionOIDs() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set<String> getNonCriticalExtensionOIDs() {
        throw new UnsupportedOperationException();
    }

    @Override
    public byte[] getExtensionValue(String oid) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void checkValidity() throws CertificateExpiredException,
            CertificateNotYetValidException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void checkValidity(Date date) throws CertificateExpiredException,
            CertificateNotYetValidException {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getVersion() {
        throw new UnsupportedOperationException();
    }

    @Override
    public BigInteger getSerialNumber() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Principal getIssuerDN() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Principal getSubjectDN() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Date getNotBefore() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Date getNotAfter() {
        throw new UnsupportedOperationException();
    }

    @Override
    public byte[] getTBSCertificate() throws CertificateEncodingException {
        throw new UnsupportedOperationException();
    }

    @Override
    public byte[] getSignature() {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getSigAlgName() {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getSigAlgOID() {
        throw new UnsupportedOperationException();
    }

    @Override
    public byte[] getSigAlgParams() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean[] getIssuerUniqueID() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean[] getSubjectUniqueID() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean[] getKeyUsage() {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getBasicConstraints() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void verify(PublicKey key)
            throws CertificateException, NoSuchAlgorithmException,
            InvalidKeyException, NoSuchProviderException, SignatureException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void verify(PublicKey key, String sigProvider)
            throws CertificateException, NoSuchAlgorithmException,
            InvalidKeyException, NoSuchProviderException, SignatureException {
        throw new UnsupportedOperationException();
    }

    @Override
    public PublicKey getPublicKey() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof PemX509Certificate)) {
            return false;
        }

        PemX509Certificate other = (PemX509Certificate) o;
        return content.equals(other.content);
    }

    @Override
    public int hashCode() {
        return content.hashCode();
    }

    @Override
    public String toString() {
        return content.toString(CharsetUtil.UTF_8);
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java PemX509Certificate.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.