/*
* eID Applet Project.
* Copyright (C) 2008-2009 FedICT.
* Copyright (C) 2014 e-Contract.be BVBA.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version
* 3.0 as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, see
* http://www.gnu.org/licenses/.
*/
package be.fedict.eid.applet.shared;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.List;
import be.fedict.eid.applet.shared.annotation.HttpBody;
import be.fedict.eid.applet.shared.annotation.HttpHeader;
import be.fedict.eid.applet.shared.annotation.MessageDiscriminator;
import be.fedict.eid.applet.shared.annotation.NotNull;
import be.fedict.eid.applet.shared.annotation.PostConstruct;
import be.fedict.eid.applet.shared.annotation.ProtocolStateAllowed;
import be.fedict.eid.applet.shared.annotation.ResponsesAllowed;
import be.fedict.eid.applet.shared.protocol.ProtocolState;
/**
* Signature Data transfer object.
*
* @author Frank Cornelis
*
*/
@ResponsesAllowed(FinishedMessage.class)
@ProtocolStateAllowed(ProtocolState.SIGN)
public class SignatureDataMessage extends AbstractProtocolMessage {
@HttpHeader(TYPE_HTTP_HEADER)
@MessageDiscriminator
public static final String TYPE = SignatureDataMessage.class.getSimpleName();
@HttpHeader(HTTP_HEADER_PREFIX + "SignatureValueSize")
@NotNull
public Integer signatureValueSize;
@HttpHeader(HTTP_HEADER_PREFIX + "SignCertFileSize")
@NotNull
public Integer signCertFileSize;
@HttpHeader(HTTP_HEADER_PREFIX + "CaCertFileSize")
@NotNull
public Integer caCertFileSize;
@HttpHeader(HTTP_HEADER_PREFIX + "RootCaCertFileSize")
@NotNull
public Integer rootCertFileSize;
@HttpBody
@NotNull
public byte[] body;
public SignatureDataMessage() {
super();
}
public SignatureDataMessage(byte[] signatureValue, List<X509Certificate> signCertChain)
throws IOException, CertificateEncodingException {
this(signatureValue, signCertChain.get(0).getEncoded(), signCertChain.get(1).getEncoded(),
signCertChain.get(2).getEncoded());
}
public SignatureDataMessage(byte[] signatureValue, byte[] signCertFile, byte[] citizenCaCertFile,
byte[] rootCaCertFile) throws IOException, CertificateEncodingException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
this.signatureValueSize = signatureValue.length;
baos.write(signatureValue);
baos.write(signCertFile);
baos.write(citizenCaCertFile);
baos.write(rootCaCertFile);
this.body = baos.toByteArray();
this.signCertFileSize = signCertFile.length;
this.caCertFileSize = citizenCaCertFile.length;
this.rootCertFileSize = rootCaCertFile.length;
}
private byte[] copy(byte[] source, int idx, int count) {
byte[] result = new byte[count];
System.arraycopy(source, idx, result, 0, count);
return result;
}
@PostConstruct
public void postConstruct() {
int idx = 0;
this.signatureValue = copy(this.body, idx, this.signatureValueSize);
idx += this.signatureValueSize;
byte[] signCertFile = copy(this.body, idx, this.signCertFileSize);
idx += this.signCertFileSize;
X509Certificate signCert = getCertificate(signCertFile);
byte[] citizenCaCertFile = copy(this.body, idx, this.caCertFileSize);
idx += this.caCertFileSize;
X509Certificate citizenCaCert = getCertificate(citizenCaCertFile);
byte[] rootCaCertFile = copy(this.body, idx, this.rootCertFileSize);
idx += this.rootCertFileSize;
X509Certificate rootCaCert = getCertificate(rootCaCertFile);
this.certificateChain = new LinkedList<X509Certificate>();
this.certificateChain.add(signCert);
this.certificateChain.add(citizenCaCert);
this.certificateChain.add(rootCaCert);
}
private X509Certificate getCertificate(byte[] certData) {
CertificateFactory certificateFactory;
try {
certificateFactory = CertificateFactory.getInstance("X.509");
} catch (CertificateException e) {
throw new RuntimeException("cert factory error: " + e.getMessage(), e);
}
try {
X509Certificate certificate = (X509Certificate) certificateFactory
.generateCertificate(new ByteArrayInputStream(certData));
return certificate;
} catch (CertificateException e) {
/*
* Can happen in case of missing certificates. Missing certificates
* are represented by means of 1300 null bytes.
*/
return null;
}
}
public byte[] signatureValue;
public List<X509Certificate> certificateChain;
}