rm userpr
[energimaaling.git] / tcpkomm / TCPMelding.cs
blobd8878d976305659b04c9775a4d14953c484fc304
1 using System;
2 using System.IO;
3 using System.Net;
4 using System.Net.Sockets;
6 using System.Threading;
8 using System.Security.Cryptography;
10 using System.Xml.Serialization;
12 namespace energimaaling
14 public class TCPKomm {
15 /* Protokoll spesifikasjon:
17 * All kommunikasjon foregår ved å sende ei TCPMelding struct
18 * Typen vil avgjere korleis ein kan tolke medlemmet 'data'.
20 * 'data' vil være kryptert.
24 /* Sentral skal lytte på denne porten for tilkobling frå Hus */
25 public const int SENTRALHUSPORT = 3000;
27 /* Sentral skal lytte på denne porten for tilkobling frå PDA */
28 public const int SENTRALPDAPORT = 3001;
30 /* DEKLARASJONER
32 * Type spesifikasjon
36 [Serializable()]
37 public enum Type { AuthQuery, AuthResponse, HusData, HusQuery, Error, Close, PdaData, PdaQuery, DEBUG };
39 /* Data objekt */
40 [Serializable()]
41 public struct AuthQuery {
42 public String kundenr;
43 public String passord;
46 [Serializable()]
47 public struct AuthResponse {
48 public bool Accepted;
51 [Serializable()]
52 public struct HusData {
53 string data;
56 /* Hus data sendt til PDA */
57 [Serializable()]
58 public struct PdaData {
59 public double effekt;
60 public bool reduser;
61 public bool alarm;
63 public string adresse;
64 public string navn;
67 [Serializable()]
68 public struct HusQuery {
69 // TODO!
72 [Serializable()]
73 public struct Debug {
74 public string msg;
77 [Serializable()]
78 public enum ErrorType { UnexpectedData };
80 [Serializable()]
81 public struct Error {
82 public ErrorType et;
83 public string msg;
86 [Serializable()]
87 public struct PdaQuery {
90 /* Sendast for å avslutte ei tilkobling skikkelig */
91 [Serializable()]
92 public struct Close {
93 public string msg;
96 [Serializable()]
97 public struct TCPMelding
99 /* Tcp Type */
100 public Type type;
102 /* Struct tilsvarande type */
103 public byte[] data;
106 /* Kryptering og sending
108 * Bruk TCPKomm.SendMelding og TCPKomm.MottaMelding, desse krypterer objektet - serialiserer det og
109 * sender det på nettverksstrømmen som du gir.
111 * Du må lage ei TCPMelding og ein TCPMelding type; bruk Serialiser.Serialize () på det og lagre
112 * det i TCPMelding.data.
114 * Du kan få det ut på samme måte, ved å lage ei TCPMelding type og bruke
115 * Serialiser.Deserialize (TCPMelding.data, typeof (TCPMelding typen)).
117 * For å sende:
119 // Lag autentiseringsmelding
120 TCPKomm.TCPMelding tm;
121 tm.type = TCPKomm.Type.AuthQuery;
122 TCPKomm.AuthQuery a;
123 a.kundenr = "test";
124 a.passord = "testp";
126 * Serialiser AuthQuery og lagre i tm.data:
128 tm.data = Serialiser.Serialize (a);
130 * Send på NetworkStream ns:
132 TCPKomm.SendMelding (ns, tm);
135 * For å motta:
137 TCPKomm.TCPMelding res = TCPKomm.MottaMelding (ns);
139 * For ei AuthQuery melding, gjer:
141 TCPKomm.AuthQuery aq = (TCPKomm.AuthQuery)Serialiser.Deserialize(tm.data, typeof(TCPKomm.AuthQuery));
143 * Du kan no bruke aq.kundenr og aq.passord.
146 * Hugs å laste nøkkel først i kvar prosess (biblioteket har ein instans for kvar) før du begynner.
148 TCPKomm.loadkeys ();
150 * Nøkkel kan lagast med 'kg' på Sentral; legg key.bin og iv.bin i samme mappe som programma skal køyre
151 * (Sentral, Hus, Pda).
156 public static void SendMelding(NetworkStream ns, TCPKomm.TCPMelding tm)
158 // krypterer (her blir TCPMelding serialisert)
159 CryptObject c = Encrypt(tm);
161 // Serialiserer CryptObjekt
162 byte[] ser = Serialiser.Serialize(c);
164 byte[] size = Serialiser.IntToSize(ser.Length);
167 // sender størrelse
168 ns.Write(size, 0, 2);
171 Console.WriteLine("SendMelding sender: " + ser.Length.ToString());
172 Console.WriteLine("Byte: " + size.ToString());
175 // sender objekt
176 ns.Write(ser, 0, ser.Length);
177 ns.Flush();
180 public static TCPMelding MottaMelding(NetworkStream ns)
182 // Vent på data
183 // while (!ns.DataAvailable) Thread.Sleep(50);
185 // motar størrelse
186 byte[] size = new byte[2];
188 ns.Read(size, 0, 2);
190 int sizei = Serialiser.SizeToInt(size);
192 // leser objekt
193 byte[] ser = new byte[sizei];
194 int r = ns.Read(ser, 0, sizei);
197 Console.WriteLine("MottaMelding; fikk: " + r.ToString() + " av " + sizei.ToString());
198 Console.WriteLine("Byte: " + size.ToString());
201 // deserialiserer cryptobjekt
202 CryptObject c = (CryptObject)Serialiser.Deserialize(ser, typeof(CryptObject));
204 // dekrypterer
205 TCPMelding tm = Decrypt(c);
206 return tm;
209 [Serializable()]
210 public struct CryptObject
212 public int length;
213 public byte[] encrypted;
216 public static CryptObject Encrypt (TCPMelding tm)
218 if (!keyloaded) throw new Exception ("Ingen key er lasta.");
219 CryptObject c = new CryptObject ();
221 MemoryStream enc = new MemoryStream ();
222 CryptoStream cStreamW = new CryptoStream (enc, ralg.CreateEncryptor (), CryptoStreamMode.Write);
224 byte[] ser = Serialiser.Serialize(tm);
226 c.length = (int) ser.Length;
228 cStreamW.Write (ser, 0, (int) ser.Length);
229 cStreamW.FlushFinalBlock (); // also .Close ()'es
231 enc.Position = 0; // Rewind
232 c.encrypted = (byte[]) enc.ToArray ();
233 return c;
236 public static TCPMelding Decrypt (CryptObject c)
238 if (!keyloaded) throw new Exception ("Ingen key er lasta.");
239 MemoryStream benc = new MemoryStream (c.encrypted);
241 CryptoStream cStreamR = new CryptoStream (benc, ralg.CreateDecryptor (), CryptoStreamMode.Read);
243 byte [] buenc = new byte[c.length];
244 cStreamR.Read (buenc, 0, c.length);
246 TCPMelding tm = (TCPMelding)Serialiser.Deserialize(buenc, typeof(TCPMelding));
247 cStreamR.Close ();
248 return tm;
252 private static bool keyloaded = false;
253 private static byte[] IV;
254 private static byte[] KEY;
255 public static Rijndael ralg;
257 public static void loadkeys () {
258 log ("Laster Rijndaelll nøkkel..");
259 try {
261 * PDA har tydeligvis problem med å laste fra fil so vi legg den inn manuelt foreløpig.
263 * Det betyr at genkeys har ingen funksjon no; og du treng ikkje key.bin og iv.bin
267 byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
268 byte[] iv = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
269 ralg = Rijndael.Create();
270 ralg.Key = key;
271 ralg.IV = iv;
272 ralg.Padding = PaddingMode.PKCS7;
274 keyloaded = true;
276 } catch {
277 log ("FEIL! Kunne ikkje laste nøkkel.");
278 keyloaded = false;
282 public static void genkeys () {
283 log ("Lager Rijndael nøkkel..");
284 ralg = Rijndael.Create ();
285 ralg.Padding = PaddingMode.PKCS7;
287 log (".. IV");
288 ralg.GenerateIV ();
290 log (".. Key");
291 ralg.GenerateKey ();
293 FileStream fiv = File.OpenWrite ("iv.bin");
294 FileStream fkey = File.OpenWrite ("key.bin");
296 BinaryWriter b = new BinaryWriter (fiv);
297 b.Write (ralg.IV);
299 b = new BinaryWriter (fkey);
300 b.Write (ralg.Key);
302 fiv.Close ();
303 fkey.Close ();
304 log ("OK.");
306 KEY = ralg.Key;
307 IV = ralg.IV;
308 keyloaded = true;
311 private static void log (String s) {
312 Console.WriteLine ("[TcpMelding] " + s);