/* * eID Applet Project. * Copyright (C) 2008-2009 FedICT. * Copyright (C) 2014-2015 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.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; /** * Authentication Data transfer object. * * @author Frank Cornelis * */ @ResponsesAllowed({ FinishedMessage.class, AuthSignRequestMessage.class }) @ProtocolStateAllowed(ProtocolState.AUTHENTICATE) public class AuthenticationDataMessage extends AbstractProtocolMessage { @HttpHeader(TYPE_HTTP_HEADER) @MessageDiscriminator public static final String TYPE = AuthenticationDataMessage.class.getSimpleName(); @HttpHeader(HTTP_HEADER_PREFIX + "SignatureValueSize") @NotNull public Integer signatureValueSize; @HttpHeader(HTTP_HEADER_PREFIX + "SaltValueSize") @NotNull public Integer saltValueSize; @HttpHeader(HTTP_HEADER_PREFIX + "SessionIdSize") public Integer sessionIdSize; @HttpHeader(HTTP_HEADER_PREFIX + "AuthnCertFileSize") @NotNull public Integer authnCertFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "CaCertFileSize") @NotNull public Integer caCertFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "RootCaCertFileSize") @NotNull public Integer rootCertFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "SignCertFileSize") public Integer signCertFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "IdentityFileSize") public Integer identityFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "AddressFileSize") public Integer addressFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "PhotoFileSize") public Integer photoFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "IdentitySignatureFileSize") public Integer identitySignatureFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "AddressSignatureFileSize") public Integer addressSignatureFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "NationalRegistryCertFileSize") public Integer rrnCertFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "ServerCertFileSize") public Integer serverCertFileSize; @HttpHeader(HTTP_HEADER_PREFIX + "TransactionMessageSignatureSize") public Integer transactionMessageSignatureSize; @HttpBody @NotNull public byte[] body; /** * Default constructor. */ public AuthenticationDataMessage() { super(); } /** * Main constructor. * * @param saltValue * @param sessionId * the optional TLS session identifier. * @param signatureValue * @param authnCertChain * @param serverCertData * the applet also needs to communicate the server SSL * certificate in case of channel binding as the server not * always knows its own identity. * @param transactionMessageSignature * the optional signed transaction message. * @throws IOException * @throws CertificateEncodingException */ public AuthenticationDataMessage(byte[] saltValue, byte[] sessionId, byte[] signatureValue, byte[] authnCertFile, byte[] citCaCertFile, byte[] rootCaCertFile, byte[] signCertFile, byte[] identityData, byte[] addressData, byte[] photoData, byte[] identitySignatureData, byte[] addressSignatureData, byte[] rrnCertData, byte[] serverCertData, byte[] transactionMessageSignature) throws IOException, CertificateEncodingException { this.saltValueSize = saltValue.length; this.signatureValueSize = signatureValue.length; this.authnCertFileSize = authnCertFile.length; this.caCertFileSize = citCaCertFile.length; this.rootCertFileSize = rootCaCertFile.length; ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(saltValue); if (null != sessionId) { this.sessionIdSize = sessionId.length; baos.write(sessionId); } baos.write(signatureValue); baos.write(authnCertFile); baos.write(citCaCertFile); baos.write(rootCaCertFile); if (null != signCertFile) { this.signCertFileSize = signCertFile.length; baos.write(signCertFile); } if (null != identityData) { baos.write(identityData); this.identityFileSize = identityData.length; } if (null != addressData) { baos.write(addressData); this.addressFileSize = addressData.length; } if (null != photoData) { baos.write(photoData); this.photoFileSize = photoData.length; } if (null != identitySignatureData) { baos.write(identitySignatureData); this.identitySignatureFileSize = identitySignatureData.length; } if (null != addressSignatureData) { baos.write(addressSignatureData); this.addressSignatureFileSize = addressSignatureData.length; } if (null != rrnCertData) { baos.write(rrnCertData); this.rrnCertFileSize = rrnCertData.length; } if (null != serverCertData) { baos.write(serverCertData); this.serverCertFileSize = serverCertData.length; } if (null != transactionMessageSignature) { baos.write(transactionMessageSignature); this.transactionMessageSignatureSize = transactionMessageSignature.length; } this.body = baos.toByteArray(); } public AuthenticationDataMessage(byte[] saltValue, byte[] sessionId, byte[] signatureValue, List<X509Certificate> authnCertChain, byte[] signCertFile, byte[] identityData, byte[] addressData, byte[] photoData, byte[] identitySignatureData, byte[] addressSignatureData, byte[] rrnCertData, byte[] serverCertData, byte[] transactionMessageSignature) throws IOException, CertificateEncodingException { this(saltValue, sessionId, signatureValue, authnCertChain.get(0).getEncoded(), authnCertChain.get(1).getEncoded(), authnCertChain.get(2).getEncoded(), signCertFile, identityData, addressData, photoData, identitySignatureData, addressSignatureData, rrnCertData, serverCertData, transactionMessageSignature); } 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; if (0 == this.saltValueSize) { throw new RuntimeException("salt bytes required"); } this.saltValue = copy(this.body, idx, this.saltValueSize); idx += this.saltValueSize; if (null != this.sessionIdSize) { this.sessionId = copy(this.body, idx, this.sessionIdSize); idx += this.sessionIdSize; } this.signatureValue = copy(this.body, idx, this.signatureValueSize); idx += this.signatureValueSize; byte[] authnCertFile = copy(this.body, idx, this.authnCertFileSize); idx += this.authnCertFileSize; this.authnCert = getCertificate(authnCertFile); byte[] citizenCaCertFile = copy(this.body, idx, this.caCertFileSize); idx += this.caCertFileSize; this.citizenCaCert = getCertificate(citizenCaCertFile); byte[] rootCaCertFile = copy(this.body, idx, this.rootCertFileSize); idx += this.rootCertFileSize; this.rootCaCert = getCertificate(rootCaCertFile); if (null != this.signCertFileSize) { byte[] signCertFile = copy(this.body, idx, this.signCertFileSize); idx += this.signCertFileSize; this.signCert = getCertificate(signCertFile); } if (null != this.identityFileSize) { this.identityData = copy(this.body, idx, this.identityFileSize); idx += this.identityFileSize; } if (null != this.addressFileSize) { this.addressData = copy(this.body, idx, this.addressFileSize); idx += this.addressFileSize; } if (null != this.photoFileSize) { this.photoData = copy(this.body, idx, this.photoFileSize); idx += this.photoFileSize; } if (null != this.identitySignatureFileSize) { this.identitySignatureData = copy(this.body, idx, this.identitySignatureFileSize); idx += this.identitySignatureFileSize; } if (null != this.addressSignatureFileSize) { this.addressSignatureData = copy(this.body, idx, this.addressSignatureFileSize); idx += this.addressSignatureFileSize; } if (null != this.rrnCertFileSize) { byte[] rrnCertData = copy(this.body, idx, this.rrnCertFileSize); this.rrnCertificate = getCertificate(rrnCertData); idx += this.rrnCertFileSize; } if (null != this.serverCertFileSize) { byte[] serverCertData = copy(this.body, idx, this.serverCertFileSize); this.encodedServerCertificate = serverCertData; this.serverCertificate = getCertificate(serverCertData); idx += this.serverCertFileSize; } if (null != this.transactionMessageSignatureSize) { this.transactionMessageSignature = copy(this.body, idx, this.transactionMessageSignatureSize); idx += this.transactionMessageSignatureSize; } } 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[] saltValue; public byte[] sessionId; public byte[] signatureValue; public X509Certificate authnCert; public X509Certificate citizenCaCert; public X509Certificate rootCaCert; public X509Certificate signCert; public byte[] identityData; public byte[] addressData; public byte[] photoData; public byte[] identitySignatureData; public byte[] addressSignatureData; public X509Certificate rrnCertificate; public X509Certificate serverCertificate; public byte[] encodedServerCertificate; public byte[] transactionMessageSignature; }