CertificateSigner.java

  1. /*
  2.  * Copyright (C) 2020-2024 by Savoir-faire Linux
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 3 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  16.  */
  17. package net.jami.jams.ca.workers.csr.utils;

  18. import lombok.extern.slf4j.Slf4j;

  19. import net.jami.jams.ca.JamsCA;

  20. import org.bouncycastle.asn1.ASN1Encodable;
  21. import org.bouncycastle.asn1.ASN1ObjectIdentifier;
  22. import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
  23. import org.bouncycastle.asn1.x509.Certificate;
  24. import org.bouncycastle.cert.X509v3CertificateBuilder;
  25. import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
  26. import org.bouncycastle.crypto.util.PrivateKeyFactory;
  27. import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
  28. import org.bouncycastle.operator.ContentSigner;
  29. import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
  30. import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
  31. import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;

  32. import java.io.ByteArrayInputStream;
  33. import java.security.PrivateKey;
  34. import java.security.cert.X509Certificate;

  35. @Slf4j
  36. public class CertificateSigner {

  37.     public static X509Certificate signCertificate(
  38.             PrivateKey privateKey,
  39.             X509v3CertificateBuilder certificateBuilder,
  40.             CertificateExtendedData certificateExtendedData) {
  41.         try {
  42.             // Appose the extended data from the template.
  43.             for (Object[] extensions : certificateExtendedData.getExtensions()) {
  44.                 certificateBuilder.addExtension(
  45.                         (ASN1ObjectIdentifier) extensions[0],
  46.                         (boolean) extensions[1],
  47.                         (ASN1Encodable) extensions[2]);
  48.             }
  49.             // Initialize the signing.
  50.             AlgorithmIdentifier sigAlgId =
  51.                     new DefaultSignatureAlgorithmIdentifierFinder().find(JamsCA.signingAlgorithm);
  52.             AlgorithmIdentifier digAlgId =
  53.                     new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
  54.             AsymmetricKeyParameter asymmetricKeyParameter =
  55.                     PrivateKeyFactory.createKey(privateKey.getEncoded());
  56.             // Sign the certificate.
  57.             ContentSigner sigGen =
  58.                     new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(asymmetricKeyParameter);
  59.             Certificate eeX509CertificateStructure =
  60.                     certificateBuilder.build(sigGen).toASN1Structure();
  61.             return (X509Certificate)
  62.                     new CertificateFactory()
  63.                             .engineGenerateCertificate(
  64.                                     new ByteArrayInputStream(
  65.                                             eeX509CertificateStructure.getEncoded()));
  66.         } catch (Exception e) {
  67.             log.error("An error occurred while signing certificate: " + e);
  68.             return null;
  69.         }
  70.     }
  71. }