/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright (c) 2013, MPL CodeInside http://codeinside.ru
*/
package ru.codeinside.gws.crypto.cryptopro;
import com.sun.org.apache.xpath.internal.XPathAPI;
import junit.framework.Assert;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.utils.Constants;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.apache.xml.security.signature.XMLSignature;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
public class DigestXmlTest {
@Test
public void testVerifySign() throws Exception {
//org.apache.xml.security.Init.init();
CryptoProvider.loadCertificate();
//Assert.assertEquals(XML_FOR_CHECK_SIGN,XML_FOR_CHECK_SIGNED_OUR_CERT );
Assert.assertTrue(signDocVer(R.getTextResource("gmp/reference.xml")));
}
public static boolean signDocVer(String signDoc) throws Exception {
// инициализация объекта чтения XML-документа
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// установка флага, определяющего игнорирование пробелов в содержимом элементов при обработке XML-документа
dbf.setIgnoringElementContentWhitespace(true);
// установка флага, определяющего преобразование узлов CDATA в текстовые узлы при обработке XML-документа
dbf.setCoalescing(true);
// установка флага, определяющего поддержку пространств имен при обработке XML-документа
dbf.setNamespaceAware(true);
// загрузка содержимого подписываемого документа на основе установленных флагами правил
final DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
/* Загружаем подписанный XML-документ из строки */
InputSource is = new InputSource(new StringReader(signDoc));
final Document doc = documentBuilder.parse(is);
/* Чтение узла подписи <ds:Signature> из XML-документа */
// чтение из загруженного документа содержимого пространства имени Signature
final Element nscontext = doc.createElementNS(null, "namespaceContext");
nscontext.setAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + "ds".trim(), Constants.SignatureSpecNS);
// выбор из прочитанного содержимого пространства имени узла подписи <ds:Signature>
final Element sigElement = (Element) XPathAPI
.selectSingleNode(doc, "//ds:Signature[1]", nscontext);
/* Проверка подписи XML-документа на основе информации об открытом ключе, хранящейся в
XML-документе */
// инициализация объекта проверки подписи
final XMLSignature signature = new XMLSignature(sigElement, "");
// чтение узла <ds:KeyInfo> информации об открытом ключе
final KeyInfo ki = signature.getKeyInfo();
// чтение сертификата их узла информации об открытом ключе
final X509Certificate certKey = ki.getX509Certificate();
// если сертификат найден, то осуществляется проверка
// подписи на основе сертфиката
if (certKey != null) {
boolean result = signature.checkSignatureValue(certKey);
System.out.println("The XML signature is " +
(result
? "valid (good)" : "invalid (bad)"));
return result;
}
// в противном случае осуществляется проверка на открытом ключе
else {
// чтение открытого ключа из узла информации об открытом ключе
final PublicKey pk = ki.getPublicKey();
// если открытый ключ найден, то на нем осуществляется проверка подписи
if (pk != null) {
boolean result = signature.checkSignatureValue(pk);
System.out.println(
"The XML signature is " + (result
? "valid (good)" : "invalid (bad)"));
return result;
}
// в противном случае проверка не может быть выполнена
else
throw new Exception(
"There are no information about public key. Verification couldn't be implemented");
}
}
}