Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OB3] Role extraction improvement - add support to extract both PSD2 and PSP roles from the certificate as needed #210

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
*/
public enum PSD2RoleEnum {

AISP("aisp"), PISP("pisp"), CBPII("cbpii"), ASPSP("aspsp");
AISP("aisp"),
PISP("pisp"),
CBPII("cbpii"),
ASPSP("aspsp"),
PSP_AI("psp_ai"),
PSP_PI("psp_pi"), PSP_IC("psp_ic"), PSP_AS("psp_as");

private String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
public class CertificateContent {
private String pspAuthorisationNumber;
private List<String> pspRoles;
private List<String> psd2Roles;
private String name;
private String ncaName;
private String ncaId;
Expand Down Expand Up @@ -54,6 +55,14 @@ public void setPspRoles(List<String> pspRoles) {
this.pspRoles = pspRoles;
}

public List<String> getPsd2Roles() {
return psd2Roles;
}

public void setPsd2Roles(List<String> psd2Roles) {
this.psd2Roles = psd2Roles;
}

public String getName() {

return name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,17 @@ public static CertificateContent extract(X509Certificate cert)
PSPRoles pspRoles = psd2QcType.getPspRoles();
List<PSPRole> rolesArray = pspRoles.getRoles();

// Roles as defined in the certificate (PSP_AI, PSP_PI, etc)
List<String> roles = new ArrayList<>();
// Relative PSD2 role names (AISP, PISP, etc)
List<String> psd2Roles = new ArrayList<>();

for (PSPRole pspRole : rolesArray) {
roles.add(pspRole.getPsd2RoleName());
roles.add(pspRole.getPspRoleName());
psd2Roles.add(pspRole.getPsd2RoleName());
}
tppCertData.setPspRoles(roles);
tppCertData.setPsd2Roles(psd2Roles);

tppCertData.setNcaName(psd2QcType.getnCAName().getString());
tppCertData.setNcaId(psd2QcType.getnCAId().getString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,29 @@ public void testExtractValidCertificate() throws Exception {
CertificateContent extract = CertificateContentExtractor.extract(cert);

Assert.assertTrue(extract.getPspRoles().size() == 3);
Assert.assertTrue(extract.getPspRoles().contains("AISP"));
Assert.assertTrue(extract.getPspRoles().contains("PISP"));
Assert.assertTrue(extract.getPspRoles().contains("CBPII"));
Assert.assertTrue(extract.getPspRoles().contains("PSP_AI"));
Assert.assertTrue(extract.getPspRoles().contains("PSP_PI"));
Assert.assertTrue(extract.getPspRoles().contains("PSP_IC"));
Assert.assertTrue(extract.getPspAuthorisationNumber().equals("PSDDE-BAFIN-123456"));
Assert.assertTrue(extract.getName().equals("www.hanseaticbank.de"));
Assert.assertTrue(extract.getNcaName().equals("Federal Financial Supervisory Authority"));
Assert.assertTrue(extract.getNcaId().equals("DE-BAFIN"));
}

@Test
public void testExtractPSD2RoleFromCert() throws Exception {

X509Certificate cert =
CommonTestUtil.parseTransportCert(CommonTestUtil.EIDAS_CERT).orElse(null);

CertificateContent extract = CertificateContentExtractor.extract(cert);

Assert.assertTrue(extract.getPsd2Roles().size() == 3);
Assert.assertTrue(extract.getPsd2Roles().contains("AISP"));
Assert.assertTrue(extract.getPsd2Roles().contains("PISP"));
Assert.assertTrue(extract.getPsd2Roles().contains("CBPII"));
}

@Test
public void testExtractInvalidCertificate() throws CertificateException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,25 +212,26 @@ public boolean validateTppRoles(X509Certificate tppCertificate, List<PSD2RoleEnu
* Validate whether the psd2 roles match with the scopes.
*
* @param tppCertificate eidas certificate with roles
* @param requiredPSD2Roles client requested roles
* @param requiredRoles client requested roles
* @return true if all required values are present in the certificate
*/
private boolean isRequiredRolesMatchWithScopes(X509Certificate tppCertificate
, List<PSD2RoleEnum> requiredPSD2Roles) throws CertificateValidationException, TPPValidationException {
, List<PSD2RoleEnum> requiredRoles) throws CertificateValidationException, TPPValidationException {


// Extract the certContent from the eidas certificate (i.e. roles, authorization number, etc)
CertificateContent certContent = CertificateContentExtractor.extract(tppCertificate);

if (log.isDebugEnabled()) {
log.debug("The TPP is requesting roles: " + requiredPSD2Roles);
log.debug("The TPP is requesting roles: " + requiredRoles);
log.debug("Provided PSD2 eIDAS certificate" +
" contains the role: " + certContent.getPspRoles());
}

// Validate whether the eIDAS certificate contains the required roles that matches with the token scopes.
for (PSD2RoleEnum requiredRole : requiredPSD2Roles) {
if (!certContent.getPspRoles().contains(requiredRole.name())) {
for (PSD2RoleEnum requiredRole : requiredRoles) {
if (!(certContent.getPspRoles().contains(requiredRole.name())
|| certContent.getPsd2Roles().contains(requiredRole.name()))) {
// Return false if any one of the roles that are bound to the scope is not present in the PSD2
// role list of the client eIDAS certificate.
final String errorMsg = "The PSD2 eIDAS certificate does not contain the required role "
Expand Down
Loading