public List <byte> GetHeaderBytes()
        {
            var token = new List <byte>();

            token.AddRange(Encoding.ASCII.GetBytes(ServerId.PadRight(34)));

            if (Ipv4Addr != null)
            {
                token.AddRange(Ipv4Addr.GetAddressBytes());
            }
            else
            {
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
            }

            if (Ipv6Addr != null)
            {
                token.AddRange(Ipv6Addr.GetAddressBytes());
            }
            else
            {
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
            }

            if (OnionAddress != null)
            {
                token.AddRange(Encoding.ASCII.GetBytes(OnionAddress));
            }
            else
            {
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
            }

            // TODO: Review the use of BitConverter for endian-ness issues
            byte[] portNumber = BitConverter.GetBytes(Port);

            token.Add(portNumber[0]);
            token.Add(portNumber[1]);

            return(token);
        }
Example #2
0
        public byte[] GetRegistrationTokenBytes(RsaKey rsaKey, BitcoinSecret privateKeyEcdsa)
        {
            var token = new List <byte>();

            token.AddRange(Encoding.ASCII.GetBytes(ServerId.PadRight(34)));

            if (Ipv4Addr != null)
            {
                token.AddRange(Ipv4Addr.GetAddressBytes());
            }
            else
            {
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
            }

            if (Ipv6Addr != null)
            {
                token.AddRange(Ipv6Addr.GetAddressBytes());
            }
            else
            {
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
            }

            if (OnionAddress != null)
            {
                token.AddRange(Encoding.ASCII.GetBytes(OnionAddress));
            }
            else
            {
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
                token.Add(0x00); token.Add(0x00); token.Add(0x00); token.Add(0x00);
            }

            // TODO: Review the use of BitConverter for endian-ness issues
            byte[] portNumber = BitConverter.GetBytes(Port);

            token.Add(portNumber[0]);
            token.Add(portNumber[1]);

            CryptoUtils cryptoUtils = new CryptoUtils(rsaKey, privateKeyEcdsa);

            // Sign header (excluding preliminary length marker bytes) with RSA
            RsaSignature = cryptoUtils.SignDataRSA(token.ToArray());
            byte[] rsaLength = BitConverter.GetBytes(RsaSignature.Length);

            // Sign header (excluding preliminary length marker bytes) with ECDSA
            EcdsaSignature = cryptoUtils.SignDataECDSA(token.ToArray());
            byte[] ecdsaLength = BitConverter.GetBytes(EcdsaSignature.Length);

            // TODO: Check if the lengths are >2 bytes. Should not happen
            // for most conceivable signature schemes at current key lengths
            token.Add(rsaLength[0]);
            token.Add(rsaLength[1]);
            token.AddRange(RsaSignature);

            token.Add(ecdsaLength[0]);
            token.Add(ecdsaLength[1]);
            token.AddRange(EcdsaSignature);

            // Server configuration hash
            token.AddRange(Encoding.ASCII.GetBytes(ConfigurationHash));

            // Finally add protocol byte and computed length to beginning of header
            byte[] protocolVersionByte = BitConverter.GetBytes(ProtocolVersion);
            byte[] headerLength        = BitConverter.GetBytes(token.Count);

            token.Insert(0, protocolVersionByte[0]);
            token.Insert(1, headerLength[0]);
            token.Insert(2, headerLength[1]);

            return(token.ToArray());
        }