/**
   * @param caminhoCertificado
   * @param senhaCertificado
   * @paaram senhaCertificado
   * @param caminhoArquivo
   * @return
   * @throws Exception
   */
  public static String assinarDocumento(
      String caminhoCertificado, String senhaCertificado, String caminhoArquivo) throws Exception {

    final KeyStore keyStore = KeyStore.getInstance("PKCS12");
    try (InputStream certificadoStream = new FileInputStream(new File(caminhoCertificado))) {
      keyStore.load(certificadoStream, senhaCertificado.toCharArray());
    }

    final KeyStore.PrivateKeyEntry keyEntry =
        (KeyStore.PrivateKeyEntry)
            keyStore.getEntry(
                keyStore.aliases().nextElement(),
                new KeyStore.PasswordProtection(senhaCertificado.toCharArray()));

    final XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");

    final List<Transform> transforms = new ArrayList<>(2);
    transforms.add(
        signatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null));
    transforms.add(
        signatureFactory.newTransform(C14N_TRANSFORM_METHOD, (TransformParameterSpec) null));

    final KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
    final X509Data x509Data =
        keyInfoFactory.newX509Data(
            Collections.singletonList((X509Certificate) keyEntry.getCertificate()));
    final KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));

    final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);

    final Document document =
        documentBuilderFactory.newDocumentBuilder().parse(new File(caminhoArquivo));

    for (final String elementoAssinavel : ELEMENTOS_ASSINAVEIS) {
      final NodeList elements = document.getElementsByTagName(elementoAssinavel);
      for (int i = 0; i < elements.getLength(); i++) {
        final Element element = (Element) elements.item(i);
        final String id = element.getAttribute("Id");
        element.setIdAttribute("Id", true);

        final Reference reference =
            signatureFactory.newReference(
                "#" + id,
                signatureFactory.newDigestMethod(DigestMethod.SHA1, null),
                transforms,
                null,
                null);
        final SignedInfo signedInfo =
            signatureFactory.newSignedInfo(
                signatureFactory.newCanonicalizationMethod(
                    CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
                signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                Collections.singletonList(reference));

        final XMLSignature signature = signatureFactory.newXMLSignature(signedInfo, keyInfo);
        signature.sign(new DOMSignContext(keyEntry.getPrivateKey(), element.getParentNode()));
      }
    }

    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
      final Transformer transformer = TransformerFactory.newInstance().newTransformer();
      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
      transformer.transform(new DOMSource(document), new StreamResult(outputStream));
      return outputStream.toString();
    }
  }
  private SignatureData getFromXmlDigSigSignature(
      SignatureVerificationRequest signatureVerificationRequest,
      SignatureVerificationResponse response)
      throws ParserConfigurationException, SAXException, IOException, MarshalException,
          SignatureException {
    String signature = new String(Base64.decode(signatureVerificationRequest.getSignature()));

    InputStream is = new ByteArrayInputStream(signature.getBytes());

    Document document = createDocument(is, true);

    XMLSignature xmlSignature =
        XMLSignatureFactory.getInstance().unmarshalXMLSignature(new DOMStructure(document));

    List contentList = xmlSignature.getKeyInfo().getContent();

    for (Object content : contentList) {
      if (content instanceof X509Data) {
        List certificateList = ((X509Data) content).getContent();
        for (Object certificateObject : certificateList) {
          if (certificateObject instanceof X509Certificate) {
            X509Certificate cert = (X509Certificate) certificateObject;
            CertificateInfo ci = new CertificateInfo();
            ci.setSubjectDn(cert.getSubjectDN().getName());
            ci.setValidTo(simpleDateFormat.format(cert.getNotAfter()));
            response.getCertificateInfos().getCertificateInfo().add(ci);
          }
        }
      }
    }

    return createSignatureDataFromXmlDigSig(signature);
  }
  /**
   * @param context JAXBFilterProcessingContext
   * @return errorCode
   * @throws XWSSecurityException
   */
  public static int sign(JAXBFilterProcessingContext context) throws XWSSecurityException {
    try {
      SignaturePolicy signaturePolicy = (SignaturePolicy) context.getSecurityPolicy();
      ((NamespaceContextEx) context.getNamespaceContext()).addSignatureNS();
      WSSPolicy keyBinding = (WSSPolicy) signaturePolicy.getKeyBinding();
      if (logger.isLoggable(Level.FINEST)) {
        logger.log(Level.FINEST, "KeyBinding is " + keyBinding);
      }

      Key signingKey = null;

      SignatureElementFactory signFactory = new SignatureElementFactory();

      KeyInfo keyInfo = null;
      SecurityHeader securityHeader = context.getSecurityHeader();

      // Get the Signing key and KeyInfo from TokenProcessor
      TokenProcessor tokenProcessor = new TokenProcessor(signaturePolicy, context);
      BuilderResult builderResult = tokenProcessor.process();
      signingKey = builderResult.getDataProtectionKey();
      keyInfo = builderResult.getKeyInfo();

      if (keyInfo != null || !keyBinding.isOptional()) {
        SignedInfo signedInfo = signFactory.constructSignedInfo(context);
        JAXBSignContext signContext = new JAXBSignContext(signingKey);
        signContext.setURIDereferencer(DSigResolver.getInstance());
        XMLSignature signature =
            signFactory.constructSignature(signedInfo, keyInfo, signaturePolicy.getUUID());
        signContext.put(MessageConstants.WSS_PROCESSING_CONTEXT, context);
        NamespaceAndPrefixMapper npMapper =
            new NamespaceAndPrefixMapper(
                context.getNamespaceContext(), context.getDisableIncPrefix());
        signContext.put(NamespaceAndPrefixMapper.NS_PREFIX_MAPPER, npMapper);
        signContext.putNamespacePrefix(MessageConstants.DSIG_NS, MessageConstants.DSIG_PREFIX);
        signature.sign(signContext);

        JAXBSignatureHeaderElement jaxBSign =
            new JAXBSignatureHeaderElement(
                (com.sun.xml.ws.security.opt.crypto.dsig.Signature) signature,
                context.getSOAPVersion());
        securityHeader.add(jaxBSign);

        // For SignatureConfirmation
        List scList = (ArrayList) context.getExtraneousProperty("SignatureConfirmation");
        if (scList != null) {
          scList.add(Base64.encode(signature.getSignatureValue().getValue()));
        }
      }
      // End SignatureConfirmation specific code

    } catch (XWSSecurityException xe) {
      logger.log(Level.SEVERE, LogStringsMessages.WSS_1701_SIGN_FAILED(), xe);
      throw xe;
    } catch (Exception ex) {
      logger.log(Level.SEVERE, LogStringsMessages.WSS_1701_SIGN_FAILED(), ex);
      throw new XWSSecurityException(ex);
    }
    return 0;
  }
  /**
   * Signs a SoapMessage with the holder-of-key configuration provided on class creation. This
   * method changes the SoapMessage.
   *
   * @param message cannot be null
   * @return The signed SoapMessage
   * @throws ParserException
   * @throws SignatureException
   */
  @Override
  public final SoapMessage sign(SoapMessage message) throws ParserException, SignatureException {

    assert message != null;

    Provider securityProvider = holderOfKeyConfig.getSecurityProvider();
    XMLSignatureFactory xmlSigFactory =
        (securityProvider != null)
            ? XMLSignatureFactory.getInstance("DOM", securityProvider)
            : XMLSignatureFactory.getInstance();

    try {
      String bodyUuid = createSoapBodyUuid(message);
      CanonicalizationMethod canonicalizationMethod =
          xmlSigFactory.newCanonicalizationMethod(
              CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null);
      SignatureMethod signatureMethod = getSignatureMethod(xmlSigFactory);
      ArrayList<String> refList = new ArrayList<String>();
      refList.add(bodyUuid);
      refList.add(createTimestampUuid(message));
      List<Reference> references = createSignatureReferences(xmlSigFactory, refList);
      SignedInfo signedInfo =
          xmlSigFactory.newSignedInfo(canonicalizationMethod, signatureMethod, references);

      KeyInfoFactory kif = KeyInfoFactory.getInstance();
      KeyInfo ki =
          kif.newKeyInfo(
              Collections.singletonList(new DOMStructure(createKeyInfoContent(message))));

      XMLSignature signature =
          xmlSigFactory.newXMLSignature(signedInfo, ki, null, addUseKeySignatureId(message), null);

      DOMSignContext dsc =
          new DOMSignContext(
              holderOfKeyConfig.getPrivateKey(), message.getHeader().getFirstChild());
      dsc.putNamespacePrefix(XMLSignature.XMLNS, DIGITAL_SIGNATURE_NAMESPACE_PREFIX);

      signature.sign(dsc);

      log.debug("Message with SOAPBody id: " + bodyUuid + " is signed.");
    } catch (NoSuchAlgorithmException e) {
      log.debug(CREATING_SIGNATURE_ERR_MSG);
      throw new SignatureException(CREATING_SIGNATURE_ERR_MSG, e);
    } catch (InvalidAlgorithmParameterException e) {
      log.debug(CREATING_SIGNATURE_ERR_MSG);
      throw new SignatureException(CREATING_SIGNATURE_ERR_MSG, e);
    } catch (MarshalException e) {
      log.debug(CREATING_SIGNATURE_ERR_MSG);
      throw new SignatureException(CREATING_SIGNATURE_ERR_MSG, e);
    } catch (XMLSignatureException e) {
      log.debug(CREATING_SIGNATURE_ERR_MSG);
      throw new SignatureException(CREATING_SIGNATURE_ERR_MSG, e);
    }

    return message;
  }
  /**
   * Recupera los signedInfo de una firma XML, excluyendo los de las firmas indicadas a
   * trav&eacute;s de su Id.
   *
   * @param xmlSign XML del que se
   * @param pk Clave publicada usada en las firmas de las que se desea obtener los signedInfo.
   * @param excludedIds Identificadores de las firmas excluidas.
   * @return Listado de signedInfos.
   * @throws SAXException Si hay problemas durante el an&aacute;lisis XML.
   * @throws IOException Si hay problemas en el tratamiento de datos.
   * @throws ParserConfigurationException Si hay problemas con el analizador por defecto para XML.
   * @throws MarshalException Si hay problemas con el empaquetado XML.
   * @throws XMLSignatureException Si hay problemas en la propia firma XMLDSig.
   * @throws XmlPreSignException Cuando no se ha encontrado ning&uacute;n signedInfo que devolver.
   */
  private static List<byte[]> getSignedInfos(
      final byte[] xmlSign, final PublicKey pk, final List<String> excludedIds)
      throws SAXException, IOException, ParserConfigurationException, MarshalException,
          XMLSignatureException, XmlPreSignException {
    final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);

    final NodeList signatureNodeList =
        dbf.newDocumentBuilder()
            .parse(new ByteArrayInputStream(xmlSign))
            .getElementsByTagNameNS(XMLSignature.XMLNS, AOXAdESSigner.SIGNATURE_TAG);
    if (signatureNodeList.getLength() == 0) {
      throw new IllegalArgumentException("Se ha proporcionado un XML sin firmas"); // $NON-NLS-1$
    }

    // Recogemos el signedInfo de cada firma cuyo identificador no este en la lista de excluidos
    // (excludedIds)
    final List<byte[]> signedInfos = new ArrayList<byte[]>();
    for (int i = 0; i < signatureNodeList.getLength(); i++) {

      final Node currentNode = signatureNodeList.item(i);

      // Saltamos las firmas sin identificador
      if (currentNode.getAttributes() == null
          || currentNode.getAttributes().getNamedItem(XML_NODE_ID) == null) {
        Logger.getLogger("es.gob.afirma")
            .warning(
                "El documento contiene firmas sin identificador reconocido"); //$NON-NLS-1$//$NON-NLS-2$
        continue;
      }

      // Saltamos las firmas excluidas (las que estaban antes)
      final String id = currentNode.getAttributes().getNamedItem(XML_NODE_ID).getNodeValue();
      if (excludedIds != null && excludedIds.contains(id)) {
        continue;
      }

      // Agregamos el signed indo de la firma al listado
      final XMLValidateContext valContext =
          new DOMValidateContext(new SimpleKeySelector(pk), currentNode);
      valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE); // $NON-NLS-1$
      final XMLSignature signature = Utils.getDOMFactory().unmarshalXMLSignature(valContext);
      signature.validate(valContext);
      signedInfos.add(
          AOUtil.getDataFromInputStream(signature.getSignedInfo().getCanonicalizedData()));
    }

    if (signedInfos.isEmpty()) {
      throw new XmlPreSignException(
          "Se ha creado un nodo firma, pero no se ha encontrado en el postproceso"); //$NON-NLS-1$
    }

    return signedInfos;
  }
  /**
   * Validate a signed document with the given public key
   *
   * @param signedDoc
   * @param publicKey
   * @return
   * @throws MarshalException
   * @throws XMLSignatureException
   */
  @SuppressWarnings("unchecked")
  public static boolean validate(Document signedDoc, Key publicKey)
      throws MarshalException, XMLSignatureException {
    if (signedDoc == null) throw logger.nullArgumentError("Signed Document");

    propagateIDAttributeSetup(signedDoc.getDocumentElement(), signedDoc.getDocumentElement());

    NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");

    if (nl == null || nl.getLength() == 0) {
      throw logger.nullValueError("Cannot find Signature element");
    }

    if (publicKey == null) throw logger.nullValueError("Public Key");

    for (int i = 0; i < nl.getLength(); i++) {
      DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(i));
      XMLSignature signature = fac.unmarshalXMLSignature(valContext);

      boolean coreValidity = signature.validate(valContext);

      if (!coreValidity) {
        if (logger.isTraceEnabled()) {
          boolean sv = signature.getSignatureValue().validate(valContext);
          logger.trace("Signature validation status: " + sv);

          List<Reference> references = signature.getSignedInfo().getReferences();
          for (Reference ref : references) {
            logger.trace(
                "[Ref id="
                    + ref.getId()
                    + ":uri="
                    + ref.getURI()
                    + "]validity status:"
                    + ref.validate(valContext));
          }
        }

        return false;
      }
    }

    return true;
  }
  private static void signImpl(
      DOMSignContext dsc,
      String digestMethod,
      String signatureMethod,
      String referenceURI,
      PublicKey publicKey,
      X509Certificate x509Certificate)
      throws GeneralSecurityException, MarshalException, XMLSignatureException {
    dsc.setDefaultNamespacePrefix("dsig");

    DigestMethod digestMethodObj = fac.newDigestMethod(digestMethod, null);
    Transform transform1 = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
    Transform transform2 =
        fac.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null);

    List<Transform> transformList = new ArrayList<Transform>();
    transformList.add(transform1);
    transformList.add(transform2);

    Reference ref = fac.newReference(referenceURI, digestMethodObj, transformList, null, null);

    CanonicalizationMethod canonicalizationMethod =
        fac.newCanonicalizationMethod(canonicalizationMethodType, (C14NMethodParameterSpec) null);

    List<Reference> referenceList = Collections.singletonList(ref);
    SignatureMethod signatureMethodObj = fac.newSignatureMethod(signatureMethod, null);
    SignedInfo si = fac.newSignedInfo(canonicalizationMethod, signatureMethodObj, referenceList);

    KeyInfo ki = null;
    if (includeKeyInfoInSignature) {
      ki = createKeyInfo(publicKey, x509Certificate);
    }
    XMLSignature signature = fac.newXMLSignature(si, ki);

    signature.sign(dsc);
  }
  /**
   * @param chnlId
   * @param xmlStr
   * @param chnlStr
   * @return
   */
  public String processXMLForChnls(String chnlId, String xmlStr, final String chnlStr) {
    if ("106".equals(chnlId) || "102".equals(chnlId)) {
      try {
        xmlStr = URLEncoder.encode(xmlStr.trim(), "UTF-8");
      } catch (UnsupportedEncodingException e) {
      }
      xmlStr = "xml=".concat(xmlStr);

    } else if ("103".equals(chnlId) && !"Route1_CONT".equals(chnlStr)) {

      xmlStr =
          "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
              + "<soap:Header>"
              + "<SOAP-SEC:Signature xmlns:SOAP-SEC=\"http://schemas.xmlsoap.org/soap/security/2000-12\">"
              + "</SOAP-SEC:Signature>"
              + "</soap:Header>".concat(xmlStr).concat("</soap:Envelope>");
      try {

        // Create a DOM XMLSignatureFactory that will be used to
        // generate the enveloped signature.
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
        Reference ref =
            fac.newReference(
                "#Body",
                fac.newDigestMethod(DigestMethod.SHA1, null),
                Collections.singletonList(
                    fac.newTransform(
                        "http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null)),
                null,
                null);

        // Create the SignedInfo.
        SignedInfo si =
            fac.newSignedInfo(
                fac.newCanonicalizationMethod(
                    CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null),
                fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                Collections.singletonList(ref));

        // Load the KeyStore and get the signing key and
        // certificate.
        KeyStore ks = KeyStore.getInstance("JKS");

        String certFileNm = "";
        // commonConfigHelper.getConfigMap().get(
        // "ROUTE1_CERTIFICATE_JSK");
        String pwd = ""; // commonConfigHelper.getConfigMap().get(
        // "ROUTE1_CERTIFICATE_PASSWORD");
        String aliasNm = ""; // commonConfigHelper.getConfigMap().get(
        // "ROUTE1_CERTIFICATE_ALIAS");
        ks.load(new FileInputStream(certFileNm), pwd.toCharArray());
        KeyStore.PrivateKeyEntry keyEntry =
            (KeyStore.PrivateKeyEntry)
                ks.getEntry(aliasNm, new KeyStore.PasswordProtection(pwd.toCharArray()));
        X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

        // Create the KeyInfo containing the X509Data.
        KeyInfoFactory kif = fac.getKeyInfoFactory();
        List x509Content = new ArrayList();
        // x509Content.add(cert.getSubjectX500Principal().getName());
        x509Content.add(cert.getIssuerX500Principal().getName());
        X509Data xd = kif.newX509Data(x509Content);
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

        // Instantiate the document to be signed.
        // Document doc = xmlUtil.getDocumentFromString(xmlStr);
        Document doc = null;

        // Create a DOMSignContext and specify the RSA PrivateKey
        // and
        // location of the resulting XMLSignature's parent element.
        DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());

        // Create the XMLSignature, but don't sign it yet.
        XMLSignature signature = fac.newXMLSignature(si, ki);

        // Marshal, generate, and sign the enveloped signature.
        signature.sign(dsc);

        // Output the resulting document.

        xmlStr = xmlUtil.convertXMLDocToString(doc);

      } catch (Exception e) {
      }
    }
    return xmlStr;
  }
  @Test
  public void testXmlSignature() throws Exception {

    String providerName =
        System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");

    XMLSignatureFactory factory =
        XMLSignatureFactory.getInstance(
            "DOM", (Provider) Class.forName(providerName).newInstance());
    DigestMethod digestMethod = factory.newDigestMethod(DigestMethod.SHA1, null);
    Transform transform = factory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
    Reference reference =
        factory.newReference("", digestMethod, Collections.singletonList(transform), null, null);
    CanonicalizationMethod canonicalizationMethod =
        factory.newCanonicalizationMethod(
            CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, (C14NMethodParameterSpec) null);
    SignatureMethod signatureMethod = factory.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
    SignedInfo signedInfo =
        factory.newSignedInfo(
            canonicalizationMethod, signatureMethod, Collections.singletonList(reference));

    KeyStore ks = KeyStore.getInstance("JKS");
    InputStream fis = XMLSigSpike.class.getClassLoader().getResourceAsStream("dev.jks");
    ks.load(fis, "devjks".toCharArray());
    fis.close();

    PrivateKey prv = (PrivateKey) ks.getKey("vgr-pdl", "devjks".toCharArray());
    final Certificate cert = ks.getCertificate("vgr-pdl");
    final Certificate cacert = ks.getCertificate("vgr-ca");

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc =
        dbf.newDocumentBuilder()
            .parse(XMLSigSpike.class.getClassLoader().getResourceAsStream("bfr.xml"));

    final X509Certificate x509Cert = (X509Certificate) cert;
    List<X509Certificate> x509 = Arrays.asList(x509Cert);

    KeyInfoFactory keyInfoFactory = factory.getKeyInfoFactory();
    X509Data x509Data = keyInfoFactory.newX509Data(x509);
    List items = new ArrayList();

    items.add(x509Data);
    // items.add(pub);
    KeyInfo keyInfo = keyInfoFactory.newKeyInfo(items);

    DOMSignContext dsc = new DOMSignContext(prv, doc.getDocumentElement());

    XMLSignature signature = factory.newXMLSignature(signedInfo, keyInfo);
    signature.sign(dsc);

    FileOutputStream fos = new FileOutputStream("mySignedFile.xml");
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.transform(new DOMSource(doc), new StreamResult(fos));
    fos.close();

    Document signedDoc = dbf.newDocumentBuilder().parse(new FileInputStream("mySignedFile.xml"));

    // Find Signature element.
    NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
      throw new Exception("Cannot find Signature element");
    }

    KeySelector selector =
        new KeySelector() {
          @Override
          public KeySelectorResult select(
              final KeyInfo keyInfo,
              final Purpose purpose,
              final AlgorithmMethod algorithmMethod,
              final XMLCryptoContext xmlCryptoContext)
              throws KeySelectorException {
            return new KeySelectorResult() {
              @Override
              public Key getKey() {
                List<X509Data> dataList = keyInfo.getContent();
                List<X509Certificate> certList = dataList.get(0).getContent();
                X509Certificate cert = certList.get(0);
                try {
                  x509Cert.verify(cacert.getPublicKey());
                } catch (CertificateException e) {
                  throw new RuntimeException(e);
                } catch (NoSuchAlgorithmException e) {
                  throw new RuntimeException(e);
                } catch (InvalidKeyException e) {
                  throw new RuntimeException(e);
                } catch (NoSuchProviderException e) {
                  throw new RuntimeException(e);
                } catch (SignatureException e) {
                  throw new RuntimeException(e);
                }
                return cert.getPublicKey();
              }
            };
          }
        };

    // Create a DOMValidateContext and specify a KeySelector
    // and document context.
    DOMValidateContext valContext = new DOMValidateContext(selector, nl.item(0));

    // Unmarshal the XMLSignature.
    XMLSignature xmlSignature = factory.unmarshalXMLSignature(valContext);

    // Validate the XMLSignature.
    boolean coreValidity = signature.validate(valContext);

    assertTrue(coreValidity);
  }
