All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.europa.esig.dss.spi.QcStatementUtils Maven / Gradle / Ivy

/**
 * DSS - Digital Signature Services
 * Copyright (C) 2015 European Commission, provided under the CEF programme
 * 

* This file is part of the "DSS - Digital Signature Services" project. *

* This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *

* This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. *

* You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package eu.europa.esig.dss.spi; import eu.europa.esig.dss.enumerations.QCType; import eu.europa.esig.dss.enumerations.RoleOfPspOid; import eu.europa.esig.dss.enumerations.SemanticsIdentifier; import eu.europa.esig.dss.model.x509.CertificateToken; import eu.europa.esig.dss.model.x509.extension.PSD2QcType; import eu.europa.esig.dss.model.x509.extension.PdsLocation; import eu.europa.esig.dss.model.x509.extension.QCLimitValue; import eu.europa.esig.dss.model.x509.extension.QcStatements; import eu.europa.esig.dss.model.x509.extension.RoleOfPSP; import eu.europa.esig.dss.utils.Utils; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.qualified.ETSIQCObjectIdentifiers; import org.bouncycastle.asn1.x509.qualified.MonetaryValue; import org.bouncycastle.asn1.x509.qualified.QCStatement; import org.bouncycastle.asn1.x509.qualified.RFC3739QCObjectIdentifiers; import org.bouncycastle.asn1.x509.qualified.SemanticsInformation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; /** * A utils class to retrieve qc-statement from a certificate token * */ public class QcStatementUtils { private static final Logger LOG = LoggerFactory.getLogger(QcStatementUtils.class); /** * Singleton */ private QcStatementUtils() { // empty } /** * Extracts the QCStatements from a certificate token * * @param certToken {@link CertificateToken} * @return {@link QcStatements} */ public static QcStatements getQcStatements(CertificateToken certToken) { final byte[] qcStatementsExtension = certToken.getCertificate().getExtensionValue(Extension.qCStatements.getId()); if (Utils.isArrayNotEmpty(qcStatementsExtension)) { try { final ASN1Sequence qcStatementsSeq = DSSASN1Utils.getAsn1SequenceFromDerOctetString(qcStatementsExtension); final QcStatements qcStatements = getQcStatements(qcStatementsSeq); qcStatements.checkCritical(certToken); return qcStatements; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcStatements : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(qcStatementsExtension)); } else { LOG.warn("Unable to extract QcStatements : {}", e.getMessage()); } } } return null; } /** * Extracts the QCStatements from a qcStatementsSeq. * NOTE: does not check if the extension is critical. Use {@code #getQcStatements(CertificateToken certToken)} * if you need to know whether the certificate extension is critical. * * @param qcStatementsSeq {@link ASN1Sequence} * @return {@link QcStatements} */ public static QcStatements getQcStatements(ASN1Sequence qcStatementsSeq) { if (qcStatementsSeq == null) { return null; } final QcStatements result = new QcStatements(); result.setOctets(DSSASN1Utils.getDEREncoded(qcStatementsSeq)); for (int i = 0; i < qcStatementsSeq.size(); i++) { final QCStatement statement = getQCStatement(qcStatementsSeq.getObjectAt(i)); if (statement != null) { final ASN1ObjectIdentifier objectIdentifier = statement.getStatementId(); String oid = objectIdentifier.getId(); final ASN1Encodable statementInfo = statement.getStatementInfo(); if (isQcCompliance(oid)) { result.setQcCompliance(true); } else if (isQcLimitValue(oid)) { result.setQcLimitValue(getQcLimitValue(statementInfo)); } else if (isQcRetentionPeriod(oid)) { result.setQcEuRetentionPeriod(getQcEuRetentionPeriod(statementInfo)); } else if (isQcSSCD(oid)) { result.setQcQSCD(true); } else if (isQcPds(oid)) { result.setQcEuPDS(getQcEuPDS(statementInfo)); } else if (isQcType(oid)) { result.setQcTypes(getQcTypes(statementInfo)); } else if (isQcCClegislation(oid)) { result.setQcLegislationCountryCodes(getQcLegislationCountryCodes(statementInfo)); } else if (isQcSemanticsIdentifier(oid)) { result.setQcSemanticsIdentifier(getQcSemanticsIdentifier(statementInfo)); } else if (isPsd2QcType(oid)) { result.setPsd2QcType(getPsd2QcType(statementInfo)); } else { LOG.warn("Not supported QcStatement with OID : '{}'", oid); result.addOtherOid(oid); } } } return result; } /** * This method verifies of the given OID is a QcCompliance statement * * @param oid {@link String} to check * @return TRUE if QcCompliance, FALSE otherwise */ public static boolean isQcCompliance(String oid) { return ETSIQCObjectIdentifiers.id_etsi_qcs_QcCompliance.getId().equals(oid); } /** * This method verifies of the given OID is a QcLimitValue statement * * @param oid {@link String} to check * @return TRUE if QcLimitValue, FALSE otherwise */ public static boolean isQcLimitValue(String oid) { return ETSIQCObjectIdentifiers.id_etsi_qcs_LimiteValue.getId().equals(oid); } /** * This method verifies of the given OID is a QcRetentionPeriod statement * * @param oid {@link String} to check * @return TRUE if QcRetentionPeriod, FALSE otherwise */ public static boolean isQcRetentionPeriod(String oid) { return ETSIQCObjectIdentifiers.id_etsi_qcs_RetentionPeriod.getId().equals(oid); } /** * This method verifies of the given OID is a QcSSCD statement * * @param oid {@link String} to check * @return TRUE if QcSSCD, FALSE otherwise */ public static boolean isQcSSCD(String oid) { return ETSIQCObjectIdentifiers.id_etsi_qcs_QcSSCD.getId().equals(oid); } /** * This method verifies of the given OID is a QcPds statement * * @param oid {@link String} to check * @return TRUE if QcPds, FALSE otherwise */ public static boolean isQcPds(String oid) { return ETSIQCObjectIdentifiers.id_etsi_qcs_QcPds.getId().equals(oid); } /** * This method verifies of the given OID is a QcType statement * * @param oid {@link String} to check * @return TRUE if QcType, FALSE otherwise */ public static boolean isQcType(String oid) { return ETSIQCObjectIdentifiers.id_etsi_qcs_QcType.getId().equals(oid); } /** * This method verifies of the given OID is a QcCClegislation statement * * @param oid {@link String} to check * @return TRUE if QcCClegislation, FALSE otherwise */ public static boolean isQcCClegislation(String oid) { return OID.id_etsi_qcs_QcCClegislation.getId().equals(oid); } /** * This method verifies of the given OID is a QcSemanticsIdentifier statement * * @param oid {@link String} to check * @return TRUE if QcSemanticsIdentifier, FALSE otherwise */ public static boolean isQcSemanticsIdentifier(String oid) { return RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v2.getId().equals(oid); } /** * This method verifies of the given OID is a Psd2QcType statement * * @param oid {@link String} to check * @return TRUE if Psd2QcType, FALSE otherwise */ public static boolean isPsd2QcType(String oid) { return OID.psd2_qcStatement.getId().equals(oid); } private static QCStatement getQCStatement(ASN1Encodable qcStatement) { if (qcStatement != null) { try { return QCStatement.getInstance(qcStatement); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QCStatement : {}. Obtained sequence binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(qcStatement))); } else { LOG.warn("Unable to extract QCStatement : {}", e.getMessage()); } } } return null; } private static QCLimitValue getQcLimitValue(ASN1Encodable statementInfo) { try { MonetaryValue monetaryValue = MonetaryValue.getInstance(statementInfo); QCLimitValue result = new QCLimitValue(); result.setCurrency(monetaryValue.getCurrency().getAlphabetic()); result.setAmount(monetaryValue.getAmount().intValue()); result.setExponent(monetaryValue.getExponent().intValue()); return result; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcLimitValue : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract QcLimitValue : {}", e.getMessage()); } return null; } } private static Integer getQcEuRetentionPeriod(ASN1Encodable statementInfo) { try { ASN1Integer integer = ASN1Integer.getInstance(statementInfo); return integer.intValueExact(); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcEuRetentionPeriod : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract QcEuRetentionPeriod : {}", e.getMessage()); } return null; } } private static List getQcEuPDS(ASN1Encodable statementInfo) { List result = new ArrayList<>(); try { ASN1Sequence sequence = ASN1Sequence.getInstance(statementInfo); for (int i = 0; i < sequence.size(); i++) { final ASN1Encodable e1 = sequence.getObjectAt(i); if (e1 instanceof ASN1Sequence) { ASN1Sequence seq = (ASN1Sequence) e1; result.add(getPdsLocation(seq)); } else { LOG.warn("ASN1Sequence in QcEuPDS does not contain ASN1Sequence, but {}", e1.getClass().getName()); } } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcEuPDS : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract QcEuPDS : {}", e.getMessage()); } } return result; } private static PdsLocation getPdsLocation(ASN1Sequence seq) { PdsLocation pdsLocation = new PdsLocation(); pdsLocation.setUrl(DSSASN1Utils.getString(seq.getObjectAt(0))); pdsLocation.setLanguage(DSSASN1Utils.getString(seq.getObjectAt(1))); return pdsLocation; } private static List getQcTypes(ASN1Encodable statementInfo) { final List oids = new ArrayList<>(); try { ASN1Sequence sequence = ASN1Sequence.getInstance(statementInfo); for (int i = 0; i < sequence.size(); i++) { final ASN1Encodable e1 = sequence.getObjectAt(i); if (e1 instanceof ASN1ObjectIdentifier) { final ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e1; oids.add(oid.getId()); } else { LOG.warn("ASN1Sequence in QcTypes does not contain ASN1ObjectIdentifier, but {}", e1.getClass().getName()); } } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcTypes : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract QcTypes : {}", e.getMessage()); } } return getQcTypes(oids); } /** * This method returns a list of {@code QCType}s from a list of given QcType OIDs * * @param oids a list of {@link String}s representing QcType OIDs * @return a list of {@link QCType}s */ public static List getQcTypes(List oids) { List result = new ArrayList<>(); for (String oid : oids) { if (Utils.isStringNotBlank(oid)) { QCType type = QCType.fromOid(oid); result.add(type); } else { LOG.warn("Empty QcType OID is skipped."); } } return result; } private static List getQcLegislationCountryCodes(ASN1Encodable statementInfo) { List result = new ArrayList<>(); try { ASN1Sequence sequence = ASN1Sequence.getInstance(statementInfo); for (int i = 0; i < sequence.size(); i++) { String countryCode = DSSASN1Utils.getString(sequence.getObjectAt(i)); if (countryCode != null) { result.add(countryCode); } } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcCClegislation : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract QcCClegislation : {}", e.getMessage()); } } return result; } private static SemanticsIdentifier getQcSemanticsIdentifier(ASN1Encodable statementInfo) { try { SemanticsInformation semanticsInfo = SemanticsInformation.getInstance(statementInfo); if (semanticsInfo != null && semanticsInfo.getSemanticsIdentifier() != null) { return SemanticsIdentifier.fromOid(semanticsInfo.getSemanticsIdentifier().getId()); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract QcSemanticsIdentifiers : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract QcSemanticsIdentifiers : {}", e.getMessage()); } } return null; } private static PSD2QcType getPsd2QcType(ASN1Encodable statementInfo) { try { PSD2QcType result = new PSD2QcType(); ASN1Sequence sequence = ASN1Sequence.getInstance(statementInfo); ASN1Sequence rolesSeq = ASN1Sequence.getInstance(sequence.getObjectAt(0)); List rolesOfPSP = new ArrayList<>(); for (int i = 0; i < rolesSeq.size(); i++) { ASN1Sequence oneRoleSeq = ASN1Sequence.getInstance(rolesSeq.getObjectAt(i)); RoleOfPSP roleOfPSP = new RoleOfPSP(); ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) oneRoleSeq.getObjectAt(0); roleOfPSP.setPspOid(RoleOfPspOid.fromOid(oid.getId())); roleOfPSP.setPspName(DSSASN1Utils.getString(oneRoleSeq.getObjectAt(1))); rolesOfPSP.add(roleOfPSP); } result.setRolesOfPSP(rolesOfPSP); result.setNcaName(DSSASN1Utils.getString(sequence.getObjectAt(1))); result.setNcaId(DSSASN1Utils.getString(sequence.getObjectAt(2))); return result; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.warn("Unable to extract PSD2-QcStatement : {}. Obtained binaries : '{}'", e.getMessage(), Utils.toBase64(DSSASN1Utils.getDEREncoded(statementInfo))); } else { LOG.warn("Unable to extract PSD2-QcStatement : {}", e.getMessage()); } return null; } } /** * This method verifies whether the given {@code qcStatementOid} is present within the {@code QcStatements} * * @param qcStatements {@link QcStatements} to be verified * @param qcStatementOid {@link String} representing OID of a QCStatement to be checked * @return TRUE if a QCStatement with the given OID is present, FALSE otherwise */ public static boolean isQcStatementPresent(QcStatements qcStatements, String qcStatementOid) { if (isQcCompliance(qcStatementOid)) { return qcStatements.isQcCompliance(); } else if (isQcLimitValue(qcStatementOid)) { return qcStatements.getQcLimitValue() != null; } else if (isQcRetentionPeriod(qcStatementOid)) { return qcStatements.getQcEuRetentionPeriod() != null; } else if (isQcSSCD(qcStatementOid)) { return qcStatements.isQcQSCD(); } else if (isQcPds(qcStatementOid)) { return Utils.isCollectionNotEmpty(qcStatements.getQcEuPDS()); } else if (isQcType(qcStatementOid)) { return Utils.isCollectionNotEmpty(qcStatements.getQcTypes()); } else if (isQcCClegislation(qcStatementOid)) { return Utils.isCollectionNotEmpty(qcStatements.getQcLegislationCountryCodes()); } else if (isQcSemanticsIdentifier(qcStatementOid)) { return qcStatements.getQcSemanticsIdentifier() != null; } else if (isPsd2QcType(qcStatementOid)) { return qcStatements.getPsd2QcType() != null; } else { return qcStatements.getOtherOids().contains(qcStatementOid); } } /** * This method verifies whether a QCType with a given {@code qcTypeOid} is present * within provided {@code QcStatements} * * @param qcStatements {@link QcStatements} to check QCTypes from * @param qcTypeOid {@link String} representing a QCType OID to be verified * @return TRUE of the QCType with a given OID is present, FALSE otherwise */ public static boolean isQcTypePresent(QcStatements qcStatements, String qcTypeOid) { List qcTypes = qcStatements.getQcTypes(); if (Utils.isCollectionNotEmpty(qcTypes)) { for (QCType qcType : qcTypes) { if (qcTypeOid.equals(qcType.getOid())) { return true; } } } return false; } /** * This method verifies whether a QCLegislation code is present within provided {@code QcStatements} * * @param qcStatements {@link QcStatements} to check QCLegislation from * @param qcLegislation {@link String} representing a QCLegislation country code to be verified * @return TRUE of the QCLegislation is present, FALSE otherwise */ public static boolean isQcLegislationPresent(QcStatements qcStatements, String qcLegislation) { List qcLegislationCountryCodes = qcStatements.getQcLegislationCountryCodes(); if (Utils.isCollectionNotEmpty(qcLegislationCountryCodes)) { return qcLegislationCountryCodes.contains(qcLegislation); } return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy