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