Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit c40a8da6 authored by Joze RIHTARSIC's avatar Joze RIHTARSIC
Browse files

Fix policyIDs validation for Client-Cert

parent 056baa21
No related branches found
No related tags found
No related merge requests found
Showing
with 96 additions and 45 deletions
package eu.europa.ec.edelivery.smp.data.ui.enums;
public enum SMPPropertyTypeEnum {
STRING (".*","Property [%s] is not valid String type!"),
LIST_STRING(".*","Property [%s] is not valid LIST_STRING type!"),
MAP_STRING(".*","Property [%s] is not valid MAP_STRING type!"),
INTEGER("\\d*","Property [%s] is not valid Integer!"),
STRING (".{0,2000}","Property [%s] is not valid String type!"),
LIST_STRING(".{0,2000}","Property [%s] is not valid LIST_STRING type!"),
MAP_STRING(".{0,2000}","Property [%s] is not valid MAP_STRING type!"),
INTEGER("\\d{0,12}","Property [%s] is not valid Integer!"),
BOOLEAN("true|false","Property [%s] is not valid Boolean type!"),
REGEXP(".*", "Property [%s] is not valid Regular Expression type!"),
CRON_EXPRESSION(".*","Property [%s] is not valid Cron Expression type!"),
EMAIL(".*","Property [%s] is not valid Email address type!"),
FILENAME(".*","Property [%s] is not valid Filename type or it does not exists!"),
PATH(".*","Property [%s] is not valid Path type or it does not exists!"),
URL(".*","Property [%s] is not valid URL type or it does not exists!"),
REGEXP(".{0,2000}", "Property [%s] is not valid Regular Expression type!"),
CRON_EXPRESSION(".{0,2000}","Property [%s] is not valid Cron Expression type!"),
EMAIL(".{0,2000}","Property [%s] is not valid Email address type!"),
FILENAME(".{0,2000}","Property [%s] is not valid Filename type or it does not exists!"),
PATH(".{0,2000}","Property [%s] is not valid Path type or it does not exists!"),
URL(".{0,2000}","Property [%s] is not valid URL!"),
;
String errorTemplate;
......
......@@ -203,12 +203,12 @@ public class UITruststoreService {
cro = convertToRo(cert);
if (validate) {
validateNewCertificate(cert, cro);
validateCertificate(cert, cro);
}
return cro;
}
public void validateNewCertificate(X509Certificate cert, CertificateRO cro) {
public void validateCertificate(X509Certificate cert, CertificateRO cro) {
// first expect the worst
cro.setInvalid(true);
cro.setInvalidReason("Certificate is not validated!");
......
......@@ -89,15 +89,32 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
user.setPassword(null);
if (user.getCertificate() != null && !StringUtils.isBlank(user.getCertificate().getCertificateId())) {
// validate certificate
try {
truststoreService.checkFullCertificateValidity(user.getCertificate());
} catch (CertificateException e) {
LOG.warn("Set invalid cert status: " + user.getCertificate().getCertificateId() + " reason: " + e.getMessage());
user.getCertificate().setInvalid(true);
user.getCertificate().setInvalidReason(e.getMessage());
X509Certificate cert = getX509CertificateFromCertificateRO(user.getCertificate());
if (cert != null) {
truststoreService.validateCertificate(cert, user.getCertificate());
} else {
// validate just the database data
try {
truststoreService.checkFullCertificateValidity(user.getCertificate());
} catch (CertificateException e) {
LOG.warn("Set invalid cert status: " + user.getCertificate().getCertificateId() + " reason: " + e.getMessage());
user.getCertificate().setInvalid(true);
user.getCertificate().setInvalidReason(e.getMessage());
}
}
}
}
public X509Certificate getX509CertificateFromCertificateRO(CertificateRO certificateRO) {
if (certificateRO == null || certificateRO.getEncodedValue() == null) {
return null;
}
try {
return X509CertificateUtils.getX509Certificate(Base64.getMimeDecoder().decode(certificateRO.getEncodedValue()));
} catch (CertificateException e) {
LOG.error("Error occurred while parsing the certificate encoded value for certificate id:[" + certificateRO.getCertificateId() + "].", e);
return null;
}
}
/**
......@@ -106,8 +123,8 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
*
* @param authorizedUserId which is authorized for update
* @param userToUpdateId the user id to be updated
* @param currentPassword authorized password
* @param validatePassword do not validate password if CAS authenticated
* @param currentPassword authorized password
* @param currentPassword do not validate password if CAS authenticated
* @return generated AccessToken.
*/
@Transactional
......@@ -156,10 +173,10 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
/**
* Method updates the user password
*
* @param authorizedUserId - authorized user id
* @param userToUpdateId - user id to update password user id
* @param authorizationPassword - authorization password
* @param newPassword - new password for the userToUpdateId
* @param authorizedUserId - authorized user id
* @param userToUpdateId - user id to update password user id
* @param authorizationPassword - authorization password
* @param newPassword - new password for the userToUpdateId
* @param validateCurrentPassword - validate authorizationPassword - if CAS authenticated skip this part
* @return generated DBUser.
*/
......@@ -199,10 +216,10 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
/**
* Method updates the user password
*
* @param authorizedUserId - authorized user id
* @param userToUpdateId - user id to update password user id
* @param authorizedUserId - authorized user id
* @param userToUpdateId - user id to update password user id
* @param authorizationPassword - authorization password
* @param newPassword - new password for the userToUpdateId
* @param newPassword - new password for the userToUpdateId
* @return generated DBUser.
*/
@Transactional
......
......@@ -74,6 +74,10 @@ public class PropertyUtils {
return null;
}
if (StringUtils.length(value) > 2000) {
throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Invalid property value! Error: Value to long. Max. allowed size 200O characters!");
}
switch (type) {
case BOOLEAN:
if(StringUtils.equalsAnyIgnoreCase(trim(value),"true","false")) {
......
......@@ -74,7 +74,7 @@ public class UITruststoreServiceTest {
doNothing().when(testInstance).checkFullCertificateValidity(cert);
doNothing().when(testInstance).validateCertificateNotUsed(certData);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertFalse(certData.isInvalid());
assertNull(certData.getInvalidReason());
......@@ -86,7 +86,7 @@ public class UITruststoreServiceTest {
CertificateRO certData = new CertificateRO();
doThrow(new CertificateExpiredException("Expired")).when(testInstance).checkFullCertificateValidity(cert);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertTrue(certData.isInvalid());
assertEquals("Certificate is expired!", certData.getInvalidReason());
......@@ -98,7 +98,7 @@ public class UITruststoreServiceTest {
CertificateRO certData = new CertificateRO();
doThrow(new CertificateNotYetValidException("Error")).when(testInstance).checkFullCertificateValidity(cert);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertTrue(certData.isInvalid());
assertEquals("Certificate is not yet valid!", certData.getInvalidReason());
......@@ -110,7 +110,7 @@ public class UITruststoreServiceTest {
CertificateRO certData = new CertificateRO();
doThrow(Mockito.mock(CertificateRevokedException.class)).when(testInstance).checkFullCertificateValidity(cert);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertTrue(certData.isInvalid());
assertEquals("Certificate is revoked!", certData.getInvalidReason());
......@@ -122,7 +122,7 @@ public class UITruststoreServiceTest {
CertificateRO certData = new CertificateRO();
doThrow(Mockito.mock(CertificateNotTrustedException.class)).when(testInstance).checkFullCertificateValidity(cert);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertTrue(certData.isInvalid());
assertEquals("Certificate is not trusted!", certData.getInvalidReason());
......@@ -134,7 +134,7 @@ public class UITruststoreServiceTest {
CertificateRO certData = new CertificateRO();
doThrow(new CertificateException(Mockito.mock(CertPathValidatorException.class))).when(testInstance).checkFullCertificateValidity(cert);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertTrue(certData.isInvalid());
assertEquals("Certificate is not trusted! Invalid certificate policy path!", certData.getInvalidReason());
......@@ -147,7 +147,7 @@ public class UITruststoreServiceTest {
CertificateRO certData = new CertificateRO();
doThrow(new CertificateException(errorMessage)).when(testInstance).checkFullCertificateValidity(cert);
testInstance.validateNewCertificate(cert, certData);
testInstance.validateCertificate(cert, certData);
assertTrue(certData.isInvalid());
assertEquals(errorMessage, certData.getInvalidReason());
......
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (1, 'peppol_user@test-mail.eu','peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu','peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (2, 'the_admin@test-mail.eu','the_admin', '','the_admin', '', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (3, 'AdminSMP1TEST@test-mail.eu','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (4, 'AdminSMP2TEST@test-mail.eu','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (3, 'AdminSMP1TEST@test-mail.eu','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO','LvglqPCs', '$2a$10$zaFAFqFIfLUZx15ZDPMvDeWBtsZLaAkrY3Vmya5e3/yCCkFq/FJCu', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (4, 'AdminSMP2TEST@test-mail.eu','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi','VIhnrCJK', '$2a$10$BtInQBIycY2BSN28PD7TxO9ipAR3lhxUT2FLeShptGmjt6HaLpR7O', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (5, 'test@test-mail.eu','test', '','test', '', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (6, 'test1@test-mail.eu','test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy','test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy', 'SMP_ADMIN', 1, NOW(), NOW());
insert into SMP_USER (ID, EMAIL, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (7, 'system@test-mail.eu','system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SYSTEM_ADMIN', 1, NOW(), NOW());
......
......@@ -24,11 +24,10 @@ DELETE FROM SMP_OWNERSHIP;
set define off;
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu','peppol_user', '$2a$10$.pqNZZ4fRDdNbLhNlnEYg.1/d4yAGpLDgeXpJFI0sw7.WtyKphFzu', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'the_admin', '','the_admin', '', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO','AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi','AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'AdminSMP1TEST', '$2a$06$u6Hym7Zrbsf4gEIeAsJRceK.Kg7tei3kDypwucQQdky0lXOLCkrCO','LvglqPCs', '$2a$10$zaFAFqFIfLUZx15ZDPMvDeWBtsZLaAkrY3Vmya5e3/yCCkFq/FJCu', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'AdminSMP2TEST', '$2a$10$h8Q3Kjbs6ZrGkU6ditjNueINlJOMDJ/g/OKiqFZy32WmdhLjV5TAi','VIhnrCJK', '$2a$10$BtInQBIycY2BSN28PD7TxO9ipAR3lhxUT2FLeShptGmjt6HaLpR7O', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'test', '','test', '', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy','test1', '$2a$06$toKXJgjqQINZdjQqSao3NeWz2n1S64PFPhVU1e8gIHh4xdbwzy1Uy', 'SMP_ADMIN', 1, sysdate, sysdate);
insert into SMP_USER (ID, USERNAME, PASSWORD, ACCESS_TOKEN_ID, ACCESS_TOKEN, ROLE, ACTIVE, CREATED_ON, LAST_UPDATED_ON) values (SMP_USER_SEQ.nextval, 'system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36','system', '$2a$06$FDmjewn/do3C219uysNm9.XG8mIn.ubHnMydAzC8lsv61HsRpOR36', 'SYSTEM_ADMIN', 1, sysdate, sysdate);
......
......@@ -34,10 +34,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Optional;
import java.util.*;
import static java.util.Locale.US;
......@@ -191,6 +188,8 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
LOG.securityWarn(SMPMessageCode.SEC_USER_CERT_INVALID, userToken, msg);
throw new AuthenticationServiceException(msg);
}
validateCertificatePolicyMatchLegacy(userToken, principal.getPolicyOids());
// Check crl list
String url = certificate.getCrlUrl();
if (!StringUtils.isBlank(url)) {
......@@ -218,6 +217,37 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
}
/**
* Method validates if the certificate contains one of allowed Certificate policy. At the moment it does not validates
* the whole chain. Because in some configuration cases does not use the truststore
*
* @param certificateId
* @throws CertificateException
*/
protected void validateCertificatePolicyMatchLegacy(String certificateId, List<String> certPolicyList) throws AuthenticationServiceException {
// allowed list
List<String> allowedCertificatePolicyOIDList = configurationService.getAllowedCertificatePolicies();
if (allowedCertificatePolicyOIDList == null || allowedCertificatePolicyOIDList.isEmpty()) {
LOG.debug("Certificate policy is not configured. Skip Certificate policy validation!");
return;
}
// certificate list
if (certPolicyList.isEmpty()) {
String excMessage = String.format("Certificate [%] does not have CertificatePolicy extension.", certificateId);
throw new AuthenticationServiceException(excMessage);
}
Optional<String> result = certPolicyList.stream().filter(allowedCertificatePolicyOIDList::contains).findFirst();
if (result.isPresent()) {
LOG.debug("Certificate [{}] is trusted with certificate policy [{}]",certificateId, result.get());
return;
}
String excMessage = String.format("Certificate policy verification failed. Certificate [%s] does not contain any of the mandatory policy: [%s]", certificateId, allowedCertificatePolicyOIDList);
throw new AuthenticationServiceException(excMessage);
}
public void delayResponse(long startTime) {
int delayInMS = configurationService.getAccessTokenLoginFailDelayInMilliSeconds() - (int) (Calendar.getInstance().getTimeInMillis() - startTime);
if (delayInMS > 0) {
......@@ -282,6 +312,7 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
throws AuthenticationException {
String authenticationTokenId = auth.getName();
LOG.debug("Got authentication token:" + authenticationTokenId);
String authenticationTokenValue = auth.getCredentials().toString();
long startTime = Calendar.getInstance().getTimeInMillis();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment