/**
   * Validates issuer info
   *
   * @param verifier
   * @return Whether issue validation successful or not.
   * @throws Exception
   */
  protected boolean validateIssuerInfoPolicy(SAMLTokenVerifier verifier, RelyingPartyData data)
      throws RelyingPartyException {
    String issuerName = verifier.getIssuerName();
    String issuerPolicy = data.getIssuerPolicy();

    try {
      if (IdentityConstants.SELF_ISSUED_ISSUER.equals(issuerName)) {
        if (issuerPolicy == null
            || issuerPolicy.equals(TokenVerifierConstants.SELF_ONLY)
            || issuerPolicy.equals(TokenVerifierConstants.SELF_AND_MANGED)) {
          return true;
        } else {
          return false;
        }
      } else if (issuerPolicy.equals(TokenVerifierConstants.SELF_ONLY)) {
        // not a self issued card when self only
        return false;
      } else {
        return true;
      }
    } catch (Exception e) {
      log.error("Error in issuer policy validation", e);
      throw new RelyingPartyException("errorValidatingIssuerPolicy", e);
    }
  }
  /**
   * The control flow is 1) Verify 2) Validate policies 3) Inject parameters into the
   * HttpServletRequest
   *
   * @param request
   * @param xmlToken
   * @param data
   * @throws RelyingPartyException
   */
  public void setInfocardSessionAttributes(
      HttpServletRequest request, String xmlToken, RelyingPartyData data)
      throws RelyingPartyException {

    SAMLTokenVerifier verifier = new SAMLTokenVerifier();
    Element plainTokenElem = verifier.decryptToken(xmlToken, data.getPrivateKey());
    boolean isAllSuccess = false;

    if (verifier.verifyDecryptedToken(plainTokenElem, data)) {
      if (validateIssuerInfoPolicy(verifier, data)) {
        isAllSuccess = true;
      }
    }

    if (isAllSuccess == false) {
      injectDataToRequestOnFailure(verifier, request);
    } else {
      injectDataToRequestOnSuccess(verifier, request);
    }
  }
  /**
   * When the token is valid this method injects valid states message
   *
   * @param verifier
   * @param request
   * @throws RelyingPartyException
   */
  protected void injectDataToRequestOnSuccess(SAMLTokenVerifier verifier, ServletRequest request)
      throws RelyingPartyException {
    String issuerInfo = getIssuerInfoString(verifier);
    Iterator propertyEntry = null;

    if (issuerInfo != null) {
      request.setAttribute(TokenVerifierConstants.ISSUER_INFO, issuerInfo);
    }

    propertyEntry = verifier.getAttributeTable().entrySet().iterator();

    while (propertyEntry.hasNext()) {
      Entry entry = (Entry) propertyEntry.next();
      String key = (String) entry.getKey();
      String value = (String) entry.getValue();
      request.setAttribute(key, value);
    }

    request.setAttribute(
        TokenVerifierConstants.SERVLET_ATTR_STATE, TokenVerifierConstants.STATE_SUCCESS);
  }
  /**
   * @param verifier
   * @return
   * @throws RelyingPartyException
   */
  protected String getIssuerInfoString(SAMLTokenVerifier verifier) throws RelyingPartyException {
    String issuerInfo = null;
    OMFactory factory = null;
    OMNamespace namespace = null;
    Element keyInfo = null;
    OMElement certificates = null;
    OMElement omKeyInfo = null;
    boolean siginingSet = false;
    OMElement certElem = null;
    Iterator<X509Certificate> certIterator = null;

    try {
      factory = OMAbstractFactory.getOMFactory();
      namespace =
          factory.createOMNamespace(TokenVerifierConstants.NS, TokenVerifierConstants.PREFIX);
      keyInfo = verifier.getKeyInfoElement();
      certIterator = verifier.getCertificates().iterator();

      while (certIterator.hasNext()) {
        X509Certificate cert = certIterator.next();
        byte[] encodedCert = cert.getEncoded();
        String base64Encoded = Base64.encode(encodedCert);

        if (certificates == null) {
          certificates = factory.createOMElement(TokenVerifierConstants.LN_CERTIFICATES, namespace);
        }

        certElem = factory.createOMElement(TokenVerifierConstants.LN_CERTIFICATE, namespace);

        if (siginingSet == false) {
          certElem.addAttribute(TokenVerifierConstants.LN_SIGNING_CERT, "true", null);
          siginingSet = true;
        }
        certElem.setText(base64Encoded);
        certificates.addChild(certElem);
      }

      if (keyInfo != null) {
        String value = IdentityUtil.nodeToString(keyInfo);
        XMLStreamReader parser =
            XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(value));
        StAXOMBuilder builder = new StAXOMBuilder(parser);
        omKeyInfo = builder.getDocumentElement();
      }
    } catch (Exception e) {
      log.error("Error while building issuer info", e);
      throw new RelyingPartyException("errorBuildingIssuerInfo");
    }

    if (certificates != null) {
      issuerInfo = certificates.toString();
    }

    if (omKeyInfo != null) {
      if (issuerInfo != null) {
        issuerInfo = issuerInfo + omKeyInfo.toString();
      } else {
        issuerInfo = omKeyInfo.toString();
      }
    }
    return issuerInfo;
  }