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

org.xwiki.crypto.pkix.internal.BcUtils Maven / Gradle / Ivy

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.crypto.pkix.internal;

import java.io.IOException;
import java.io.OutputStream;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.operator.ContentSigner;
import org.xwiki.crypto.internal.asymmetric.BcAsymmetricKeyParameters;
import org.xwiki.crypto.internal.asymmetric.BcPublicKeyParameters;
import org.xwiki.crypto.params.cipher.asymmetric.PublicKeyParameters;
import org.xwiki.crypto.pkix.CertificateFactory;
import org.xwiki.crypto.pkix.params.CertifiedPublicKey;
import org.xwiki.crypto.pkix.params.PrincipalIndentifier;
import org.xwiki.crypto.signer.Signer;

/**
 * Utility class for converting values from/into Bouncy Castle equivalents.
 *
 * @version $Id: cc7166845018fcd9865813b8228c19ceeef3f9f8 $
 * @since 5.4
 */
public final class BcUtils
{
    private BcUtils()
    {
        // Utility class.
    }

    /**
     * Convert certified public key to certificate holder.
     *
     * @param cert the certified public key.
     * @return a certificate holder.
     */
    public static X509CertificateHolder getX509CertificateHolder(CertifiedPublicKey cert)
    {
        if (cert instanceof BcX509CertifiedPublicKey) {
            return ((BcX509CertifiedPublicKey) cert).getX509CertificateHolder();
        } else {
            try {
                return new X509CertificateHolder(cert.getEncoded());
            } catch (IOException e) {
                // Very unlikely
                throw new IllegalArgumentException("Invalid certified public key, unable to encode.");
            }
        }

    }

    /**
     * Convert public key parameters to asymmetric key parameter.
     *
     * @param publicKey the public key parameter to convert.
     * @return an asymmetric key parameter.
     */
    public static AsymmetricKeyParameter getAsymmetricKeyParameter(PublicKeyParameters publicKey)
    {
        if (publicKey instanceof BcAsymmetricKeyParameters) {
            return ((BcAsymmetricKeyParameters) publicKey).getParameters();
        } else {
            try {
                return PublicKeyFactory.createKey(publicKey.getEncoded());
            } catch (IOException e) {
                // Very unlikely
                throw new IllegalArgumentException("Invalid public key, unable to encode.");
            }
        }

    }

    /**
     * Convert public key parameter to subject public key info.
     *
     * @param publicKey the public key to convert.
     * @return a subject public key info.
     */
    public static SubjectPublicKeyInfo getSubjectPublicKeyInfo(PublicKeyParameters publicKey)
    {
        try {
            if (publicKey instanceof BcPublicKeyParameters) {
                return ((BcPublicKeyParameters) publicKey).getSubjectPublicKeyInfo();
            } else {
                return SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(getAsymmetricKeyParameter(publicKey));
            }
        } catch (IOException e) {
            // Very unlikely
            throw new IllegalArgumentException("Invalid public key, unable to get subject info.");
        }
    }

    /**
     * Build the structure of an X.509 certificate.
     *
     * @param tbsCert the to be signed structure
     * @param signature the signature
     * @return a X.509 certificate holder.
     */
    public static X509CertificateHolder getX509CertificateHolder(TBSCertificate tbsCert, byte[] signature)
    {
        ASN1EncodableVector v = new ASN1EncodableVector();

        v.add(tbsCert);
        v.add(tbsCert.getSignature());
        v.add(new DERBitString(signature));

        return new X509CertificateHolder(Certificate.getInstance(new DERSequence(v)));
    }

    /**
     * Compare two algorithm identifier.
     *
     * @param id1 an algorithm identifier.
     * @param id2 another algorithm identifier.
     * @return true if both algorithm identifier are equals, false otherwise.
     */
    public static boolean isAlgorithlIdentifierEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
    {
        if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
        {
            return false;
        }

        if (id1.getParameters() == null)
        {
            return !(id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE));
        }

        if (id2.getParameters() == null)
        {
            return !(id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE));
        }

        return id1.getParameters().equals(id2.getParameters());
    }

    /**
     * DER encode an ASN.1 object into the given signer and return the signer.
     *
     * @param signer a signer.
     * @param tbsObj the object to sign.
     * @return a the signer for chaining.
     * @throws java.io.IOException on encoding error.
     */
    public static Signer updateDEREncodedObject(Signer signer, ASN1Encodable tbsObj)
        throws IOException
    {
        OutputStream sOut = signer.getOutputStream();
        ASN1OutputStream dOut = ASN1OutputStream.create(sOut);

        dOut.writeObject(tbsObj);

        sOut.close();

        return signer;
    }

    /**
     * Convert principal identifier to X.500 name.
     *
     * @param principal principal identifier to convert.
     * @return an X.500 name.
     */
    public static X500Name getX500Name(PrincipalIndentifier principal)
    {
        if (principal instanceof BcPrincipalIdentifier) {
            return ((BcPrincipalIdentifier) principal).getX500Name();
        } else {
            return new X500Name(principal.getName());
        }
    }

    /**
     * Get the algorithm identifier of a signer.
     *
     * @param signer the signer.
     * @return an algorithm identifier.
     */
    public static AlgorithmIdentifier getSignerAlgoritmIdentifier(Signer signer)
    {
        if (signer instanceof ContentSigner) {
            return ((ContentSigner) signer).getAlgorithmIdentifier();
        } else {
            return AlgorithmIdentifier.getInstance(signer.getEncoded());
        }
    }

    /**
     * Convert a Bouncy Castle certificate holder into a certified public key.
     *
     * @param certFactory the certificate factory to be used for conversion.
     * @param cert the certificate to convert.
     * @return a certified public key wrapping equivalent to the provided holder.
     * @since 6.0M1
     */
    public static CertifiedPublicKey convertCertificate(CertificateFactory certFactory, X509CertificateHolder cert)
    {
        if (cert == null) {
            return null;
        }

        if (certFactory instanceof BcX509CertificateFactory) {
            return ((BcX509CertificateFactory) certFactory).convert(cert);
        } else {
            try {
                return certFactory.decode(cert.getEncoded());
            } catch (IOException e) {
                // Very unlikely
                throw new IllegalArgumentException("Invalid Certificate, unable to encode", e);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy