protected override byte[] EncodeDataBytes(ProtocolVersion version)
{
int typesLength = 0;
if (CertificateTypes.Count > 255) {
throw new Exception("Number of certificate types too large: " + CertificateTypes.Count);
} else {
typesLength = CertificateTypes.Count;
}
int sighashLength = 0;
if (version.HasSelectableSighash) {
if (SignatureAndHashAlgorithms.Count > 65535) {
throw new Exception("Number of sighash values too large: " + SignatureAndHashAlgorithms.Count);
} else {
sighashLength = 2*SignatureAndHashAlgorithms.Count;
}
}
int authsLength = 0;
foreach (string name in CertificateAuthorities) {
// TODO: Should support punycode as well?
authsLength += 2;
authsLength += Encoding.ASCII.GetBytes(name).Length;
if (authsLength > 65535) {
throw new Exception("Certificate authorities length too large");
}
}
MemoryStream memStream = new MemoryStream();
HandshakeStream stream = new HandshakeStream(memStream);
stream.WriteUInt8((byte) typesLength);
foreach (byte type in CertificateTypes) {
stream.WriteUInt8(type);
}
if (version.HasSelectableSighash) {
stream.WriteUInt16((UInt16) sighashLength);
foreach (UInt16 sighash in SignatureAndHashAlgorithms) {
stream.WriteUInt16(sighash);
}
}
stream.WriteUInt16((UInt16) authsLength);
foreach (string name in CertificateAuthorities) {
// TODO: Should support punycode as well?
int nameLen = Encoding.ASCII.GetBytes(name).Length;
stream.WriteUInt16((UInt16) nameLen);
stream.WriteBytes(Encoding.ASCII.GetBytes(name));
}
return memStream.ToArray();
}