diff options
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2')
12 files changed, 1819 insertions, 0 deletions
| diff --git a/eidas_modules/authmodule-eIDAS-v2/pom.xml b/eidas_modules/authmodule-eIDAS-v2/pom.xml index 4f3133f8..680c528e 100644 --- a/eidas_modules/authmodule-eIDAS-v2/pom.xml +++ b/eidas_modules/authmodule-eIDAS-v2/pom.xml @@ -180,6 +180,17 @@        <artifactId>jose4j</artifactId>        <version>0.7.2</version>      </dependency> +      <dependency> +          <groupId>at.gv.egiz.eaaf</groupId> +          <artifactId>eaaf_module_pvp2_core</artifactId> +          <version>1.1.11</version> +          <scope>compile</scope> +      </dependency> +    <dependency> +      <groupId>at.gv.egiz.eaaf</groupId> +      <artifactId>eaaf_module_pvp2_sp</artifactId> +      <scope>compile</scope> +    </dependency>    </dependencies>    <build> diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/AhExtendedPvpAttributeDefinitions.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/AhExtendedPvpAttributeDefinitions.java new file mode 100644 index 00000000..af9a2972 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/AhExtendedPvpAttributeDefinitions.java @@ -0,0 +1,24 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AhExtendedPvpAttributeDefinitions implements ExtendedPvpAttributeDefinitions { +  private static final Logger log = +      LoggerFactory.getLogger(AhExtendedPvpAttributeDefinitions.class); + +  private AhExtendedPvpAttributeDefinitions() { +    log.trace("Instance class: {} for SonarQube", +        AhExtendedPvpAttributeDefinitions.class.getName()); + +  } + +  public static final String EID_BCBIND_NAME = "urn:eidgvat:attributes.bcbind"; +  public static final String EID_BCBIND_FRIENDLY_NAME = "bcBind"; + +  public static final String EID_BINDING_PUBKEY_NAME = "urn:eidgvat:attributes.binding.pubkey"; +  public static final String EID_BINDING_PUBKEY_FRIENDLY_NAME = "BindingPubKey"; + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/AuthHandlerConstants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/AuthHandlerConstants.java new file mode 100644 index 00000000..60219759 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/AuthHandlerConstants.java @@ -0,0 +1,141 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + + +public class AuthHandlerConstants { + +  private AuthHandlerConstants() { + +  } + +  // TODO: maybe update to another target +  public static final String DEFAULT_INTERNAL_BPK_TARGET = "urn:publicid:gv.at:cdid+ZP-MH"; + +  // configuration parameters +  public static final String PROP_CONFIG_APPLICATION_PREFIX = "authhandler."; +  public static final String PROP_CONFIG_APPLICATION_PUBLIC_URL_PREFIX = "core.context.url.prefix"; +  public static final String PROP_CONFIG_APPLICATION_PUBLIC_URL_REQUEST_VALIDATION = +      "core.context.url.request.validation"; +  public static final String PROP_CONFIG_LEGACY_ALLOW = "core.legacy.allowLegacyMode"; + +  public static final String PROP_CONFIG_WEBCONTENT_STATIC_PATH = +      "core.webcontent.static.directory"; +  public static final String PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH = "core.webcontent.templates"; +  public static final String PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH = "core.webcontent.properties"; + +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_NAME = "core.cache.transaction.name"; +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_ENC_ENABLED = +      "core.cache.transaction.encryption.enabled"; +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_ENC_KEY_TYPE = +      "core.cache.transaction.encryption.type"; +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_ENC_PASSPHRASE = +      "core.cache.transaction.encryption.passphrase"; +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_ENC_SALT = +      "core.cache.transaction.encryption.salt"; +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_ENC_KEYSTORE_NAME = +      "core.cache.transaction.encryption.keystore.name"; +  public static final String PROP_CONFIG_CACHE_TRANSACTIONS_ENC_KEY_ALIAS = +      "core.cache.transaction.encryption.key.alias"; + +  public static final String PROP_CONFIG_CACHE_ATTRIBUTEPROXY_NAME = +      "core.cache.attributeproxy.name"; + +  public static final String PROP_CONFIG_BACKEND_ENDPOINT_GETALLSUPPORTEDATTRIBUTES = +      "backend.endpoints.getallsupportedattributes"; +  public static final String PROP_CONFIG_BACKEND_ENDPOINT_GETAPPLICATIONCONFIGURATION = +      "backend.endpoints.getapplicationconfiguration"; + +  public static final String PROP_CONFIG_INTERNAL_BPK_TARGET = "core.internal.bpk.target"; + +  public static final String PROP_CONFIG_INTERNAL_FRONTEND_ONLY_MODE = "core.internal.frontend.only.mode"; +  public static final boolean PROP_DEFAULT_CONFIG_INTERNAL_FRONTEND_ONLY_MODE = false; + +  // Servlet End-Points +  public static final String ENDPOINT_PROCESSENGINE_CONTROLLER = "/api/process"; +  public static final String ENDPOINT_ERROR_IFRAME_HOPPING = "/error/parenthop"; + + +  // GUI template directories +  public static final String CLASSPATH_TEMPLATE_DIR = "/templates/"; +  public static final String FILESYSTEM_TEMPLATE_DIR = "./templates/"; +  public static final String TEMPLATE_HTML_ERROR = "error_message.html"; + +  // GUI template defaultfiles +  public static final String TEMPLATE_AUTHPROCESS_SELECTION_VDA_FULLFRAME = "authSelection.html"; +  public static final String TEMPLATE_AUTHPROCESS_SELECTION_VDA_IFRAME = "authSelection_iframe.html"; +  public static final String TEMPLATE_USER_CONSENT_REQUEST = "userConsent.html"; +  public static final String TEMPLATE_IFRAME_TO_PARENT_HOPE = "iframe_parent_hope.html"; +  public static final String TEMPLATE_MANDATE_SELECTION = "mandateSelection.html"; +  public static final String TEMPLATE_PROF_REP_MANDATE_SELECTION = "profRepMandateSelection.html"; +  public static final String TEMPLATE_MANDATE_SELECTION_DUMMY = "mandateSelection_dummy.html"; + + + +  // http request parameters +  public static final String HTTP_PARAM_APPLICATION_ID = "appId"; +  public static final String HTTP_PARAM_STOP_PROCESS = "stopAuthProcess"; +  public static final String HTTP_PARAM_EIDAS_PROCESS = "useeIDAS"; +  public static final String HTTP_PARAM_EID_PROCESS = "useeID"; +  public static final String HTTP_PARAM_EID_BINDING_AUTH_PROCESS = "useBindingAuth"; +  public static final String HTTP_PARAM_USE_MANDATES = "useMandate"; +  public static final String HTTP_PARAM_AUTHMETHOD = "authMethod"; +  public static final String HTTP_PARAM_CONSENT_RELEASE_ATTRIBUTES = "releaseAttributes"; +  public static final String HTTP_PARAM_CONSENT_STORE_CONSENT = "storeConsent"; + +  @Deprecated +  public static final String HTTP_PARAM_EIDMIGRATIONPILOT_PROCESS = "pilotMigration"; +  @Deprecated +  public static final String HTTP_PARAM_EIDMIGRATIONPILOT_SHOW_INFO_PAGE = "pilotMigrationInfoPage"; +  @Deprecated +  public static final String HTTP_PARAM_MOBILESIGNATURE_PROCESS = "usemobileSig"; + +  // UI options +  public static final String UI_PARAM_USE_MANDATES = HTTP_PARAM_USE_MANDATES; +  public static final String UI_PARAM_USE_ONLY_MANDATES = "useOnlyMandate"; +  public static final String UI_PARAM_USE_EIDAS = HTTP_PARAM_EIDAS_PROCESS; +  public static final String UI_PARAM_DSGVO_SHORT_INFO = "dsgvoShortText"; +  public static final String UI_PARAM_DSGVO_SP_PRIVACY_STATEMENT_URL = "dsgvoPrivacyStatementUrl"; +  public static final String UI_PARAM_DSGVO_SP_SERVICE_URL = "dsgvoServiceUrl"; +  public static final String UI_PARAM_DSGVO_SP_LOGO = "dsgvoSpLogo"; +  public static final String UI_PARAM_DSGVO_SP_LOGO_SET = "dsgvoSpLogoSet"; +  public static final String UI_PARAM_DSGVO_SP_LOGO_SET_DATAURL = "dataUrl"; +  public static final String UI_PARAM_DSGVO_SP_LOGO_SET_THEME = "theme"; +  public static final String UI_PARAM_DSGVO_SP_LOGO_SET_RESOLUTION = "resolution"; +  public static final String UI_PARAM_DSGVO_SP_LOGO_SET_TYPE = "type"; + +  public enum LogoType { SVG, PNG, UNKNOWN } + +  public enum AuthBlockType { +    CADES("CAdES"), JWS("JWS"), NONE("none"); + +    private final String internalType; + +    AuthBlockType(final String type) { +      this.internalType = type; + +    } + +    /** +     * Get Type identifier for this AuthBlock. +     * +     * @return +     */ +    public String getAuthBlockType() { +      return this.internalType; +    } + +    @Override +    public String toString() { +      return getAuthBlockType(); + +    } +  } + +  // process context parameters +  public static final String PROCESSCONTEXT_USERCONSENT_NEEDED = "userConsentNeeded"; +  public static final String PROCESSCONTEXT_AUTHPROCESSSELECTION_DONE = "authProcSelectDone"; +  public static final String PROCESSCONTEXT_SWITCH_LANGUAGE = "changeLanguage"; +  public static final String PROCESSCONTEXT_IFRAME_PARENT_NEEDED = "iframeParentNeeded"; + +  public static final String PROCESSCONTEXT_WAS_EID_PROCESS = "wasEidProcess"; + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthConstants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthConstants.java new file mode 100644 index 00000000..e4d520b4 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthConstants.java @@ -0,0 +1,166 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + + +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.impl.data.Triple; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + + +public class EidasCentralAuthConstants { + +  private EidasCentralAuthConstants() { + +  } + +  public static final String SAML2_STATUSCODE_USERSTOP = "1005"; + +  public static final String MODULE_NAME_FOR_LOGGING = "eIDAS central authentication"; + +  public static final int METADATA_VALIDUNTIL_IN_HOURS = 24; + +  //  public static final String HTTP_PARAM_CENTRAL_EIDAS_AUTH_SELECTION = +  //      AuthHandlerConstants.HTTP_PARAM_EIDAS_PROCESS; + +  public static final String ENDPOINT_POST = "/sp/eidas/post"; +  public static final String ENDPOINT_REDIRECT = "/sp/eidas/redirect"; +  public static final String ENDPOINT_METADATA = "/sp/eidas/metadata"; + +  public static final String CONFIG_PROPS_PREFIX = "modules.eidascentralauth."; +  public static final String CONFIG_PROPS_KEYSTORE_TYPE = CONFIG_PROPS_PREFIX + "keystore.type"; +  public static final String CONFIG_PROPS_KEYSTORE_NAME = CONFIG_PROPS_PREFIX + "keystore.name"; +  public static final String CONFIG_PROPS_KEYSTORE_PATH = CONFIG_PROPS_PREFIX + "keystore.path"; +  public static final String CONFIG_PROPS_KEYSTOREPASSWORD = CONFIG_PROPS_PREFIX + "keystore.password"; +  public static final String CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD = CONFIG_PROPS_PREFIX +      + "metadata.sign.password"; +  public static final String CONFIG_PROPS_SIGN_METADATA_ALIAS = CONFIG_PROPS_PREFIX +      + "metadata.sign.alias"; +  public static final String CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD = CONFIG_PROPS_PREFIX +      + "request.sign.password"; +  public static final String CONFIG_PROPS_SIGN_SIGNING_ALIAS = CONFIG_PROPS_PREFIX +      + "request.sign.alias"; +  public static final String CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD = CONFIG_PROPS_PREFIX +      + "response.encryption.password"; +  public static final String CONFIG_PROPS_ENCRYPTION_ALIAS = CONFIG_PROPS_PREFIX +      + "response.encryption.alias"; + +  public static final String CONFIG_PROPS_TRUSTSTORE_TYPE = CONFIG_PROPS_PREFIX + "truststore.type"; +  public static final String CONFIG_PROPS_TRUSTSTORE_NAME = CONFIG_PROPS_PREFIX + "truststore.name"; +  public static final String CONFIG_PROPS_TRUSTSTORE_PATH = CONFIG_PROPS_PREFIX + "truststore.path"; +  public static final String CONFIG_PROPS_TRUSTSTORE_PASSWORD = CONFIG_PROPS_PREFIX + "truststore.password"; + +  public static final String CONFIG_PROPS_REQUIRED_PVP_ATTRIBUTES_LIST = CONFIG_PROPS_PREFIX +      + "required.additional.attributes"; +  public static final String CONFIG_PROPS_REQUIRED_LOA = CONFIG_PROPS_PREFIX +      + "required.loa"; +  public static final String CONFIG_PROPS_NODE_ENTITYID = CONFIG_PROPS_PREFIX + "node.entityId"; +  public static final String CONFIG_PROPS_NODE_METADATAURL = CONFIG_PROPS_PREFIX + "node.metadataUrl"; +  public static final String CONFIG_PROPS_NODE_TRUSTPROFILEID = CONFIG_PROPS_PREFIX + "node.trustprofileID"; + + +  public static final String CONFIG_PROPS_METADATA_CONTACT_GIVENNAME = +      CONFIG_PROPS_PREFIX + "metadata.contact.givenname"; +  public static final String CONFIG_PROPS_METADATA_CONTACT_SURNAME = +      CONFIG_PROPS_PREFIX + "metadata.contact.surname"; +  public static final String CONFIG_PROPS_METADATA_CONTACT_EMAIL = +      CONFIG_PROPS_PREFIX + "metadata.contact.email"; +  public static final String CONFIG_PROPS_METADATA_ORGANISATION_NAME = +      CONFIG_PROPS_PREFIX + "metadata.organisation.name"; +  public static final String CONFIG_PROPS_METADATA_ORGANISATION_FRIENDLYNAME = +      CONFIG_PROPS_PREFIX + "metadata.organisation.friendyname"; +  public static final String CONFIG_PROPS_METADATA_ORGANISATION_URL = +      CONFIG_PROPS_PREFIX + "metadata.organisation.url"; + +  public static final String CONFIG_PROPS_APPSPECIFIC_EIDAS_NODE_URL = "auth.eidas.node.entityId"; + +  public static final String CONFIG_PROPS_SEMPER_MANDATES_ACTIVE = CONFIG_PROPS_PREFIX +      + "semper.mandates.active"; +  public static final String CONFIG_PROPS_SEMPER_MANDATES_MS_PROXY_LIST = CONFIG_PROPS_PREFIX +      + "semper.msproxy.list"; + +  public static final String CONFIG_DEFAULT_LOA_EIDAS_LEVEL = EaafConstants.EIDAS_LOA_HIGH; + +  @Deprecated +  public static final List<Triple<String, String, Boolean>> DEFAULT_REQUIRED_PVP_ATTRIBUTES_WITHOUT_EID = +      Collections.unmodifiableList(new ArrayList<Triple<String, String, Boolean>>() { +        private static final long serialVersionUID = 1L; +        { +          // add PVP Version attribute +          add(Triple.newInstance(PvpAttributeDefinitions.PVP_VERSION_NAME, +              PvpAttributeDefinitions.PVP_VERSION_FRIENDLY_NAME, true)); + +          // request entity information +          add(Triple.newInstance(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, +              PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, false)); +          add(Triple.newInstance(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, +              PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, true)); +          add(Triple.newInstance(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, +              PvpAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME, true)); + +          // entity eID information +          add(Triple.newInstance(AhExtendedPvpAttributeDefinitions.EID_EIDBIND_NAME, +              AhExtendedPvpAttributeDefinitions.EID_EIDBIND_FRIENDLY_NAME, false)); +          add(Triple.newInstance(AhExtendedPvpAttributeDefinitions.EID_AUTHBLOCK_SIGNED_NAME, +              AhExtendedPvpAttributeDefinitions.EID_AUTHBLOCK_SIGNED_FRIENDLY_NAME, false)); + +          // Deprecated information +          add(Triple.newInstance(PvpAttributeDefinitions.GIVEN_NAME_NAME, +              PvpAttributeDefinitions.GIVEN_NAME_FRIENDLY_NAME, false)); +          add(Triple.newInstance(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, +              PvpAttributeDefinitions.PRINCIPAL_NAME_FRIENDLY_NAME, false)); +          add(Triple.newInstance(PvpAttributeDefinitions.BIRTHDATE_NAME, +              PvpAttributeDefinitions.BIRTHDATE_FRIENDLY_NAME, false)); +          add(Triple.newInstance(PvpAttributeDefinitions.BPK_NAME, PvpAttributeDefinitions.BPK_FRIENDLY_NAME, +              false)); +          add(Triple.newInstance(PvpAttributeDefinitions.EID_IDENTITY_LINK_NAME, +              PvpAttributeDefinitions.EID_IDENTITY_LINK_FRIENDLY_NAME, false)); + +          //request pII transactionId from MS-Connector +          add(Triple.newInstance(ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME, +              ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_FRIENDLY_NAME, false)); + +        } +      }); + +  public static final List<Triple<String, String, Boolean>> DEFAULT_REQUIRED_PVP_ATTRIBUTES = +      Collections.unmodifiableList(new ArrayList<Triple<String, String, Boolean>>() { +        private static final long serialVersionUID = 1L; +        { +          // add PVP Version attribute +          add(Triple.newInstance(PvpAttributeDefinitions.PVP_VERSION_NAME, +              PvpAttributeDefinitions.PVP_VERSION_FRIENDLY_NAME, true)); + +          // entity metadata information +          add(Triple.newInstance(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, +              PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_FRIENDLY_NAME, true)); +          add(Triple.newInstance(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, +              PvpAttributeDefinitions.EID_ISSUING_NATION_FRIENDLY_NAME, true)); + +          // entity eID information +          add(Triple.newInstance(AhExtendedPvpAttributeDefinitions.EID_EIDBIND_NAME, +              AhExtendedPvpAttributeDefinitions.EID_EIDBIND_FRIENDLY_NAME, true)); +          add(Triple.newInstance(AhExtendedPvpAttributeDefinitions.EID_AUTHBLOCK_SIGNED_NAME, +              AhExtendedPvpAttributeDefinitions.EID_AUTHBLOCK_SIGNED_FRIENDLY_NAME, true)); + +          //request pII transactionId from MS-Connector +          add(Triple.newInstance(ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME, +              ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_FRIENDLY_NAME, false)); + +        } +      }); + +  public static final List<String> DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES = +      Collections.unmodifiableList(new ArrayList<String>() { +        private static final long serialVersionUID = 1L; +        { +          for (final Triple<String, String, Boolean> el : DEFAULT_REQUIRED_PVP_ATTRIBUTES) { +            add(el.getFirst()); +          } +        } +      }); + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthCredentialProvider.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthCredentialProvider.java new file mode 100644 index 00000000..13c84bc5 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthCredentialProvider.java @@ -0,0 +1,130 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; + +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Credential provider for eIDAS PVP S-Profile client. + * + * @author tlenz + * + */ +public class EidasCentralAuthCredentialProvider extends AbstractCredentialProvider { + +  @Autowired +  IConfiguration authConfig; + +  private static final String FRIENDLYNAME = "eIDAS centrial authentication"; + +  @Override +  public KeyStoreConfiguration getBasicKeyStoreConfig() throws EaafConfigurationException { +    final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration(); +    keyStoreConfig.setFriendlyName(FRIENDLYNAME); +    keyStoreConfig.setKeyStoreType( +        authConfig.getBasicConfiguration(EidasCentralAuthConstants.CONFIG_PROPS_KEYSTORE_TYPE, +            KeyStoreType.PKCS12.getKeyStoreType())); +    keyStoreConfig.setKeyStoreName( +        authConfig.getBasicConfiguration(EidasCentralAuthConstants.CONFIG_PROPS_KEYSTORE_NAME)); +    keyStoreConfig.setSoftKeyStoreFilePath(getKeyStoreFilePath()); +    keyStoreConfig.setSoftKeyStorePassword( +        authConfig.getBasicConfiguration(EidasCentralAuthConstants.CONFIG_PROPS_KEYSTOREPASSWORD)); + +    return keyStoreConfig; + +  } + +  private String getKeyStoreFilePath() throws EaafConfigurationException { +    final String path = authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_KEYSTORE_PATH); +    if (path == null) { +      throw new EaafConfigurationException("module.eidasauth.00", +          new Object[] { EidasCentralAuthConstants.CONFIG_PROPS_KEYSTORE_PATH }); + +    } +    return path; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider# +   * getMetadataKeyAlias() +   */ +  @Override +  public String getMetadataKeyAlias() { +    return authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_SIGN_METADATA_ALIAS); +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider# +   * getMetadataKeyPassword() +   */ +  @Override +  public String getMetadataKeyPassword() { +    return authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_SIGN_METADATA_KEY_PASSWORD); +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider# +   * getSignatureKeyAlias() +   */ +  @Override +  public String getSignatureKeyAlias() { +    return authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_SIGN_SIGNING_ALIAS); +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider# +   * getSignatureKeyPassword() +   */ +  @Override +  public String getSignatureKeyPassword() { +    return authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_SIGN_SIGNING_KEY_PASSWORD); +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider# +   * getEncryptionKeyAlias() +   */ +  @Override +  public String getEncryptionKeyAlias() { +    return authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_ENCRYPTION_ALIAS); +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.signer.AbstractCredentialProvider# +   * getEncryptionKeyPassword() +   */ +  @Override +  public String getEncryptionKeyPassword() { +    return authConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_ENCRYPTION_KEY_PASSWORD); +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataConfiguration.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataConfiguration.java new file mode 100644 index 00000000..ca71807f --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataConfiguration.java @@ -0,0 +1,471 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.data.Triple; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder; + +import org.opensaml.saml.saml2.core.Attribute; +import org.opensaml.saml.saml2.core.NameIDType; +import org.opensaml.saml.saml2.metadata.ContactPerson; +import org.opensaml.saml.saml2.metadata.Organization; +import org.opensaml.saml.saml2.metadata.RequestedAttribute; +import org.opensaml.security.credential.Credential; + +import lombok.extern.slf4j.Slf4j; + +/** + * Configuration object to generate PVP S-Profile metadata for SAML2 client. + * + * @author tlenz + * + */ +@Slf4j +public class EidasCentralAuthMetadataConfiguration implements IPvpMetadataBuilderConfiguration { + +  private Collection<RequestedAttribute> additionalAttributes = null; + +  private final String authUrl; +  private final EidasCentralAuthCredentialProvider credentialProvider; +  private final IPvp2BasicConfiguration pvpConfiguration; + +  /** +   * Configuration object to create PVP2 S-Profile metadata information. +   * +   * @param authUrl            Public URL prefix of the application +   * @param credentialProvider Credentials used by PVP2 S-Profile end-point +   * @param pvpConfiguration   Basic PVP2 S-Profile end-point configuration +   */ +  public EidasCentralAuthMetadataConfiguration(String authUrl, +                                               EidasCentralAuthCredentialProvider credentialProvider, +                                               IPvp2BasicConfiguration pvpConfiguration) { +    this.authUrl = authUrl; +    this.credentialProvider = credentialProvider; +    this.pvpConfiguration = pvpConfiguration; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getMetadataValidUntil() +   */ +  @Override +  public int getMetadataValidUntil() { +    return EidasCentralAuthConstants.METADATA_VALIDUNTIL_IN_HOURS; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * buildEntitiesDescriptorAsRootElement() +   */ +  @Override +  public boolean buildEntitiesDescriptorAsRootElement() { +    return false; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * buildIDPSSODescriptor() +   */ +  @Override +  public boolean buildIdpSsoDescriptor() { +    return false; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * buildSPSSODescriptor() +   */ +  @Override +  public boolean buildSpSsoDescriptor() { +    return true; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getEntityIDPostfix() +   */ +  @Override +  public String getEntityID() { +    return authUrl + EidasCentralAuthConstants.ENDPOINT_METADATA; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getEntityFriendlyName() +   */ +  @Override +  public String getEntityFriendlyName() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getContactPersonInformation() +   */ +  @Override +  public List<ContactPerson> getContactPersonInformation() { +    try { +      return pvpConfiguration.getIdpContacts(); + +    } catch (final EaafException e) { +      log.warn("Can not load Metadata entry: Contect Person", e); +      return null; + +    } + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getOrgansiationInformation() +   */ +  @Override +  public Organization getOrgansiationInformation() { +    try { +      return pvpConfiguration.getIdpOrganisation(); + +    } catch (final EaafException e) { +      log.warn("Can not load Metadata entry: Organisation", e); +      return null; + +    } +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getMetadataSigningCredentials() +   */ +  @Override +  public EaafX509Credential getMetadataSigningCredentials() throws CredentialsNotAvailableException { +    return credentialProvider.getMetaDataSigningCredential(); + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getRequestorResponseSigningCredentials() +   */ +  @Override +  public Credential getRequestorResponseSigningCredentials() throws CredentialsNotAvailableException { +    return credentialProvider.getMessageSigningCredential(); + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getEncryptionCredentials() +   */ +  @Override +  public Credential getEncryptionCredentials() throws CredentialsNotAvailableException { +    return credentialProvider.getMessageEncryptionCredential(); + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getIDPWebSSOPostBindingURL() +   */ +  @Override +  public String getIdpWebSsoPostBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getIDPWebSSORedirectBindingURL() +   */ +  @Override +  public String getIdpWebSsoRedirectBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getIDPSLOPostBindingURL() +   */ +  @Override +  public String getIdpSloPostBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getIDPSLORedirectBindingURL() +   */ +  @Override +  public String getIdpSloRedirectBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPAssertionConsumerServicePostBindingURL() +   */ +  @Override +  public String getSpAssertionConsumerServicePostBindingUrl() { +    return authUrl + EidasCentralAuthConstants.ENDPOINT_POST; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPAssertionConsumerServiceRedirectBindingURL() +   */ +  @Override +  public String getSpAssertionConsumerServiceRedirectBindingUrl() { +    return authUrl + EidasCentralAuthConstants.ENDPOINT_REDIRECT; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPSLOPostBindingURL() +   */ +  @Override +  public String getSpSloPostBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPSLORedirectBindingURL() +   */ +  @Override +  public String getSpSloRedirectBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPSLOSOAPBindingURL() +   */ +  @Override +  public String getSpSloSoapBindingUrl() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getIDPPossibleAttributes() +   */ +  @Override +  public List<Attribute> getIdpPossibleAttributes() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getIDPPossibleNameITTypes() +   */ +  @Override +  public List<String> getIdpPossibleNameIdTypes() { +    return null; +  } + + + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPRequiredAttributes() +   */ +  @Override +  public Collection<RequestedAttribute> getSpRequiredAttributes() { +    final Map<String, RequestedAttribute> requestedAttributes = new HashMap<>(); + +    if (pvpConfiguration.getBasicConfiguration().getBasicConfigurationBoolean( +        AuthHandlerConstants.PROP_CONFIG_LEGACY_ALLOW, false)) { +      log.trace("Build required attributes for legacy operaton ... "); +      injectDefinedAttributes(requestedAttributes, +          EidasCentralAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTES_WITHOUT_EID); + +    } else { +      log.trace("Build required attributes for E-ID operaton ... "); +      injectDefinedAttributes(requestedAttributes, +          EidasCentralAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTES); + +    } + +    if (additionalAttributes != null) { +      log.trace("Add additional PVP attributes into metadata ... "); +      for (final RequestedAttribute el : additionalAttributes) { +        if (requestedAttributes.containsKey(el.getName())) { +          log.debug("Attribute " + el.getName() +              + " is already added by default configuration. Overwrite it by user configuration"); +        } + +        requestedAttributes.put(el.getName(), el); + +      } +    } + +    return requestedAttributes.values(); + +  } + + + +  /* +   * (non-Javadoc) +   * +   * @see +   * at.gv.egovernment.moa.id.protocols.pvp2x.builder.AbstractPVPMetadataBuilder# +   * getSPAllowedNameITTypes() +   */ +  @Override +  public List<String> getSpAllowedNameIdTypes() { +    return Arrays.asList(NameIDType.PERSISTENT); + +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPMetadataBuilderConfiguration#getSPNameForLogging() +   */ +  @Override +  public String getSpNameForLogging() { +    return EidasCentralAuthConstants.MODULE_NAME_FOR_LOGGING; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPMetadataBuilderConfiguration#wantAssertionSigned() +   */ +  @Override +  public boolean wantAssertionSigned() { +    return false; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPMetadataBuilderConfiguration#wantAuthnRequestSigned() +   */ +  @Override +  public boolean wantAuthnRequestSigned() { +    return true; +  } + +  /** +   * Add additonal PVP attributes that are required by this deployment. +   * +   * @param additionalAttr List of PVP attribute name and isRequired flag +   */ +  public void setAdditionalRequiredAttributes(List<Pair<String, Boolean>> additionalAttr) { +    if (additionalAttr != null && !additionalAttr.isEmpty()) { +      additionalAttributes = new ArrayList<>(); +      for (final Pair<String, Boolean> el : additionalAttr) { +        final Attribute attributBuilder = PvpAttributeBuilder.buildEmptyAttribute(el.getFirst()); +        if (attributBuilder != null) { +          additionalAttributes.add( +              PvpAttributeBuilder.buildReqAttribute( +                  attributBuilder.getName(), +                  attributBuilder.getFriendlyName(), +                  el.getSecond())); + +        } else { +          log.info("NO PVP attribute with name: " + el.getFirst()); +        } + +      } +    } +  } + +  private void injectDefinedAttributes(Map<String, RequestedAttribute> requestedAttributes, +                                       List<Triple<String, String, Boolean>> attributes) { +    for (final Triple<String, String, Boolean> el : attributes) { +      requestedAttributes.put(el.getFirst(), PvpAttributeBuilder.buildReqAttribute(el.getFirst(), el +          .getSecond(), el.getThird())); + +    } +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataController.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataController.java new file mode 100644 index 00000000..90e1e674 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataController.java @@ -0,0 +1,149 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.http.HttpUtils; +import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.google.common.net.MediaType; +import lombok.extern.slf4j.Slf4j; + +/** + * Controller that generates SAML2 metadata for eIDAS authentication client. + * + * @author tlenz + * + */ +@Slf4j +@Controller +public class EidasCentralAuthMetadataController extends AbstractController { + +  private static final String ERROR_CODE_INTERNAL_00 = "eaaf.core.00"; + +  @Autowired +  PvpMetadataBuilder metadatabuilder; +  @Autowired +  EidasCentralAuthCredentialProvider credentialProvider; +  @Autowired +  IPvp2BasicConfiguration pvpConfiguration; + +  /** +   * Default construction with logging. +   * +   */ +  public EidasCentralAuthMetadataController() { +    super(); +    log.debug("Registering servlet " + getClass().getName() +        + " with mappings '" + EidasCentralAuthConstants.ENDPOINT_METADATA +        + "'."); + +  } + +  /** +   * End-point that produce PVP2 metadata for eIDAS authentication client. +   * +   * @param req  http Request +   * @param resp http Response +   * @throws IOException   In case of an I/O error +   * @throws EaafException In case of a metadata generation error +   */ +  @RequestMapping(value = EidasCentralAuthConstants.ENDPOINT_METADATA, +      method = { RequestMethod.GET }) +  public void getSpMetadata(HttpServletRequest req, HttpServletResponse resp) throws IOException, +      EaafException { +    // check PublicURL prefix +    try { +      final String authUrl = getAuthUrlFromHttpContext(req); + +      // initialize metadata builder configuration +      final EidasCentralAuthMetadataConfiguration metadataConfig = +          new EidasCentralAuthMetadataConfiguration(authUrl, credentialProvider, pvpConfiguration); +      metadataConfig.setAdditionalRequiredAttributes(getAdditonalRequiredAttributes()); + +      // build metadata +      final String xmlMetadata = metadatabuilder.buildPvpMetadata(metadataConfig); + +      // write response +      final byte[] content = xmlMetadata.getBytes("UTF-8"); +      resp.setStatus(HttpServletResponse.SC_OK); +      resp.setContentLength(content.length); +      resp.setContentType(MediaType.XML_UTF_8.toString()); +      resp.getOutputStream().write(content); + +    } catch (final Exception e) { +      log.warn("Build federated-authentication PVP metadata FAILED.", e); +      protAuthService.handleErrorNoRedirect(e, req, resp, false); + +    } + +  } + +  private String getAuthUrlFromHttpContext(HttpServletRequest req) throws EaafException { +    // check if End-Point is valid +    final String authUrlString = HttpUtils.extractAuthUrlFromRequest(req); +    URL authReqUrl; +    try { +      authReqUrl = new URL(authUrlString); + +    } catch (final MalformedURLException e) { +      log.warn("Requested URL: {} is not a valid URL.", authUrlString); +      throw new EaafAuthenticationException(ERROR_CODE_INTERNAL_00, new Object[] { authUrlString }, e); + +    } + +    final String idpAuthUrl = authConfig.validateIdpUrl(authReqUrl); +    if (idpAuthUrl == null) { +      log.warn("Requested URL: {} is NOT found in configuration.", authReqUrl); +      throw new EaafAuthenticationException(ERROR_CODE_INTERNAL_00, new Object[] { authUrlString }); + +    } + +    return idpAuthUrl; +  } + +  private List<Pair<String, Boolean>> getAdditonalRequiredAttributes() { +    final List<Pair<String, Boolean>> result = new ArrayList<>(); + +    // load attributes from configuration +    final Map<String, String> addReqAttributes = authConfig.getBasicConfigurationWithPrefix( +        EidasCentralAuthConstants.CONFIG_PROPS_REQUIRED_PVP_ATTRIBUTES_LIST); +    for (final String el : addReqAttributes.values()) { +      if (StringUtils.isNotEmpty(el)) { +        log.trace("Parse additional attr. definition: " + el); +        final List<String> attr = KeyValueUtils.getListOfCsvValues(el.trim()); +        if (attr.size() == 2) { +          result.add(Pair.newInstance(attr.get(0), Boolean.parseBoolean(attr.get(1)))); + +        } else { +          log.info("IGNORE additional attr. definition: " + el +              + " Reason: Format not valid"); +        } +      } +    } + +    return result; + +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataProvider.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataProvider.java new file mode 100644 index 00000000..b920e789 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthMetadataProvider.java @@ -0,0 +1,169 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.Provider; +import java.security.cert.CertificateException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.annotation.PostConstruct; + +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; +import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2MetadataException; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.AbstractChainingMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.PvpMetadataResolverFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SchemaValidationFilter; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.metadata.SimpleMetadataSignatureVerificationFilter; + +import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml.metadata.resolver.MetadataResolver; +import org.opensaml.saml.metadata.resolver.filter.MetadataFilter; +import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain; +import org.springframework.beans.factory.annotation.Autowired; + +import lombok.extern.slf4j.Slf4j; + +/** + * SAML2 metadata-provider implementation for eIDAS client. + * + * @author tlenz + * + */ +@Slf4j +public class EidasCentralAuthMetadataProvider extends AbstractChainingMetadataProvider { + +  private static final String FRIENDLYNAME_METADATA_TRUSTSTORE = "'eIDAS_client metadata truststore'"; +  private static final String PROVIDER_ID_PATTERN = "eIDAS resolver: {0}"; +  public static final String PROVIDER_ID = "'eIDAS_client metadata provider'"; + +  @Autowired +  private IConfiguration basicConfig; + +  @Autowired +  private PvpMetadataResolverFactory metadataProviderFactory; +  @Autowired +  private IHttpClientFactory httpClientFactory; + +  @Autowired +  private EaafKeyStoreFactory keyStoreFactory; + +  private Pair<KeyStore, Provider> metadataSigningTrustStore; + +  @Override +  protected String getMetadataUrl(String entityId) throws EaafConfigurationException { +    log.trace("eIDAS Auth. uses SAML2 well-known location approach. EntityId is Metadata-URL"); +    return entityId; + +  } + +  @Override +  protected MetadataResolver createNewMetadataProvider(String entityId) throws EaafConfigurationException, +      IOException, CertificateException { +    final List<MetadataFilter> filterList = new ArrayList<>(); +    filterList.add(new SchemaValidationFilter(true)); +    filterList.add(new SimpleMetadataSignatureVerificationFilter( +        metadataSigningTrustStore.getFirst(), entityId)); + +    final MetadataFilterChain filter = new MetadataFilterChain(); +    filter.setFilters(filterList); + +    try { +      return metadataProviderFactory.createMetadataProvider(getMetadataUrl(entityId), +          filter, +          MessageFormat.format(PROVIDER_ID_PATTERN, entityId), +          httpClientFactory.getHttpClient()); + +    } catch (final Pvp2MetadataException e) { +      log.info("Can NOT build metadata provider for entityId: {}", entityId); +      throw new EaafConfigurationException("module.eidasauth.04", +          new Object[] { entityId, e.getMessage() }, e); + +    } +  } + +  @Override +  protected List<String> getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException { +    return Collections.emptyList(); + +  } + +  @Override +  protected String getMetadataProviderId() { +    return PROVIDER_ID; + +  } + +  @Override +  public void runGarbageCollector() { +    log.trace("Garbage collection is NOT supported by: {}", getId()); +  } + +  @Override +  public void doDestroy() { +    super.fullyDestroy(); + +  } + +  @PostConstruct +  private void initialize() throws EaafException { +    // initialize truststore to validate metadata signing certificates +    initializeTrustStore(); + +    // load metadata with metadataURL, as backup +    initializeFileSystemMetadata(); + +  } + +  private void initializeFileSystemMetadata() { +    try { +      final String metadataUrl = basicConfig.getBasicConfiguration( +          EidasCentralAuthConstants.CONFIG_PROPS_NODE_METADATAURL); +      if (StringUtils.isNotEmpty(metadataUrl)) { +        log.info("Use not recommended metadata-provider initialization!" +            + " SAML2 'Well-Known-Location' is the preferred methode."); +        log.info("Initialize 'ms-specific eIDAS node' metadata-provider with URL: {}", metadataUrl); + +        addMetadataResolverIntoChain(createNewMetadataProvider(metadataUrl)); +      } + +    } catch (final EaafConfigurationException | CertificateException | IOException e) { +      log.warn("Can NOT inject static eIDAS Node metadata-soure.", e); +      log.warn("eIDAS Node communication can be FAIL."); + +    } +  } + +  private void initializeTrustStore() throws EaafException { +    // set configuration +    final KeyStoreConfiguration trustStoreConfig = new KeyStoreConfiguration(); +    trustStoreConfig.setFriendlyName(FRIENDLYNAME_METADATA_TRUSTSTORE); +    trustStoreConfig.setKeyStoreType(basicConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_TRUSTSTORE_TYPE, +        KeyStoreType.JKS.getKeyStoreType())); +    trustStoreConfig.setKeyStoreName(basicConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_TRUSTSTORE_NAME)); +    trustStoreConfig.setSoftKeyStoreFilePath(basicConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_TRUSTSTORE_PATH)); +    trustStoreConfig.setSoftKeyStorePassword(basicConfig.getBasicConfiguration( +        EidasCentralAuthConstants.CONFIG_PROPS_TRUSTSTORE_PASSWORD)); + +    // validate configuration +    trustStoreConfig.validate(); + +    // open new TrustStore +    metadataSigningTrustStore = keyStoreFactory.buildNewKeyStore(trustStoreConfig); + +  } + +} + diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthRequestBuilderConfiguration.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthRequestBuilderConfiguration.java new file mode 100644 index 00000000..723654eb --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/EidasCentralAuthRequestBuilderConfiguration.java @@ -0,0 +1,300 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + +import java.util.List; + +import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPvpAuthnRequestBuilderConfiguruation; + +import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration; +import org.opensaml.saml.saml2.core.NameIDType; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; +import org.w3c.dom.Element; + +public class EidasCentralAuthRequestBuilderConfiguration implements IPvpAuthnRequestBuilderConfiguruation { + +  private boolean isPassive; +  private String spEntityId; +  private String qaaLevel; +  private EntityDescriptor idpEntity; +  private EaafX509Credential signCred; +  private String scopeRequesterId; +  private String providerName; +  private List<EaafRequestedAttribute> requestedAttributes; +  private String reqId; + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#isPassivRequest() +   */ +  @Override +  public Boolean isPassivRequest() { +    return this.isPassive; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getAssertionConsumerServiceId() +   */ +  @Override +  public Integer getAssertionConsumerServiceId() { +    return 0; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getEntityID() +   */ +  @Override +  public String getSpEntityID() { +    return this.spEntityId; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getNameIDPolicy() +   */ +  @Override +  public String getNameIdPolicyFormat() { +    return NameIDType.PERSISTENT; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getNameIDPolicy() +   */ +  @Override +  public boolean getNameIdPolicyAllowCreation() { +    return true; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getAuthnContextClassRef() +   */ +  @Override +  public String getAuthnContextClassRef() { +    return this.qaaLevel; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getAuthnContextComparison() +   */ +  @Override +  public AuthnContextComparisonTypeEnumeration getAuthnContextComparison() { +    return AuthnContextComparisonTypeEnumeration.MINIMUM; +  } + +  /** +   * Set isPassive flag in SAML2 request. +   * +   * @param isPassive the isPassive to set. +   */ +  public void setPassive(boolean isPassive) { +    this.isPassive = isPassive; +  } + +  /** +   * Set the requester EntityId. +   * +   * @param spEntityId EntityId of SP +   */ +  public void setSpEntityID(String spEntityId) { +    this.spEntityId = spEntityId; +  } + +  /** +   * Set required LoA. +   * +   * @param loa the LoA to set. +   */ +  public void setRequestedLoA(String loa) { +    qaaLevel = loa; +  } + +  /** +   * Set EntityId of IDP. +   * +   * @param idpEntity the idpEntity to set. +   */ +  public void setIdpEntity(EntityDescriptor idpEntity) { +    this.idpEntity = idpEntity; +  } + +  /** +   * Set message signing credentials. +   * +   * @param signCred the signCred to set. +   */ +  public void setSignCred(EaafX509Credential signCred) { +    this.signCred = signCred; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getAuthnRequestSigningCredential() +   */ +  @Override +  public EaafX509Credential getAuthnRequestSigningCredential() { +    return this.signCred; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getIDPEntityDescriptor() +   */ +  @Override +  public EntityDescriptor getIdpEntityDescriptor() { +    return this.idpEntity; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getSubjectNameID() +   */ +  @Override +  public String getSubjectNameID() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getSPNameForLogging() +   */ +  @Override +  public String getSpNameForLogging() { +    return EidasCentralAuthConstants.MODULE_NAME_FOR_LOGGING; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getSubjectNameIDFormat() +   */ +  @Override +  public String getSubjectNameIdFormat() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getRequestID() +   */ +  @Override +  public String getRequestID() { +    return this.reqId; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getSubjectNameIDQualifier() +   */ +  @Override +  public String getSubjectNameIdQualifier() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getSubjectConformationMethode() +   */ +  @Override +  public String getSubjectConformationMethode() { +    return null; +  } + +  /* +   * (non-Javadoc) +   * +   * @see at.gv.egovernment.moa.id.protocols.pvp2x.config. +   * IPVPAuthnRequestBuilderConfiguruation#getSubjectConformationDate() +   */ +  @Override +  public Element getSubjectConformationDate() { +    return null; +  } + +  @Override +  public List<EaafRequestedAttribute> getRequestedAttributes() { +    return this.requestedAttributes; + +  } + +  @Override +  public String getProviderName() { +    return this.providerName; +  } + +  @Override +  public String getScopeRequesterId() { +    return this.scopeRequesterId; +  } + +  /** +   * Set the entityId of the SP that requests the proxy for eIDAS authentication. +   * +   * @param scopeRequesterId RequestId in SAML2 Proxy extension +   */ +  public void setScopeRequesterId(String scopeRequesterId) { +    this.scopeRequesterId = scopeRequesterId; +  } + +  /** +   * Set a friendlyName for the SP that requests the proxy for eIDAS +   * authentication. +   * +   * @param providerName SAML2 provider-name attribute-value +   */ +  public void setProviderName(String providerName) { +    this.providerName = providerName; +  } + +  /** +   * Set a Set of PVP attributes that a requested by using requested attributes. +   * +   * @param requestedAttributes Requested SAML2 attributes +   */ +  public void setRequestedAttributes(List<EaafRequestedAttribute> requestedAttributes) { +    this.requestedAttributes = requestedAttributes; +  } + +  /** +   * Set a RequestId for this Authn. Request. +   * +   * @param reqId SAML2 message requestId +   */ +  public void setRequestId(String reqId) { +    this.reqId = reqId; +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/IAhSpConfiguration.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/IAhSpConfiguration.java new file mode 100644 index 00000000..d8e873c0 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/mobilesig/IAhSpConfiguration.java @@ -0,0 +1,151 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig; + +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration; +import at.gv.egiz.eaaf.core.impl.data.Pair; + +public interface IAhSpConfiguration extends ISpConfiguration { + + +  /** +   * Flag if this Service Provider is enabled. +   * +   * @return true if the SP is enabled, otherwise false +   */ +  boolean isEnabled(); + +  /** +   * Get unique identifier that is used in Application-Register from BM.I. +   * +   * <p>If no BM.I specific identifier is available then this method returns +   * the same identifier as <code>getUniqueIdentifier()</code></p> +   * +   * @return unique identifier from BM.I AppReg, or generic uniqueId of no specific exists +   */ +  String getUniqueApplicationRegisterIdentifier(); + +  /** +   * Flag that marks this Service-Provider as <i>public</i> or <i>private</i>. +   * +   * <p><b>Default:</b> If it is not set or has an unknown value, its <i>private</i> by default</p> +   * +   * @return <code>true</code> if it is from <i>public</i>, otherwise <code>false</code> +   */ +  boolean isPublicServiceProvider(); + +  /** +   * Enable test identities for this Service Provider. +   * +   * @return true if test identities are allowed, otherwise false +   */ +  boolean isTestCredentialEnabled(); + +  /** +   * Get a List of OID's that refine the set of allowed test identities. +   * +   * @return @link {@link List} of test-identity OID's +   */ +  @Nullable +  List<String> getTestCredentialOids(); + + +  /** +   * Get a List of unique attribute URI's that are required by this SP. +   * +   * @return {@link List} of attribute URI's / parameter {@link Pair}s +   */ +  List<Pair<String, String>> getRequiredAttributes(); + + +  /** +   * Get the CountryCode for this service. <br> +   * <br> +   * <b>Default:</b> AT +   * +   * @return +   */ +  String getCountryCode(); + +  /** +   * Set the CountryCode for this service. If not countryCode is set, AT is used as default. +   * +   * @param cc Service-Provider country-code +   */ +  void setCountryCode(String cc); + +  /** +   * Enable mandates for this service provider. +   * +   * @return <code>true</code> if mandates are enabled, otherwise <code>false</code> +   */ +  boolean isMandateEnabled(); + +  /** +   * Enables multi-mandates for this service-provider. +   * +   * @return <code>true</code> if multi-mandates are enabled, otherwise <code>false</code> +   */ +  boolean isMultiMandateEnabled(); + +  /** +   * Only mandates are allowed for this service provider. +   * +   * @return <code>true</code> if only mandates are allowed, otherwise <code>false</code> +   */ +  boolean isOnlyMandateEnabled(); + +  /** +   * Get a {@link List} of mandate profiles that are supported by this Service provider. +   * +   * @return +   */ +  @Nonnull List<String> getMandateProfiles(); + + +  /** +   * eIDAS authentication allowed flag. +   * +   * @return <code>true</code> if eIDAS authentication is enabled, otherwise <code>false</code> +   */ +  boolean isEidasEnabled(); + +  /** +   * Get a List of targets for additional bPKs that are required by this service provider. +   * +   * @return List of prefixed bPK targets +   */ +  @Nonnull List<String> getAdditionalBpkTargets(); + +  /** +   * Get a list of foreign bPK targets that are required by this service provider. +   * +   * @return List of pairs with prefixed bPK targets as first element and VKZ as second element +   */ +  @Nonnull List<Pair<String, String>> getAdditionalForeignBpkTargets(); + +  /** +   * Flag that indicates that service-provider as restricted or unrestricted. +   * +   * <p>A restricted service-provider can only used by test-identities that contains a +   * valid application-restriction in User-Certificate Pinning</p> +   * +   * <p><b>Default:</b> true</p> +   * +   * @return <code>true</code> if it is restricted, otherwise <code>false</code> +   */ +  boolean isRestrictedServiceProvider(); + + +  /** +   * Defines the time in minutes how long the last VDA registration h@Override +   ave passed as maximum. +   * +   * @return time in minutes +   */ +  long lastVdaAuthenticationDelay(); + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java index 736ac6e5..3f2ae1f2 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java @@ -23,15 +23,36 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig.EidasCentralAuthConstants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig.EidasCentralAuthCredentialProvider; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig.EidasCentralAuthMetadataProvider; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig.EidasCentralAuthRequestBuilderConfiguration; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig.IAhSpConfiguration; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;  import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;  import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;  import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpAttributeBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import at.gv.egiz.eaaf.modules.pvp2.sp.impl.PvpAuthnRequestBuilder;  import lombok.extern.slf4j.Slf4j; +import net.shibboleth.utilities.java.support.security.SecureRandomIdentifierGenerationStrategy;  import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml.saml2.core.Attribute; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; +import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Component;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List;  /**   * Task that searches ErnB and ZMR before adding person to SZR. @@ -43,12 +64,31 @@ import javax.servlet.http.HttpServletResponse;  public class GenerateMobilePhoneSignatureRequestTask extends AbstractAuthServletTask { +  private static final String ERROR_CODE_02 = "module.eidasauth.02"; + +  private static final String ERROR_MSG_1 = +      "Requested 'ms-specific eIDAS node' {0} has no valid metadata or metadata is not found"; + +  @Autowired +  PvpAuthnRequestBuilder authnReqBuilder; +  @Autowired +  EidasCentralAuthCredentialProvider credential; +  @Autowired +  EidasCentralAuthMetadataProvider metadataService; +  //  @Autowired +  //  ITransactionStorage transactionStorage; + +    @Override    public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)        throws TaskExecutionException {      try {        log.trace("Starting GenerateMobilePhoneSignatureRequestTask");        //step 15a + +      //final IAhSpConfiguration spConfig = pendingReq.getServiceProviderConfiguration( +      //    IAhSpConfiguration.class); +        // get entityID for ms-specific eIDAS node        final String msNodeEntityID = "TODO"; @@ -57,6 +97,45 @@ public class GenerateMobilePhoneSignatureRequestTask extends AbstractAuthServlet          throw new TaskExecutionException(pendingReq, "", null);        } + +      // load IDP SAML2 entitydescriptor +      final EntityDescriptor entityDesc = metadataService.getEntityDescriptor(msNodeEntityID); +      if (entityDesc == null) { +        throw new EaafConfigurationException(ERROR_CODE_02, +            new Object[]{MessageFormat.format(ERROR_MSG_1, msNodeEntityID)}); + +      } + +      // setup AuthnRequestBuilder configuration +      final EidasCentralAuthRequestBuilderConfiguration authnReqConfig = +          new EidasCentralAuthRequestBuilderConfiguration(); +      final SecureRandomIdentifierGenerationStrategy gen = +          new SecureRandomIdentifierGenerationStrategy(); +      authnReqConfig.setRequestId(gen.generateIdentifier()); +      authnReqConfig.setIdpEntity(entityDesc); +      authnReqConfig.setPassive(false); +      authnReqConfig.setSignCred(credential.getMessageSigningCredential()); +      authnReqConfig.setSpEntityID(pendingReq.getAuthUrl() + EidasCentralAuthConstants.ENDPOINT_METADATA); +      authnReqConfig.setRequestedLoA(authConfig.getBasicConfiguration( +          EidasCentralAuthConstants.CONFIG_PROPS_REQUIRED_LOA, +          EidasCentralAuthConstants.CONFIG_DEFAULT_LOA_EIDAS_LEVEL)); + +      authnReqConfig.setScopeRequesterId( +          pendingReq.getServiceProviderConfiguration(IAhSpConfiguration.class) +              .getUniqueApplicationRegisterIdentifier()); +      authnReqConfig.setProviderName(pendingReq.getServiceProviderConfiguration().getFriendlyName()); +      authnReqConfig.setRequestedAttributes(buildRequestedAttributes(pendingReq)); + +      /*build relayState for session synchronization, because SAML2 only allows RelayState with 80 characters +       * but encrypted PendingRequestId is much longer. +       */ +      String relayState = Random.nextProcessReferenceValue(); +      //      transactionStorage.put(relayState, pendingReq.getPendingRequestId(), -1); + +      // build and transmit AuthnRequest +      authnReqBuilder.buildAuthnRequest(pendingReq, authnReqConfig, relayState, response); + +        //MsEidasNodeConstants.ENDPOINT_PVP_POST        //MsEidasNodeConstants.ENDPOINT_PVP_METADATA @@ -67,4 +146,28 @@ public class GenerateMobilePhoneSignatureRequestTask extends AbstractAuthServlet      }    } +  private List<EaafRequestedAttribute> buildRequestedAttributes(IRequest pendingReq) { +    final List<EaafRequestedAttribute> attributes = new ArrayList<>(); + +    //build TransactionId attribute +    final Attribute attrTransId = PvpAttributeBuilder.buildEmptyAttribute( +        ExtendedPvpAttributeDefinitions.EID_TRANSACTION_ID_NAME); +    final EaafRequestedAttribute attrTransIdReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +        attrTransId, +        true, +        pendingReq.getUniqueTransactionIdentifier()); +    attributes.add(attrTransIdReqAttr); + +    // build EID sector for identification attribute +    final Attribute attr = PvpAttributeBuilder.buildEmptyAttribute( +        PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME); +    final EaafRequestedAttribute bpkTargetReqAttr = Saml2Utils.generateReqAuthnAttributeSimple( +        attr, +        true, +        pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); +    attributes.add(bpkTargetReqAttr); + +    return attributes; +  } +  } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml index d669835f..e1e3aedd 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml @@ -133,4 +133,8 @@    <bean id="ReceiveGuiAustrianResidenceResponseTask"          class="at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveGuiAustrianResidenceResponseTask"          scope="prototype" /> + +  <bean id="eidasCentralAuthCredentialProvider" +        class="at.asitplus.eidas.specific.modules.auth.eidas.v2.mobilesig.EidasCentralAuthCredentialProvider" /> +  </beans>
\ No newline at end of file | 
