/*
* 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.signature.injector;
import org.apache.commons.codec.binary.Base64;
import ru.codeinside.gws.api.Signature;
import sun.security.util.DerOutputStream;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@XmlRootElement(name = "Signature", namespace = XMLDSign.XMLNS)
@XmlAccessorType(XmlAccessType.FIELD)
public class XMLDSign {
public static final String XMLNS = "http://www.w3.org/2000/09/xmldsig#";
public static final String DIGEST_METHOD = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
public static final String SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
public static final String CANONICALIZATION_METHOD = "http://www.w3.org/2001/10/xml-exc-c14n#";
public static final String ENVELOPED_SIGNATURE = "http://www.w3.org/2000/09/xmldsig#enveloped-signature";
@XmlElement(name = "SignedInfo", namespace = XMLDSign.XMLNS)
private SignedInfo signedInfo;
@XmlElement(name = "SignatureValue", namespace = XMLNS)
private String signatureValue;
@XmlElement(name = "KeyInfo", namespace = XMLNS)
private KeyInfo keyInfo;
private byte[] getSignatureValue() {
return Base64.decodeBase64(signatureValue);
}
private void setSignatureValue(byte[] signatureValue) {
this.signatureValue = Base64.encodeBase64String(signatureValue);
}
public XMLDSign() {
}
public XMLDSign(Signature signature, String id) {
signedInfo = new SignedInfo(signature.getDigest(), id);
setSignatureValue(signature.sign);
if (signature.certificate != null) {
keyInfo = new KeyInfo();
keyInfo.x509Data.setCertificate(signature.certificate);
}
}
public void setEnveloped(boolean enveloped) {
if (enveloped) {
signedInfo.addEnvelopedTransform();
} else {
signedInfo.removeEnvelopedTransform();
}
}
// public XmlSignature getXmlSignature() {
// if (!SIGNATURE_METHOD.equals(signedInfo.signatureMethod.algorithm)) {
// throw new RuntimeException("Unexpected signature method: " + signedInfo.signatureMethod.algorithm);
// }
// if (!DIGEST_METHOD.equals(signedInfo.reference.digestMethod.algorithm)) {
// throw new RuntimeException("Unexpected digest method: " + signedInfo.reference.digestMethod.algorithm);
// }
// XmlSignature xmlSignature = new XmlSignature();
// xmlSignature.elementReference = signedInfo.reference.uri;
// xmlSignature.certificate = keyInfo.x509Data.getCertificate();
// xmlSignature.digest = signedInfo.reference.getDigestValue();
// xmlSignature.signature = getSignatureValue();
// return xmlSignature;
// }
/** INNER CLASSES **/
static class KeyInfo {
@XmlElement(name = "X509Data", namespace = XMLNS)
public X509Data x509Data = new X509Data();
}
@XmlAccessorType(XmlAccessType.FIELD)
static class X509Data {
@XmlElement(name = "X509Certificate", namespace = XMLNS)
private String x509Certificate = "";
@XmlElement(name = "X509SubjectName", namespace = XMLNS)
private String x509SubjectName = null;
public void setSubjectName(String subjectName) {
this.x509SubjectName = subjectName;
}
public void setCertificate(X509Certificate certificate) {
DerOutputStream derEncoder;
try {
derEncoder = new DerOutputStream();
derEncoder.write(certificate.getEncoded());
} catch (CertificateEncodingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
this.x509Certificate = Base64.encodeBase64String(derEncoder.toByteArray());
}
public X509Certificate getCertificate() {
try {
byte[] derBytes = Base64.decodeBase64(x509Certificate);
ByteArrayInputStream is = new ByteArrayInputStream(derBytes);
return (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(is);
} catch (CertificateException e) {
throw new RuntimeException(e);
}
}
}
}