From dfe957b0193cf2fd8b4f42205f0bcc164405b014 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Sun, 9 Apr 2023 11:50:14 +0530 Subject: [PATCH] Add SCEP support fixes https://roadmap.entgra.net/issues/10042 --- .../mgt/core/impl/CertificateGenerator.java | 117 +++++++++++++++++- .../service/CertificateManagementService.java | 2 + .../CertificateManagementServiceImpl.java | 5 + .../util/CertificateManagementConstants.java | 1 + 4 files changed, 119 insertions(+), 6 deletions(-) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java index 2cb6d4098f8..20b4833d562 100755 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java @@ -44,12 +44,17 @@ import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.util.Store; -import org.jscep.message.*; +import org.jscep.message.CertRep; +import org.jscep.message.MessageDecodingException; +import org.jscep.message.MessageEncodingException; +import org.jscep.message.PkcsPkiEnvelopeDecoder; +import org.jscep.message.PkcsPkiEnvelopeEncoder; +import org.jscep.message.PkiMessage; +import org.jscep.message.PkiMessageDecoder; +import org.jscep.message.PkiMessageEncoder; import org.jscep.transaction.FailInfo; import org.jscep.transaction.Nonce; import org.jscep.transaction.TransactionId; -import org.wso2.carbon.certificate.mgt.core.cache.CertificateCacheManager; -import org.wso2.carbon.certificate.mgt.core.cache.impl.CertificateCacheManagerImpl; import org.wso2.carbon.certificate.mgt.core.dao.CertificateDAO; import org.wso2.carbon.certificate.mgt.core.dao.CertificateManagementDAOException; import org.wso2.carbon.certificate.mgt.core.dao.CertificateManagementDAOFactory; @@ -72,13 +77,31 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; -import java.security.*; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; import java.security.cert.Certificate; -import java.security.cert.*; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.concurrent.TimeUnit; public class CertificateGenerator { @@ -757,4 +780,86 @@ public class CertificateGenerator { return generateCertificateFromCSR(privateKeyCA, certificationRequest, certCA.getIssuerX500Principal().getName()); } -} + + public X509Certificate generateAlteredCertificateFromCSR(String csr) + throws KeystoreException { + byte[] byteArrayBst = DatatypeConverter.parseBase64Binary(csr); + PKCS10CertificationRequest certificationRequest; + KeyStoreReader keyStoreReader = new KeyStoreReader(); + PrivateKey privateKeyCA = keyStoreReader.getCAPrivateKey(); + X509Certificate certCA = (X509Certificate) keyStoreReader.getCACertificate(); + + X509Certificate issuedCert; + try { + certificationRequest = new PKCS10CertificationRequest(byteArrayBst); + JcaContentSignerBuilder csBuilder = + new JcaContentSignerBuilder(CertificateManagementConstants.SIGNING_ALGORITHM); + ContentSigner signer = csBuilder.build(privateKeyCA); + + BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); + + X500Name issuerName = new X500Name(certCA.getSubjectDN().getName()); + + String commonName = certificationRequest.getSubject().getRDNs(BCStyle.CN)[0].getFirst() + .getValue().toString(); + X500Name subjectName = new X500Name("O=" + commonName + "O=AndroidDevice,CN=" + + serialNumber); + Date startDate = new Date(System.currentTimeMillis()); + Date endDate = new Date(System.currentTimeMillis() + + TimeUnit.DAYS.toMillis(365 * 100)); + PublicKey publicKey = getPublicKeyFromRequest(certificationRequest); + + X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( + issuerName, serialNumber, startDate, endDate, + subjectName, publicKey); + + X509CertificateHolder certHolder = certBuilder.build(signer); + + CertificateFactory certificateFactory = CertificateFactory.getInstance + (CertificateManagementConstants.X_509); + byte[] encodedCertificate = certHolder.getEncoded(); + issuedCert = (X509Certificate) certificateFactory + .generateCertificate(new ByteArrayInputStream(encodedCertificate)); + + org.wso2.carbon.certificate.mgt.core.bean.Certificate certificate = + new org.wso2.carbon.certificate.mgt.core.bean.Certificate(); + List certificates = new ArrayList<>(); + certificate.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); + certificate.setCertificate(issuedCert); + certificates.add(certificate); + saveCertInKeyStore(certificates); + + } catch (OperatorCreationException e) { + String errorMsg = "Error creating the content signer"; + log.error(errorMsg); + throw new KeystoreException(errorMsg, e); + } catch (CertificateException e) { + String errorMsg = "Error when opening the newly created certificate"; + log.error(errorMsg); + throw new KeystoreException(errorMsg, e); + } catch (InvalidKeySpecException e) { + String errorMsg = "Public key is having invalid specification"; + log.error(errorMsg); + throw new KeystoreException(errorMsg, e); + } catch (NoSuchAlgorithmException e) { + String errorMsg = "Could not find RSA algorithm"; + log.error(errorMsg); + throw new KeystoreException(errorMsg, e); + } catch (IOException e) { + String errorMsg = "Error while reading the csr"; + log.error(errorMsg); + throw new KeystoreException(errorMsg, e); + } + return issuedCert; + } + + private static PublicKey getPublicKeyFromRequest(PKCS10CertificationRequest request) + throws InvalidKeySpecException, NoSuchAlgorithmException, IOException { + byte[] publicKeyBytes = request.getSubjectPublicKeyInfo().getEncoded(); + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); + return publicKey; + } + +} \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementService.java index becd68720b1..393dbdd0ede 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementService.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementService.java @@ -79,4 +79,6 @@ public interface CertificateManagementService { List searchCertificates(String serialNumber) throws CertificateManagementException; + X509Certificate generateAlteredCertificateFromCSR(String csr) throws KeystoreException; + } diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementServiceImpl.java index c47472f35c0..67cca297c46 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementServiceImpl.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/service/CertificateManagementServiceImpl.java @@ -234,4 +234,9 @@ public class CertificateManagementServiceImpl implements CertificateManagementSe } } + @Override + public X509Certificate generateAlteredCertificateFromCSR(String csr) throws KeystoreException{ + return certificateGenerator.generateAlteredCertificateFromCSR(csr); + } + } diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/util/CertificateManagementConstants.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/util/CertificateManagementConstants.java index 5e5f02c7f08..96c6cc2148d 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/util/CertificateManagementConstants.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/util/CertificateManagementConstants.java @@ -39,6 +39,7 @@ public final class CertificateManagementConstants { public static final String RSA_PRIVATE_KEY_END_TEXT = "-----END RSA PRIVATE KEY-----"; public static final String EMPTY_TEXT = ""; public static final int RSA_KEY_LENGTH = 2048; + public static final String SIGNING_ALGORITHM = "SHA256withRSA"; public static final class DataBaseTypes { private DataBaseTypes() {