-- Tests for the serialization of data structures in SMG Protocol -- S.MG, 2018 with RNG; with Data_Structs; use Data_Structs; with Messages; use Messages; with Interfaces; use Interfaces; with System; with System.Storage_Elements; use System.Storage_Elements; with Ada.Text_IO; use Ada.Text_IO; package body Test_Serializing is procedure Serialize_Keyset_SS is Msg : Serpent_Msg; RMsg : RSA_Msg; KSet : Serpent_Keyset(5); LSB : Interfaces.Unsigned_8 := 16#01#; MSB : Interfaces.Unsigned_8 := 16#80#; LMSB : Interfaces.Unsigned_8 := 16#81#; Counter : Interfaces.Unsigned_16 := 101; NewSetS : Serpent_Keyset; NewSetR : Serpent_Keyset; NewCounterR: Interfaces.Unsigned_16:=0; NewCounterS: Interfaces.Unsigned_16:=0; begin Put_Line("Generating the Serpent Keys..."); -- fill a set of Serpent Keys for I in 1..KSet.N loop RNG.Get_Octets(KSet.Keys(Interfaces.Unsigned_8(I))); end loop; KSet.Flag := LSB; Put_Line("Writing the keys to messages..."); -- write keyset to serpent & rsa messages Write_SKeys_SMsg( KSet, Counter, Msg ); Write_SKeys_RMsg( KSet, Counter, RMsg ); Put_Line("Reading keys back from messages..."); -- read keyset from serpent and rsa messages Read_SKeys_SMsg( Msg, NewCounterS, NewSetS ); Read_SKeys_RMsg( RMsg, NewCounterR, NewSetR ); Put_Line("Comparing the keysets..."); -- compare the two keysets if NewCounterS /= Counter or NewCounterS /= Counter or NewSetS /= KSet or NewSetR /= KSet then Put_Line("FAIL: keysets are different!"); else Put_Line("PASS: keysets are the same!"); end if; Put_Line("Attempting to read from mangled message"); begin Msg(Msg'First) := Msg(Msg'First)+25; Read_SKeys_SMsg( Msg, Counter, NewSetS); Put_Line("FAIL: read failed to raise invalid message exception!"); exception when Invalid_Msg => Put_Line("PASS: exception correctly raised for invalid message"); end; end Serialize_Keyset_SS; procedure Serialize_Keys_Mgm is N_Burnt : Counter_8bits; Counter : Interfaces.Unsigned_16 := 16#EDA9#; Mgm_S : Keys_Mgm; Mgm_R : Keys_Mgm; Cnt_S : Interfaces.Unsigned_16:=0; Cnt_R : Interfaces.Unsigned_16:=0; O1 : Octets_1; SMsg : Serpent_Msg; RMsg : RSA_Msg; begin -- fill the struct with random stuff RNG.Get_Octets( O1 ); N_Burnt := Cast(O1); declare Mgm: Keys_Mgm(N_Burnt); begin RNG.Get_Octets( O1 ); Mgm.N_Server := O1(O1'First); RNG.Get_Octets( O1 ); Mgm.N_Client := O1(O1'First); RNG.Get_Octets( O1 ); Mgm.Key_ID := O1(O1'First); if N_Burnt > 0 then RNG.Get_Octets( Mgm.Burnt ); end if; -- write it to Serpent and RSA messages Write_KMgm_SMsg(Mgm, Counter, SMsg); Write_KMgm_RMsg(Mgm, Counter, RMsg); -- read it back from Serpent and RSA messages Read_KMgm_SMsg( SMsg, Cnt_S, Mgm_S ); Read_KMgm_RMsg( RMsg, Cnt_R, Mgm_R ); -- check results if Cnt_S /= Counter or Mgm_S.N_Burnt /= Mgm.N_Burnt or Mgm_S /= Mgm then Put_Line("FAIL: read/write key management struct to S msg."); else Put_Line("PASS: read/write key management struct to S msg."); end if; if Cnt_R /= Counter or Mgm_R.N_Burnt /= Mgm.N_Burnt or Mgm_R /= Mgm then Put_Line("FAIL: read/write key management struct to R msg."); Put_Line("Cnt_R is " & Unsigned_16'Image(Cnt_R)); Put_Line("Counter is " & Unsigned_16'Image(Counter)); Put_Line("Mgm_R.N_Burnt is " & Counter_8bits'Image(Mgm_R.N_Burnt)); Put_Line("Mgm.N_Burnt is " & Counter_8bits'Image(Mgm.N_Burnt)); else Put_Line("PASS: read/write key management struct to R msg."); end if; -- attempt mangled call - should raise exception begin SMsg(SMsg'First) := SMsg(SMsg'First) + 1; Read_KMgm_SMsg( SMsg, Cnt_S, Mgm_S); Put_Line("FAIL: Read_KMgm_SMsg failed to raise exception!"); exception when Invalid_Msg => Put_Line("PASS: Read_KMgm_SMsg correctly raised exception."); end; end; end Serialize_Keys_Mgm; procedure Serialize_File_Request( Reps: in Positive) is MaxSz: Positive := 340; O2 : Raw_Types.Octets_2; U16 : Interfaces.Unsigned_16; Counter : Interfaces.Unsigned_16; ReadCounter: Interfaces.Unsigned_16; Written: Natural; Msg : Raw_Types.Serpent_Msg; F_No, Sz: Text_Len; begin for I in 1 .. Reps loop -- generate a random size RNG.Get_Octets( O2 ); U16 := Raw_Types.Cast( O2 ); Sz := Text_Len( Positive(U16) mod MaxSz + 1); -- generate a random number of files RNG.Get_Octets( O2 ); U16 := Raw_Types.Cast( O2 ); F_No := Text_Len( Positive(U16) mod Sz ); if F_No = 0 then F_No := 1; end if; declare FR: Filenames(F_No, Sz); ReadFR: Filenames; O : Octets(1..Sz); Len : Positive := Sz / F_No; begin Put_Line("Generating test for File Request with " & Integer'Image(FR.F_No) & " filenames."); -- generate a random counter RNG.Get_Octets(O2); Counter := Raw_Types.Cast(O2); -- fill FR RNG.Get_Octets( O ); -- replace separators if any for I in O'Range loop if O(I) = 59 then O(I) := 69; end if; end loop; Octets_To_String( O, FR.S ); for I in FR.Starts'Range loop FR.Starts(I) := Interfaces.Unsigned_16( FR.Starts'First + Len*(I-FR.Starts'First)); end loop; -- write FR to message Write_File_Request(FR, Counter, Msg, Written); -- check how many filenames were written if Written /= FR.F_No then Put_Line("FAIL: only " & Natural'Image(Written) & " filenames written out of " & Natural'Image(FR.F_No)); else Put_Line("PASS: wrote " & Natural'Image(Written) & " filenames."); end if; -- read it from message and check result Read_File_Request(Msg, ReadCounter, ReadFR); if ReadCounter /= Counter then Put_Line("FAIL: ReadCounter is " & Unsigned_16'Image(ReadCounter) & " instead of expected " & Unsigned_16'Image(Counter) ); else Put_Line("PASS: ReadCounter was read correctly as " & Unsigned_16'Image(ReadCounter)); end if; if ReadFr.Sz /= FR.Sz then Put_Line("FAIL: Read FR.Sz = " & Text_Len'Image(ReadFr.Sz) & " while expected sz is " & Text_Len'Image(FR.Sz)); else Put_Line("PASS: Read FR.Sz as expected = " & Text_Len'Image(ReadFr.Sz)); end if; if ReadFr /= FR then Put_Line("FAIL: ReadFr different from FR."); else Put_Line("PASS: ReadFr as expected, same as FR."); end if; end; end loop; -- test with more files than can fit Put_Line("Test case for File Request with more files than fit."); declare F: Filenames(4, 16384); ReadF: Filenames; begin F.Starts(1) := Interfaces.Unsigned_16(F.S'First); F.Starts(2) := Interfaces.Unsigned_16(F.S'First + 342); F.Starts(3) := 16370; F.Starts(4) := 16380; Write_File_Request(F, Counter, Msg, Written); if Written /= 1 then Put_Line("FAIL: Written is " & Natural'Image(Written) & " instead of expected 1."); else Put_Line("PASS: Written is 1 out of 4, as expected."); end if; Read_File_Request(Msg, ReadCounter, ReadF); if ReadF.F_No /= 1 or ReadF.Starts(1) /= 1 or ReadF.Sz /= 342 then Put_Line("FAIL: F_No is " & Text_Len'Image(ReadF.F_No) & " Sz is " & Text_Len'Image(ReadF.Sz)); else Put_line("PASS: written 1 out of 4 correctly."); end if; end; end Serialize_File_Request; procedure Serialize_File_Chunk is Filename : String := "afile.png"; FC : File_Chunk( Len => 945, Count => 0, Name_Len => Filename'Length); ReadFC : File_Chunk; Msg : Raw_Types.Serpent_Msg; begin -- fill FC with random content FC.Filename := Filename; RNG.Get_Octets(FC.Content); -- write FC to message Write_File_Transfer( FC, Msg ); -- read FC and check Read_File_Transfer( Msg, ReadFC ); if FC /= ReadFC then Put_Line("FAIL: read/write file chunk."); else Put_Line("PASS: read/write file chunk."); end if; end Serialize_File_Chunk; procedure Converter_String_Octets is Len: constant Natural := 234; -- original values S: String(1..Len); O: Octets(1..Len); -- converted values CS: String(1..Len); CO: Octets(1..Len); begin -- original octets RNG.Get_Octets(O); Octets_To_String(O, CS); String_To_Octets(CS, CO); if CO /= O then Put_Line("FAIL: octets different after string/octets conversion."); else Put_Line("PASS: octets same after string/octets conversion."); end if; -- original string for I in S'Range loop S(I) := Character'Val(I mod 12); end loop; String_To_Octets(S, CO); Octets_To_String(CO, CS); if CS /= S then Put_Line("FAIL: string different after string/octets conversion."); else Put_Line("PASS: string same after string/octets conversion."); end if; end Converter_String_Octets; end Test_Serializing;