package org.bouncycastle.crypto.tls;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.io.Streams;
public class ServerNameList
{
protected Vector serverNameList;
public ServerNameList(Vector serverNameList)
{
if (serverNameList == null)
{
throw new IllegalArgumentException("'serverNameList' must not be null");
}
this.serverNameList = serverNameList;
}
public Vector getServerNameList()
{
return serverNameList;
}
public void encode(OutputStream output) throws IOException
{
ByteArrayOutputStream buf = new ByteArrayOutputStream();
short[] nameTypesSeen = new short[0];
for (int i = 0; i < serverNameList.size(); ++i)
{
ServerName entry = (ServerName)serverNameList.elementAt(i);
nameTypesSeen = checkNameType(nameTypesSeen, entry.getNameType());
if (nameTypesSeen == null)
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
entry.encode(buf);
}
TlsUtils.checkUint16(buf.size());
TlsUtils.writeUint16(buf.size(), output);
Streams.writeBufTo(buf, output);
}
public static ServerNameList parse(InputStream input) throws IOException
{
int length = TlsUtils.readUint16(input);
if (length < 1)
{
throw new TlsFatalAlert(AlertDescription.decode_error);
}
byte[] data = TlsUtils.readFully(length, input);
ByteArrayInputStream buf = new ByteArrayInputStream(data);
short[] nameTypesSeen = new short[0];
Vector server_name_list = new Vector();
while (buf.available() > 0)
{
ServerName entry = ServerName.parse(buf);
nameTypesSeen = checkNameType(nameTypesSeen, entry.getNameType());
if (nameTypesSeen == null)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
server_name_list.addElement(entry);
}
return new ServerNameList(server_name_list);
}
private static short[] checkNameType(short[] nameTypesSeen, short nameType)
{
if (!NameType.isValid(nameType) || Arrays.contains(nameTypesSeen, nameType))
{
return null;
}
return Arrays.append(nameTypesSeen, nameType);
}
}