Exemple #10
0
  private void validateSignature(SOAPMessage soapMessage) throws Exception {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    SOAPPart soapPart = soapMessage.getSOAPPart();
    Source source = null;
    try {

      source = soapPart.getContent();
    } catch (Exception e) {
    }

    Node root = null;
    Document doc = null;
    DocumentBuilder db = null;
    if (source instanceof DOMSource) {
      root = ((DOMSource) source).getNode();
      if (root instanceof Document) {
        doc = (Document) root;
      }
    } else if (source instanceof SAXSource) {
      InputSource inSource = ((SAXSource) source).getInputSource();
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(true);
      db = dbf.newDocumentBuilder();
      doc = db.parse(inSource);
      root = (Node) doc.getDocumentElement();
    } else { // if (source instanceof JAXMStreamSource){
      StreamSource streamSource = (StreamSource) source;
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(true);
      db = dbf.newDocumentBuilder();
      doc = db.parse(streamSource.getInputStream());
      root = (Node) doc.getDocumentElement();
      root = root.getParentNode();
    }
    /////////////////////////////////////////////
    NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
      throw new Exception("Cannot find Signature element");
      // System.out.println("Cannot find Signature element");
    }

    KeyValueKeySelector kvks = new KeyValueKeySelector();
    DOMValidateContext valContext =
        new DOMValidateContext(kvks, nl.item(0)); // (LoadPublicKey("", "RSA"),nl.item(0));
    XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
    XMLSignature signature = factory.unmarshalXMLSignature(valContext);
    if (signature.validate(valContext)) valid = 1;
    else valid = 0;
    if (DEBUG_) System.out.println("WSupdate:HS: valid=" + valid);
    try {
      md.update(signature.getKeySelectorResult().getKey().getEncoded());
      String PK_WS = getHexString(md.digest());
      if (PK_WS.equals(PK_Hex)) valid = 1;
      else valid = 0;
      if (DEBUG_)
        System.out.println(
            "Signature validation by comparing URL digest PK and empadded PK (1 or 0) " + valid);
      if (DEBUG_) System.out.println("Public Key from SOAP: " + PK_WS);
      md.reset();
      if (DEBUG_) System.out.println("Public Key from DB: " + PK_Hex);
      // md.update(LoadPublicKey("", "RSA").getEncoded());
      // System.out.println("Public Key from File: " + getHexString(md.digest()));
    } catch (Exception e) {
      System.out.print(e);
    }

    //  PublicKey pub = keypair.getPublic();

    /////////////////////////////////////////////
    //		Element envelope = getFirstChildElement(root);
    //        Element header = getFirstChildElement(envelope);
    //		Element sigElement = getFirstChildElement(header);
    //        DOMValidateContext valContext = new DOMValidateContext(LoadPublicKey("","RSA"),
    // sigElement);
    //        valContext.setIdAttributeNS(getNextSiblingElement(header),
    //        "http://schemas.xmlsoap.org/soap/security/2000-12", "id");
    //  if(sig.validate(valContext)) valid=1 ; else valid=0;

    ////////////////////////////////////////////

  }
  /**
   * Cria a assinatura para o objeto informado no construtor.
   *
   * @return Assinatura gerada.
   * @throws SignatureException Caso ocorra algum erro ao gerar a assinatura.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  public SignatureType createSignature() throws SignatureException {
    try {
      final X509Certificate certificate = Configuration.getInstance().getCertificate();

      // Cria a assinatura com a API do Java.
      final XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");

      final List<Transform> transformList = new ArrayList<Transform>();
      transformList.add(factory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null));
      transformList.add(
          factory.newTransform(CanonicalizationMethod.INCLUSIVE, (TransformParameterSpec) null));

      final Reference reference =
          factory.newReference(
              this.referenceUri,
              factory.newDigestMethod(DigestMethod.SHA1, null),
              transformList,
              null,
              null);
      final SignedInfo signedInfo =
          factory.newSignedInfo(
              factory.newCanonicalizationMethod(
                  CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
              factory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
              Collections.singletonList(reference));

      final KeyInfoFactory keyInfoFactory = factory.getKeyInfoFactory();

      final List x509Content = new ArrayList();
      x509Content.add(certificate.getSubjectX500Principal().getName());
      x509Content.add(certificate);

      final X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
      final KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));

      final DOMSignContext domSignContext =
          new DOMSignContext(
              Configuration.getInstance().getPrivateKey(), this.document.getDocumentElement());

      final XMLSignature newXMLSignature = factory.newXMLSignature(signedInfo, keyInfo);
      newXMLSignature.sign(domSignContext);

      // Remove tags nao recomendadas.
      final String[] unnecessaryElements =
          new String[] {
            "X509SubjectName",
            "X509IssuerSerial",
            "X509IssuerName",
            "X509IssuerName",
            "X509SKI",
            "KeyValue",
            "RSAKeyValue",
            "Modulus",
            "Exponent"
          };
      final XPathFactory xpathFactory = XPathFactory.newInstance();

      for (final String elementName : unnecessaryElements) {
        final XPathExpression xpath =
            xpathFactory.newXPath().compile("//*[name()='" + elementName + "']");
        final Node node = (Node) xpath.evaluate(this.document, XPathConstants.NODE);

        if (null != node) {
          node.getParentNode().removeChild(node);
        }
      }

      final XPathExpression xpath = xpathFactory.newXPath().compile("//*[name()='Signature']");
      return JAXB.unmarshal(
          new DOMSource((Node) xpath.evaluate(this.document, XPathConstants.NODE)),
          SignatureType.class);

    } catch (Exception e) {
      throw new SignatureException("Um erro ocorreu ao criar a assinatura.", e);
    }
  }
  @Test
  public void testSignEnvelopingDocumentOffice2010() throws Exception {
    // setup
    EnvelopedSignatureFacet envelopedSignatureFacet = new EnvelopedSignatureFacet();
    KeyInfoSignatureFacet keyInfoSignatureFacet = new KeyInfoSignatureFacet(true, false, false);
    SignaturePolicyService signaturePolicyService =
        new ExplicitSignaturePolicyService(
            "urn:test", "hello world".getBytes(), "description", "http://here.com");
    XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(signaturePolicyService);
    TimeStampService mockTimeStampService = EasyMock.createMock(TimeStampService.class);
    RevocationDataService mockRevocationDataService =
        EasyMock.createMock(RevocationDataService.class);
    XAdESXLSignatureFacet xadesXLSignatureFacet =
        new XAdESXLSignatureFacet(mockTimeStampService, mockRevocationDataService);
    XmlSignatureTestService testedInstance =
        new XmlSignatureTestService(
            envelopedSignatureFacet,
            keyInfoSignatureFacet,
            xadesSignatureFacet,
            new Office2010SignatureFacet(),
            xadesXLSignatureFacet);

    KeyPair keyPair = PkiTestUtils.generateKeyPair();
    DateTime notBefore = new DateTime();
    DateTime notAfter = notBefore.plusYears(1);
    X509Certificate certificate =
        PkiTestUtils.generateCertificate(
            keyPair.getPublic(),
            "CN=Test",
            notBefore,
            notAfter,
            null,
            keyPair.getPrivate(),
            true,
            0,
            null,
            null,
            new KeyUsage(KeyUsage.nonRepudiation));
    List<X509Certificate> certificateChain = new LinkedList<X509Certificate>();
    /*
     * We need at least 2 certificates for the XAdES-C complete certificate
     * refs construction.
     */
    certificateChain.add(certificate);
    certificateChain.add(certificate);

    RevocationData revocationData = new RevocationData();
    final X509CRL crl = PkiTestUtils.generateCrl(certificate, keyPair.getPrivate());
    revocationData.addCRL(crl);
    OCSPResp ocspResp =
        PkiTestUtils.createOcspResp(
            certificate, false, certificate, certificate, keyPair.getPrivate(), "SHA1withRSA");
    revocationData.addOCSP(ocspResp.getEncoded());

    // expectations
    EasyMock.expect(
            mockTimeStampService.timeStamp(
                EasyMock.anyObject(byte[].class), EasyMock.anyObject(RevocationData.class)))
        .andStubAnswer(
            new IAnswer<byte[]>() {
              public byte[] answer() throws Throwable {
                Object[] arguments = EasyMock.getCurrentArguments();
                RevocationData revocationData = (RevocationData) arguments[1];
                revocationData.addCRL(crl);
                return "time-stamp-token".getBytes();
              }
            });
    EasyMock.expect(mockRevocationDataService.getRevocationData(EasyMock.eq(certificateChain)))
        .andStubReturn(revocationData);

    // prepare
    EasyMock.replay(mockTimeStampService, mockRevocationDataService);

    // operate
    DigestInfo digestInfo = testedInstance.preSign(null, certificateChain, null, null, null);

    // verify
    assertNotNull(digestInfo);
    assertEquals("SHA-1", digestInfo.digestAlgo);
    assertNotNull(digestInfo.digestValue);

    TemporaryTestDataStorage temporaryDataStorage =
        (TemporaryTestDataStorage) testedInstance.getTemporaryDataStorage();
    assertNotNull(temporaryDataStorage);
    InputStream tempInputStream = temporaryDataStorage.getTempInputStream();
    assertNotNull(tempInputStream);
    Document tmpDocument = PkiTestUtils.loadDocument(tempInputStream);

    LOG.debug("tmp document: " + PkiTestUtils.toString(tmpDocument));
    Element nsElement = tmpDocument.createElement("ns");
    nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
    nsElement.setAttributeNS(
        Constants.NamespaceSpecNS, "xmlns:xades", "http://uri.etsi.org/01903/v1.3.2#");
    Node digestValueNode = XPathAPI.selectSingleNode(tmpDocument, "//ds:DigestValue", nsElement);
    assertNotNull(digestValueNode);
    String digestValueTextContent = digestValueNode.getTextContent();
    LOG.debug("digest value text content: " + digestValueTextContent);
    assertFalse(digestValueTextContent.isEmpty());

    /*
     * Sign the received XML signature digest value.
     */
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
    byte[] digestInfoValue =
        ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestInfo.digestValue);
    byte[] signatureValue = cipher.doFinal(digestInfoValue);

    /*
     * Operate: postSign
     */
    testedInstance.postSign(signatureValue, certificateChain);

    // verify
    EasyMock.verify(mockTimeStampService, mockRevocationDataService);
    byte[] signedDocumentData = testedInstance.getSignedDocumentData();
    assertNotNull(signedDocumentData);
    Document signedDocument =
        PkiTestUtils.loadDocument(new ByteArrayInputStream(signedDocumentData));
    LOG.debug("signed document: " + PkiTestUtils.toString(signedDocument));

    NodeList signatureNodeList =
        signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    assertEquals(1, signatureNodeList.getLength());
    Element signatureNode = (Element) signatureNodeList.item(0);

    // work-around for Java 7
    Element signedPropertiesElement =
        (Element)
            signatureNode
                .getElementsByTagNameNS(XAdESXLSignatureFacet.XADES_NAMESPACE, "SignedProperties")
                .item(0);
    signedPropertiesElement.setIdAttribute("Id", true);

    DOMValidateContext domValidateContext =
        new DOMValidateContext(
            KeySelector.singletonKeySelector(keyPair.getPublic()), signatureNode);
    XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance();
    XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
    boolean validity = xmlSignature.validate(domValidateContext);
    assertTrue(validity);

    File tmpFile = File.createTempFile("xades-bes-", ".xml");
    FileUtils.writeStringToFile(tmpFile, PkiTestUtils.toString(signedDocument));
    LOG.debug("tmp file: " + tmpFile.getAbsolutePath());

    Node resultNode =
        XPathAPI.selectSingleNode(
            signedDocument,
            "ds:Signature/ds:Object/xades:QualifyingProperties/xades:SignedProperties/xades:SignedSignatureProperties/xades:SigningCertificate/xades:Cert/xades:CertDigest/ds:DigestValue",
            nsElement);
    assertNotNull(resultNode);

    // also test whether the XAdES extension is in line with the XAdES XML
    // Schema.

    // stax-api 1.0.1 prevents us from using
    // "XMLConstants.W3C_XML_SCHEMA_NS_URI"
    Node qualifyingPropertiesNode =
        XPathAPI.selectSingleNode(
            signedDocument, "ds:Signature/ds:Object/xades:QualifyingProperties", nsElement);
    SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
    LSResourceResolver xadesResourceResolver = new XAdESLSResourceResolver();
    factory.setResourceResolver(xadesResourceResolver);
    InputStream schemaInputStream =
        XAdESSignatureFacetTest.class.getResourceAsStream("/XAdESv141.xsd");
    Source schemaSource = new StreamSource(schemaInputStream);
    Schema schema = factory.newSchema(schemaSource);
    Validator validator = schema.newValidator();
    // DOMResult gives some DOMException...
    validator.validate(new DOMSource(qualifyingPropertiesNode));

    StreamSource streamSource = new StreamSource(tmpFile.toURI().toString());
    ByteArrayOutputStream resultOutputStream = new ByteArrayOutputStream();
    StreamResult streamResult = new StreamResult(resultOutputStream);
    // validator.validate(streamSource, streamResult);
    LOG.debug("result: " + resultOutputStream);
  }