Add tenant based storing and loading SCEP certificates

master-sync
Pahansith Gunathilake 2 years ago
parent 1aafd53d3e
commit 209f2b66c9

@ -51,6 +51,16 @@ public interface CertificateDAO {
*/
CertificateResponse retrieveCertificate(String serialNumber) throws CertificateManagementDAOException;
/**
* Obtain a certificated stored in the database by providing the common name and the tenant ID
*
* @param serialNumber Serial number (Common name) of the certificate
* @param tenantId ID of the certificate owning tenant
* @return representation of the certificate.
* @throws CertificateManagementDAOException if fails to read the certificate from the database
*/
CertificateResponse retrieveCertificate(String serialNumber, int tenantId) throws CertificateManagementDAOException;
/**
* Get all the certificates in a paginated manner.
*

@ -119,6 +119,42 @@ public abstract class AbstractCertificateDAOImpl implements CertificateDAO{
return certificateResponse;
}
@Override
public CertificateResponse retrieveCertificate(String serialNumber, int tenantId) throws CertificateManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
CertificateResponse certificateResponse = null;
try {
conn = this.getConnection();
String query =
"SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID, USERNAME FROM"
+ " DM_DEVICE_CERTIFICATE WHERE SERIAL_NUMBER = ? AND TENANT_ID = ? ";
stmt = conn.prepareStatement(query);
stmt.setString(1, serialNumber);
stmt.setInt(2, tenantId);
resultSet = stmt.executeQuery();
if (resultSet.next()) {
certificateResponse = new CertificateResponse();
byte[] certificateBytes = resultSet.getBytes("CERTIFICATE");
certificateResponse.setCertificate(certificateBytes);
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
certificateResponse.setUsername(resultSet.getString("USERNAME"));
CertificateGenerator.extractCertificateDetails(certificateBytes, certificateResponse);
}
} catch (SQLException e) {
String errorMsg =
"Unable to get the read the certificate with serial" + serialNumber;
log.error(errorMsg, e);
throw new CertificateManagementDAOException(errorMsg, e);
} finally {
CertificateManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return certificateResponse;
}
@Override
public List<CertificateResponse> searchCertificate(String serialNumber)
throws CertificateManagementDAOException {

@ -358,15 +358,31 @@ public class CertificateGenerator {
CertificateResponse lookUpCertificate = null;
KeyStoreReader keyStoreReader = new KeyStoreReader();
if (distinguishedName != null && !distinguishedName.isEmpty()) {
if (distinguishedName.contains("/CN=")) {
String[] dnSplits = distinguishedName.split("/");
if (distinguishedName.contains("CN=")) {
String[] dnSplits = null;
if (distinguishedName.contains("/")) {
dnSplits = distinguishedName.split("/");
} else if (distinguishedName.contains(",")) {
//some older versions of nginx will forward the client certificate subject dn separated with commas
dnSplits = distinguishedName.split(",");
}
String commonNameExtracted = null;
int tenantId = 0;
if (dnSplits != null && dnSplits.length >= 1) {
for (String dnPart : dnSplits) {
if (dnPart.contains("CN=")) {
String commonNameExtracted = dnPart.replace("CN=", "");
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted);
break;
commonNameExtracted = dnPart.replace("CN=", "");
} else if (dnPart.contains("OU=")) {
//the OU of the certificate will be like OU=tenant_<TENANT_ID> ex: OU=tenant_-1234
//splitting by underscore to extract the tenant domain
String[] orgUnitSplits = dnPart.split("_");
tenantId = Integer.parseInt(orgUnitSplits[1]);
}
}
}
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted, tenantId);
} else {
LdapName ldapName;
try {
@ -807,8 +823,9 @@ public class CertificateGenerator {
X500Name issuerName = new X500Name(subjectDn);
String commonName = certificationRequest.getSubject().getRDNs(BCStyle.CN)[0].getFirst()
.getValue().toString();
X500Name subjectName = new X500Name("O=" + commonName + "O=AndroidDevice,CN=" +
serialNumber);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
X500Name subjectName = new X500Name("O=" + commonName + ",CN=" +
serialNumber + ", OU=tenant_"+tenantId);
Date startDate = new Date(System.currentTimeMillis());
Date endDate = new Date(System.currentTimeMillis()
+ TimeUnit.DAYS.toMillis(365 * 100));
@ -826,6 +843,10 @@ public class CertificateGenerator {
issuedCert = (X509Certificate) certificateFactory
.generateCertificate(new ByteArrayInputStream(encodedCertificate));
io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate certificate =
new io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate();
List<io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate> certificates = new ArrayList<>();
certificate.setTenantId(tenantId);
org.wso2.carbon.certificate.mgt.core.bean.Certificate certificate =
new org.wso2.carbon.certificate.mgt.core.bean.Certificate();
List<org.wso2.carbon.certificate.mgt.core.bean.Certificate> certificates = new ArrayList<>();

@ -275,6 +275,43 @@ public class KeyStoreReader {
return raPrivateKey;
}
public CertificateResponse getCertificateBySerial(String serialNumber, int tenantId) throws KeystoreException {
CertificateResponse certificateResponse = null;
try {
CertificateCacheManager cacheManager = CertificateCacheManagerImpl.getInstance();
certificateResponse = cacheManager.getCertificateBySerial(serialNumber);
if (certificateResponse == null) {
try {
CertificateManagementDAOFactory.openConnection();
certificateResponse = certDao.retrieveCertificate(serialNumber, tenantId);
} catch (SQLException e) {
String errorMsg = "Error when making a connection to the database.";
throw new KeystoreException(errorMsg, e);
} finally {
CertificateManagementDAOFactory.closeConnection();
}
if (certificateResponse != null && certificateResponse.getCertificate() != null) {
Certificate certificate = (Certificate) Serializer.deserialize(certificateResponse.getCertificate());
if (certificate instanceof X509Certificate) {
X509Certificate x509cert = (X509Certificate) certificate;
String commonName = CertificateGenerator.getCommonName(x509cert);
certificateResponse.setCommonName(commonName);
cacheManager.addCertificateBySerial(serialNumber, certificateResponse);
}
}
}
} catch (CertificateManagementDAOException e) {
String errorMsg = "Error when retrieving certificate from the the database for the serial number: " +
serialNumber;
throw new KeystoreException(errorMsg, e);
} catch (ClassNotFoundException | IOException e) {
String errorMsg = "Error when de-serializing saved certificate.";
throw new KeystoreException(errorMsg, e);
}
return certificateResponse;
}
public CertificateResponse getCertificateBySerial(String serialNumber) throws KeystoreException {
CertificateResponse certificateResponse = null;
try {

@ -0,0 +1,32 @@
/* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 org.wso2.carbon.device.mgt.core.common.exception;
/**
* Represents the exception thrown during storing and retrieving the artifacts.
*/
public class StorageManagementException extends Exception {
public StorageManagementException(String message, Throwable ex) {
super(message, ex);
}
public StorageManagementException(String message) {
super(message);
}
}
Loading…
Cancel
Save