diff options
9 files changed, 141 insertions, 50 deletions
| diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java index a9eb06be..881eeb8a 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java @@ -75,7 +75,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {        if (nameIdPolicy != null) {          final String nameIdFormat = nameIdPolicy.getFormat();          if (nameIdFormat != null) { -          if (!(NameIDType.TRANSIENT.equals(nameIdFormat)  +          if (!(NameIDType.TRANSIENT.equals(nameIdFormat)                || NameIDType.PERSISTENT.equals(nameIdFormat))) {              throw new NameIdFormatNotSupportedException(nameIdFormat); @@ -114,10 +114,10 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {        // post-process requested LoA comparison-level        pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setLoAMachtingMode(            extractComparisonLevel(authnReq)); -       -      //extract information from requested attributes + +      // extract information from requested attributes        extractFromRequestedAttriutes(pendingReq, authnReq); -       +      } catch (final EaafStorageException e) {        log.info("Can NOT store Authn. Req. data into pendingRequest.", e);        throw new AuthnRequestValidatorException("internal.02", null, e); @@ -126,14 +126,14 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {    } -  private void extractFromRequestedAttriutes(IRequest pendingReq, AuthnRequest authnReq)  -      throws AuthnRequestValidatorException { +  private void extractFromRequestedAttriutes(IRequest pendingReq, AuthnRequest authnReq) +      throws AuthnRequestValidatorException, EaafStorageException {      // validate and process requested attributes      boolean sectorDetected = false; -     +      final ServiceProviderConfiguration spConfig = pendingReq.getServiceProviderConfiguration(          ServiceProviderConfiguration.class); -     +      if (authnReq.getExtensions() != null) {        final List<XMLObject> requestedAttributes = authnReq.getExtensions().getUnknownXMLObjects();        for (final XMLObject reqAttrObj : requestedAttributes) { @@ -143,77 +143,101 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {              for (final EaafRequestedAttribute el : reqAttr.getAttributes()) {                log.trace("Processing req. attribute '" + el.getName() + "' ... ");                if (el.getName().equals(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME)) { -                sectorDetected = extractBpkTargetIdentifier(el, spConfig);  -                +                sectorDetected = extractBpkTargetIdentifier(el, spConfig); +                } else if (el.getName().equals(ExtendedPvpAttributeDefinitions.EID_TRANSACTION_ID_NAME)) {                  extractUniqueTransactionId(el, pendingReq); -                 + +              } else if (el.getName().equals(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME)) { +                extractBindingPublicKey(el, pendingReq); +                } else {                  log.debug("Ignore req. attribute: " + el.getName()); -                 +                }              }            } else {              log.debug("No requested Attributes in Authn. Request"); -             +            }          } else {            log.info("Ignore unknown requested attribute: " + reqAttrObj.getElementQName().toString()); -           +          }        }      } -     +      if (!sectorDetected) {        log.warn("Authn.Req validation FAILED. Reason: Contains NO or NO VALID target-sector information.");        throw new AuthnRequestValidatorException("pvp2.22", new Object[] {            "NO or NO VALID target-sector information" });      } -     + +  } + +  private void extractBindingPublicKey(EaafRequestedAttribute el, IRequest pendingReq) +      throws EaafStorageException { +    if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { +      final String bindingPubKey = el.getAttributeValues().get(0).getDOM().getTextContent(); +      pendingReq.setRawDataToTransaction(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME, bindingPubKey); +      log.info("Find Binding Public-Key. eIDAS authentication will be used to create an ID Austria Binding"); + +    } else { +      log.warn( +          "Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute", +          el.getName()); + +    }    }    /**     * Extract unique transactionId from AuthnRequest. -   *  -   * @param el Requested attribute from AuthnRequest -   * @param pendingReq Current pendingRequest object (has to be of type {@link RequestImpl}) -   * @return <code>true</code> if transactionId extraction was successful, otherwise <code>false</code> +   * +   * @param el         Requested attribute from AuthnRequest +   * @param pendingReq Current pendingRequest object (has to be of type +   *                   {@link RequestImpl}) +   * @return <code>true</code> if transactionId extraction was successful, +   *         otherwise <code>false</code>     */    private boolean extractUniqueTransactionId(EaafRequestedAttribute el, IRequest pendingReq) {      if (!(pendingReq instanceof RequestImpl)) { -      log.warn("Can NOT set unique transactionId from AuthnRequest,because 'PendingRequest' is NOT from Type: {}", +      log.warn( +          "Can NOT set unique transactionId from AuthnRequest,because 'PendingRequest' is NOT from Type: {}",            RequestImpl.class.getName()); -       -    } else {         + +    } else {        if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { -        final String transactionId = el.getAttributeValues().get(0).getDOM().getTextContent();       -        ((RequestImpl)pendingReq).setUniqueTransactionIdentifier(transactionId);       +        final String transactionId = el.getAttributeValues().get(0).getDOM().getTextContent(); +        ((RequestImpl) pendingReq).setUniqueTransactionIdentifier(transactionId);          return true;        } else { -        log.warn("Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute",  +        log.warn( +            "Req. attribute '{}' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute",              el.getName()); -         +        } -       +      } -     +      return false;    }    /**     * Extract the bPK target from requested attribute. -   *  -   * @param el Requested attribute from AuthnRequest +   * +   * @param el       Requested attribute from AuthnRequest     * @param spConfig Service-Provider configuration for current process -   * @return <code>true</code> if bPK target extraction was successful, otherwise <code>false</code> +   * @return <code>true</code> if bPK target extraction was successful, otherwise +   *         <code>false</code>     */ -  private boolean extractBpkTargetIdentifier(EaafRequestedAttribute el, ServiceProviderConfiguration spConfig) {         +  private boolean extractBpkTargetIdentifier(EaafRequestedAttribute el, +      ServiceProviderConfiguration spConfig) {      if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) { -      final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent();       +      final String sectorId = el.getAttributeValues().get(0).getDOM().getTextContent();        try {          spConfig.setBpkTargetIdentifier(sectorId);          return true; @@ -227,16 +251,16 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {        log.warn("Req. attribute '" + el.getName()            + "' contains NO or MORE THEN ONE attribute-values. Ignore full req. attribute");      } -     +      return false; -     +    } -   -  private void postprocessLoaLevel(IRequest pendingReq, AuthnRequest authnReq)  + +  private void postprocessLoaLevel(IRequest pendingReq, AuthnRequest authnReq)        throws AuthnRequestValidatorException {      final List<String> reqLoA = extractLoA(authnReq); -    log.trace("SP requests LoA with: {}", String.join(", ",reqLoA)); -     +    log.trace("SP requests LoA with: {}", String.join(", ", reqLoA)); +      LevelOfAssurance minimumLoAFromConfig = LevelOfAssurance.fromString(basicConfig.getBasicConfiguration(          MsEidasNodeConstants.PROP_EIDAS_REQUEST_LOA_MINIMUM_LEVEL,          EaafConstants.EIDAS_LOA_HIGH)); @@ -246,15 +270,15 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {        minimumLoAFromConfig = LevelOfAssurance.HIGH;      } -           +      log.trace("Validate requested LoA to connector configuration minimum LoA: {} ...", -        minimumLoAFromConfig);       +        minimumLoAFromConfig);      final List<String> allowedLoA = new ArrayList<>();      for (final String loa : reqLoA) {        try {          final LevelOfAssurance intLoa = LevelOfAssurance.fromString(loa);          String selectedLoA = EaafConstants.EIDAS_LOA_HIGH; -        if (intLoa != null  +        if (intLoa != null              && intLoa.numericValue() <= minimumLoAFromConfig.numericValue()) {            log.info("Client: {} requested LoA: {} will be upgraded to: {}",                pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(), @@ -281,7 +305,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {      pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class).setRequiredLoA(          allowedLoA); -     +    }    private String extractComparisonLevel(AuthnRequest authnReq) { @@ -335,7 +359,7 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {    private String extractScopeRequsterId(AuthnRequest authnReq) {      if (authnReq.getScoping() != null) {        final Scoping scoping = authnReq.getScoping(); -      if (scoping.getRequesterIDs() != null  +      if (scoping.getRequesterIDs() != null            && scoping.getRequesterIDs().size() > 0) {          if (scoping.getRequesterIDs().size() == 1) {            return scoping.getRequesterIDs().get(0).getRequesterID(); diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java index 77037415..fcb0e73a 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java @@ -6,6 +6,7 @@ import static org.powermock.api.mockito.PowerMockito.when;  import java.io.ByteArrayInputStream;  import java.io.IOException;  import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field;  import java.net.URISyntaxException;  import java.util.Map;  import java.util.Timer; @@ -71,6 +72,7 @@ import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.OpenSaml3ResourceAdapter;  import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer;  import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;  import at.gv.egiz.eaaf.modules.pvp2.sp.impl.utils.AssertionAttributeExtractor; +import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication;  import eu.eidas.auth.commons.attribute.AttributeDefinition;  import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;  import eu.eidas.auth.commons.light.ILightRequest; @@ -151,13 +153,19 @@ public class FullStartUpAndProcessTest {    /**     * Test shut-down.     * -   * @throws IOException In case of an error +   * @throws Exception In case of an error     */    @AfterClass -  public static void closeIgniteNode() throws IOException { +  public static void closeIgniteNode() throws Exception {      System.out.println("Closiong Ignite Node ... ");      Ignition.stopAll(true); +     +    //set Ignite-node holder to 'null' because static holders are shared between different tests +    final Field field = IgniteInstanceInitializerSpecificCommunication.class.getDeclaredField("instance"); +    field.setAccessible(true); +    field.set(null, null); +        }    /** diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java index 86df55df..708560b2 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java @@ -22,6 +22,7 @@ import org.junit.runners.BlockJUnit4ClassRunner;  import at.asitplus.eidas.specific.connector.SpringBootApplicationInitializer;  import at.gv.egiz.eaaf.core.impl.logging.DummyStatusMessager;  import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; +import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication;  import lombok.extern.slf4j.Slf4j;  @Slf4j @@ -50,17 +51,22 @@ public class MainClassExecutableModeTest {    /**     * Initializer. -   * @throws InterruptedException In case of an error  +   * @throws Exception In case of an error      *     */    @AfterClass -  public static void closeIgniteNode() throws InterruptedException { +  public static void closeIgniteNode() throws Exception {      System.out.println("Closing Ignite Node ... ");      log.info("Stopping already running Apache Ignite nodes ... ");      Ignition.stopAll(true);          Thread.sleep(1000); +    //set Ignite-node holder to 'null' because static holders are shared between different tests +    final Field field = IgniteInstanceInitializerSpecificCommunication.class.getDeclaredField("instance"); +    field.setAccessible(true); +    field.set(null, null); +                }    /** diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java index 07ef4968..79d062ae 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java @@ -22,6 +22,7 @@ import org.junit.runners.BlockJUnit4ClassRunner;  import at.asitplus.eidas.specific.connector.SpringBootApplicationInitializer;  import at.gv.egiz.eaaf.core.impl.logging.DummyStatusMessager;  import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; +import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication;  @RunWith(BlockJUnit4ClassRunner.class)  public class MainClassWebAppModeTest { @@ -68,6 +69,12 @@ public class MainClassWebAppModeTest {      System.clearProperty("eidas.ms.configuration");      SpringBootApplicationInitializer.exit(); +     +     +    //set Ignite-node holder to 'null' because static holders are shared between different tests +    final Field field1 = IgniteInstanceInitializerSpecificCommunication.class.getDeclaredField("instance"); +    field1.setAccessible(true); +    field1.set(null, null);    } diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthnRequestValidatorTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthnRequestValidatorTest.java index 9aafb4b6..c57515a0 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthnRequestValidatorTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthnRequestValidatorTest.java @@ -214,6 +214,11 @@ public class AuthnRequestValidatorTest {      Assert.assertEquals("wrong transactionId", "transId_11223344556677aabbcc",           pendingReq.getUniqueTransactionIdentifier()); +    +    Assert.assertEquals("wrong binding pubkey", "binding_pubKey_1144225247125dsfasfasdf",  +        pendingReq.getRawData(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME, String.class)); +     +        } diff --git a/connector/src/test/resources/data/pvp2_authn_3.xml b/connector/src/test/resources/data/pvp2_authn_3.xml index 35e49b0f..5352c441 100644 --- a/connector/src/test/resources/data/pvp2_authn_3.xml +++ b/connector/src/test/resources/data/pvp2_authn_3.xml @@ -31,6 +31,9 @@        <eid:RequestedAttribute FriendlyName="transactionId" Name="urn:eidgvat:attributes.transactionId" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true">          <eid:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">transId_11223344556677aabbcc</eid:AttributeValue>        </eid:RequestedAttribute> +      <eid:RequestedAttribute FriendlyName="Binding-PublicKey" Name="urn:eidgvat:attributes.binding.pubkey" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"> +        <eid:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">binding_pubKey_1144225247125dsfasfasdf</eid:AttributeValue> +      </eid:RequestedAttribute>      </eid:RequestedAttributes>    </saml2p:Extensions>    <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/> diff --git a/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/MsEidasNodeConstants.java b/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/MsEidasNodeConstants.java index 133f104d..027d0832 100644 --- a/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/MsEidasNodeConstants.java +++ b/connector_lib/src/main/java/at/asitplus/eidas/specific/connector/MsEidasNodeConstants.java @@ -169,6 +169,9 @@ public class MsEidasNodeConstants {    public static final List<String> COUNTRY_SELECTION_PARAM_WHITELIST =        Arrays.asList(REQ_PARAM_SELECTED_COUNTRY, REQ_PARAM_SELECTED_ENVIRONMENT); +   +  public static final String EID_BINDING_PUBLIC_KEY_NAME = "urn:eidgvat:attributes.binding.pubkey"; +      private MsEidasNodeConstants() {      //hidden Constructor for class with static values only.    } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java index 234d52dd..a2af4342 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/AuthBlockSigningService.java @@ -18,6 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Service;  import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude;  import com.fasterxml.jackson.annotation.JsonProperty;  import com.fasterxml.jackson.core.JsonProcessingException;  import com.fasterxml.jackson.databind.ObjectMapper; @@ -81,6 +82,14 @@ public class AuthBlockSigningService {      authBlock.setTimestamp(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));      authBlock.setUniqueId(pendingReq.getRawData(MsEidasNodeConstants.DATA_REQUESTERID, String.class));       authBlock.setPiiTransactionId(pendingReq.getUniquePiiTransactionIdentifier()); +     +    //set Binding PublicKey if available +    Object bindingPubKey = pendingReq.getRawData(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME); +    if (bindingPubKey instanceof String) { +      authBlock.setBindingPublicKey((String) bindingPubKey); +       +    } +          String jwsPayload = mapper.writeValueAsString(authBlock);      log.debug("Building and sign authBlock with data: {}", jwsPayload); @@ -172,6 +181,7 @@ public class AuthBlockSigningService {     *     */    @Data +  @JsonInclude(JsonInclude.Include.NON_NULL)    private static class EidasAuchBlock {      @JsonProperty("challenge") @@ -189,6 +199,8 @@ public class AuthBlockSigningService {      @JsonProperty("piiTransactionId")      private String piiTransactionId; +    @JsonProperty("bindingPublicKey") +    private String bindingPublicKey;    } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java index 2e6790c5..0621081a 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java @@ -221,6 +221,7 @@ public class CreateIdentityLinkTaskEidNewTest {      Assert.assertEquals("appId", randomTestSp, authBlockJson.get("appId").asText());          Assert.assertFalse("'challenge' is null", authBlockJson.get("challenge").asText().isEmpty());      Assert.assertFalse("'timestamp' is null", authBlockJson.get("timestamp").asText().isEmpty()); +    Assert.assertFalse("binding pubKey", authBlockJson.has("bindingPublicKey"));      // check vsz request @@ -312,9 +313,11 @@ public class CreateIdentityLinkTaskEidNewTest {      signContentEntry.setValue(RandomStringUtils.randomAlphanumeric(10));      signContentResp.getOut().add(signContentEntry);      when(szrMock, "signContent", any(), any(), any()).thenReturn(signContentResp); - +          String randomTestSp = RandomStringUtils.randomAlphabetic(10); +    String bindingPubKey = RandomStringUtils.randomAlphabetic(10);      pendingReq.setRawDataToTransaction(MsEidasNodeConstants.DATA_REQUESTERID, randomTestSp); +    pendingReq.setRawDataToTransaction(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME, bindingPubKey);      //perform test      task.execute(pendingReq, executionContext); @@ -329,8 +332,28 @@ public class CreateIdentityLinkTaskEidNewTest {      Assert.assertNotNull("AuthProcessData", authProcessData);      Assert.assertNotNull("eidasBind", authProcessData.getGenericDataFromSession(Constants.EIDAS_BIND, String.class)); +    // check authblock signature      String authBlock = authProcessData.getGenericDataFromSession(Constants.SZR_AUTHBLOCK, String.class);      Assert.assertNotNull("AuthBlock", authBlock); +    final AlgorithmConstraints constraints = new AlgorithmConstraints(ConstraintType.PERMIT, +        BINDING_AUTH_ALGORITHM_WHITELIST_SIGNING.toArray(new String[BINDING_AUTH_ALGORITHM_WHITELIST_SIGNING.size()])); +    Pair<KeyStore, Provider> keyStore = getKeyStore(); +    X509Certificate[] trustedCerts = EaafKeyStoreUtils +        .getPrivateKeyAndCertificates(keyStore.getFirst(), ALIAS, PW.toCharArray(), true, "junit").getSecond(); +    JwsResult result = JoseUtils.validateSignature(authBlock, Arrays.asList(trustedCerts), constraints); +    Assert.assertTrue("AuthBlock not valid", result.isValid());         +    JsonNode authBlockJson = mapper.readTree(result.getPayLoad());     +    Assert.assertNotNull("deserialized AuthBlock", authBlockJson); +     +    Assert.assertNotNull("no piiTransactionId in pendingRequesdt",  +        storedPendingReq.getUniquePiiTransactionIdentifier()); +    Assert.assertEquals("piiTransactionId", storedPendingReq.getUniquePiiTransactionIdentifier(),  +        authBlockJson.get("piiTransactionId").asText()); +    Assert.assertEquals("appId", randomTestSp, authBlockJson.get("appId").asText());     +    Assert.assertFalse("'challenge' is null", authBlockJson.get("challenge").asText().isEmpty()); +    Assert.assertFalse("'timestamp' is null", authBlockJson.get("timestamp").asText().isEmpty()); +    Assert.assertTrue("binding pubKey", authBlockJson.has("bindingPublicKey")); +    Assert.assertEquals("binding PubKey", bindingPubKey, authBlockJson.get("bindingPublicKey").asText());      Assert.assertTrue("EID process", authProcessData.isEidProcess());      Assert.assertTrue("foreigner process", authProcessData.isForeigner()); | 
