-
+ 9F725D85955F8C39AA166D4F5E1B63D54F9F153084A351667D78C9BB709A41F86927936730FEB6615127F6111821624E7F67B5D7AE6A95299716F78B5C9A3B87
smg_comms/tests/messages-test_serializing.adb
(0 . 0)(1 . 478)
633 -- Tests for the serialization of data structures in SMG Protocol
634 -- S.MG, 2018
635
636 with RNG;
637 with Data_Structs;
638 with Messages; use Messages;
639 with Interfaces; use Interfaces;
640 with System;
641 with System.Storage_Elements; use System.Storage_Elements;
642 with Ada.Text_IO; use Ada.Text_IO;
643
644 package body Messages.Test_Serializing is
645
646 procedure Serialize_Keyset_RSA is
647 Msg : RSA_Msg;
648 ReadK : Player_RSA;
649 ReadC : Interfaces.Unsigned_16;
650 WMsg : RSA_Msg;
651 TypeID : constant Interfaces.Unsigned_8 := 251;
652 begin
653 Put_Line("Generating data for 5.1 RSA key set in RSA message.");
654 -- fill message with random data
655 RNG.Get_Octets(Msg);
656
657 -- attempt read - it should fail
658 begin
659 Read_RKeys_RMsg( Msg, ReadC, ReadK );
660 exception
661 when Invalid_Msg =>
662 if Msg(Msg'First) /= TypeID then
663 Put_Line("PASS: exception correctly raised for invalid message");
664 else
665 Put_Line("FAIL: exception raised on VALID message!");
666 end if;
667 end;
668
669 -- set correct type id
670 Msg(Msg'First) := TypeID;
671
672 -- attempt read + write and compare
673 Read_RKeys_RMsg( Msg, ReadC, ReadK );
674 Write_RKeys_RMsg( ReadK, ReadC, RNG_PAD, WMsg );
675
676 -- check result (without trailing padding since that CAN be different!)
677 if WMsg(1..520) /= Msg(1..520) then
678 Put_Line("FAIL: read+write of RSA keys to RSA message.");
679 for I in 1..520 loop
680 if WMsg(I) /= Msg(I) then
681 Put_Line("At " & Integer'Image(I) & " WMsg is " &
682 Unsigned_8'Image(WMsg(I)) & " while Msg is " &
683 Unsigned_8'Image(Msg(I)));
684 end if;
685 end loop;
686 else
687 Put_Line("PASS: read+write of RSA keys to RSA message.");
688 end if;
689 end Serialize_Keyset_RSA;
690
691 procedure Serialize_Keyset_SS is
692 Msg : Serpent_Msg;
693 RMsg : RSA_Msg;
694 KSet : Serpent_Keyset(5);
695 LSB : Interfaces.Unsigned_8 := 16#01#;
696 MSB : Interfaces.Unsigned_8 := 16#80#;
697 LMSB : Interfaces.Unsigned_8 := 16#81#;
698 Counter : Interfaces.Unsigned_16 := 101;
699 NewSetS : Serpent_Keyset;
700 NewSetR : Serpent_Keyset;
701 NewCounterR: Interfaces.Unsigned_16:=0;
702 NewCounterS: Interfaces.Unsigned_16:=0;
703 begin
704 Put_Line("Generating the Serpent Keys...");
705 -- fill a set of Serpent Keys
706 for I in 1..KSet.N loop
707 RNG.Get_Octets(KSet.Keys(Interfaces.Unsigned_8(I)));
708 end loop;
709 KSet.Flag := LSB;
710
711 Put_Line("Writing the keys to messages...");
712 -- write keyset to serpent & rsa messages
713 Write_SKeys_SMsg( KSet, Counter, RNG_PAD, Msg );
714 Write_SKeys_RMsg( KSet, Counter, RNG_PAD, RMsg );
715
716 Put_Line("Reading keys back from messages...");
717 -- read keyset from serpent and rsa messages
718 Read_SKeys_SMsg( Msg, NewCounterS, NewSetS );
719 Read_SKeys_RMsg( RMsg, NewCounterR, NewSetR );
720
721 Put_Line("Comparing the keysets...");
722 -- compare the two keysets
723 if NewCounterS /= Counter or NewCounterS /= Counter or
724 NewSetS /= KSet or NewSetR /= KSet then
725 Put_Line("FAIL: keysets are different!");
726 else
727 Put_Line("PASS: keysets are the same!");
728 end if;
729
730 Put_Line("Attempting to read from mangled message");
731 begin
732 Msg(Msg'First) := Msg(Msg'First)+25;
733 Read_SKeys_SMsg( Msg, Counter, NewSetS);
734 Put_Line("FAIL: read failed to raise invalid message exception!");
735 exception
736 when Invalid_Msg =>
737 Put_Line("PASS: exception correctly raised for invalid message");
738 end;
739 end Serialize_Keyset_SS;
740
741 procedure Serialize_Keys_Mgm is
742 N_Burnt : Counter_8bits;
743 Counter : Interfaces.Unsigned_16 := 16#EDA9#;
744 Mgm_S : Keys_Mgm;
745 Mgm_R : Keys_Mgm;
746 Cnt_S : Interfaces.Unsigned_16:=0;
747 Cnt_R : Interfaces.Unsigned_16:=0;
748 O1 : Octets_1;
749 SMsg : Serpent_Msg;
750 RMsg : RSA_Msg;
751 begin
752 -- fill the struct with random stuff
753 RNG.Get_Octets( O1 );
754 N_Burnt := Cast(O1);
755 declare
756 Mgm: Keys_Mgm(N_Burnt);
757 begin
758 RNG.Get_Octets( O1 );
759 Mgm.N_Server := O1(O1'First);
760 RNG.Get_Octets( O1 );
761 Mgm.N_Client := O1(O1'First);
762 RNG.Get_Octets( O1 );
763 Mgm.Key_ID := O1(O1'First);
764 if N_Burnt > 0 then
765 RNG.Get_Octets( Mgm.Burnt );
766 end if;
767 -- write it to Serpent and RSA messages
768 Write_KMgm_SMsg(Mgm, Counter, RNG_PAD, SMsg);
769 Write_KMgm_RMsg(Mgm, Counter, RNG_PAD, RMsg);
770
771 -- read it back from Serpent and RSA messages
772 Read_KMgm_SMsg( SMsg, Cnt_S, Mgm_S );
773 Read_KMgm_RMsg( RMsg, Cnt_R, Mgm_R );
774
775 -- check results
776 if Cnt_S /= Counter or
777 Mgm_S.N_Burnt /= Mgm.N_Burnt or
778 Mgm_S /= Mgm then
779 Put_Line("FAIL: read/write key management struct to S msg.");
780 else
781 Put_Line("PASS: read/write key management struct to S msg.");
782 end if;
783
784 if Cnt_R /= Counter or
785 Mgm_R.N_Burnt /= Mgm.N_Burnt or
786 Mgm_R /= Mgm then
787 Put_Line("FAIL: read/write key management struct to R msg.");
788 Put_Line("Cnt_R is " & Unsigned_16'Image(Cnt_R));
789 Put_Line("Counter is " & Unsigned_16'Image(Counter));
790 Put_Line("Mgm_R.N_Burnt is " & Counter_8bits'Image(Mgm_R.N_Burnt));
791 Put_Line("Mgm.N_Burnt is " & Counter_8bits'Image(Mgm.N_Burnt));
792 else
793 Put_Line("PASS: read/write key management struct to R msg.");
794 end if;
795
796 -- attempt mangled call - should raise exception
797 begin
798 SMsg(SMsg'First) := SMsg(SMsg'First) + 1;
799 Read_KMgm_SMsg( SMsg, Cnt_S, Mgm_S);
800 Put_Line("FAIL: Read_KMgm_SMsg failed to raise exception!");
801 exception
802 when Invalid_Msg =>
803 Put_Line("PASS: Read_KMgm_SMsg correctly raised exception.");
804 end;
805
806 end;
807
808 end Serialize_Keys_Mgm;
809
810 procedure Serialize_File_Request( Reps: in Positive) is
811 MaxSz: Positive := 340;
812 O2 : Raw_Types.Octets_2;
813 U16 : Interfaces.Unsigned_16;
814 Counter : Interfaces.Unsigned_16;
815 ReadCounter: Interfaces.Unsigned_16;
816 Written: Natural;
817 Msg : Raw_Types.Serpent_Msg;
818 F_No, Sz: Text_Len;
819 begin
820 for I in 1 .. Reps loop
821 -- generate a random size
822 RNG.Get_Octets( O2 );
823 U16 := Raw_Types.Cast( O2 );
824 Sz := Text_Len( Positive(U16) mod MaxSz + 1);
825
826 -- generate a random number of files
827 RNG.Get_Octets( O2 );
828 U16 := Raw_Types.Cast( O2 );
829 -- make sure it's within Positive range i.e. not 0
830 if U16 = 0 then
831 U16 := 1;
832 end if;
833 F_No := Text_Len( Positive(U16) mod Sz + 1 );
834
835 declare
836 FR: Filenames(F_No, Sz);
837 ReadFR: Filenames;
838 O : Octets(1..Sz);
839 Len : Positive := Sz / F_No;
840 begin
841 Put_Line("Generating test for File Request with " &
842 Integer'Image(FR.F_No) & " filenames.");
843 -- generate a random counter
844 RNG.Get_Octets(O2);
845 Counter := Raw_Types.Cast(O2);
846
847 -- fill FR
848 RNG.Get_Octets( O );
849 -- replace separators if any
850 for I in O'Range loop
851 if O(I) = 59 then
852 O(I) := 69;
853 end if;
854 end loop;
855
856 Octets_To_String( O, FR.S );
857 for I in FR.Starts'Range loop
858 FR.Starts(I) := Interfaces.Unsigned_16( FR.Starts'First +
859 Len*(I-FR.Starts'First));
860 end loop;
861
862 -- write FR to message
863 Write_File_Request(FR, Counter, RNG_PAD, Msg, Written);
864
865 -- check how many filenames were written
866 if Written /= FR.F_No then
867 Put_Line("FAIL: only " & Natural'Image(Written) &
868 " filenames written out of " & Natural'Image(FR.F_No));
869 else
870 Put_Line("PASS: wrote " & Natural'Image(Written) & " filenames.");
871 end if;
872
873 -- read it from message and check result
874 Read_File_Request(Msg, ReadCounter, ReadFR);
875 if ReadCounter /= Counter then
876 Put_Line("FAIL: ReadCounter is " & Unsigned_16'Image(ReadCounter) &
877 " instead of expected " & Unsigned_16'Image(Counter) );
878 else
879 Put_Line("PASS: ReadCounter was read correctly as " &
880 Unsigned_16'Image(ReadCounter));
881 end if;
882 if ReadFr.Sz /= FR.Sz then
883 Put_Line("FAIL: Read FR.Sz = " & Text_Len'Image(ReadFr.Sz) &
884 " while expected sz is " & Text_Len'Image(FR.Sz));
885 else
886 Put_Line("PASS: Read FR.Sz as expected = " &
887 Text_Len'Image(ReadFr.Sz));
888 end if;
889 if ReadFr /= FR then
890 Put_Line("FAIL: ReadFr different from FR.");
891 else
892 Put_Line("PASS: ReadFr as expected, same as FR.");
893 end if;
894 end;
895 end loop;
896
897 -- test with more files than can fit
898 Put_Line("Test case for File Request with more files than fit.");
899 declare
900 F: Filenames(4, 16384);
901 ReadF: Filenames;
902 begin
903 F.Starts(1) := Interfaces.Unsigned_16(F.S'First);
904 F.Starts(2) := Interfaces.Unsigned_16(F.S'First + 342);
905 F.Starts(3) := 16370;
906 F.Starts(4) := 16380;
907 Write_File_Request(F, Counter, RNG_PAD, Msg, Written);
908 if Written /= 1 then
909 Put_Line("FAIL: Written is " & Natural'Image(Written) &
910 " instead of expected 1.");
911 else
912 Put_Line("PASS: Written is 1 out of 4, as expected.");
913 end if;
914 Read_File_Request(Msg, ReadCounter, ReadF);
915 if ReadF.F_No /= 1 or ReadF.Starts(1) /= 1 or ReadF.Sz /= 342 then
916 Put_Line("FAIL: F_No is " & Text_Len'Image(ReadF.F_No) &
917 " Sz is " & Text_Len'Image(ReadF.Sz));
918 else
919 Put_line("PASS: written 1 out of 4 correctly.");
920 end if;
921 end;
922 end Serialize_File_Request;
923
924 procedure Serialize_File_Chunk is
925 Filename : String := "afile.png";
926 FC : File_Chunk( Len => 945,
927 Count => 0,
928 Name_Len => Filename'Length);
929 ReadFC : File_Chunk;
930 Msg : Raw_Types.Serpent_Msg;
931 Pad : Raw_Types.Octets_8 := RNG_PAD;
932 begin
933 -- fill FC with random content
934 FC.Filename := Filename;
935 RNG.Get_Octets(FC.Content);
936
937 -- write FC to message with random padding
938 Write_File_Transfer( FC, Pad, Msg );
939
940 -- read FC and check
941 Read_File_Transfer( Msg, ReadFC );
942
943 if FC /= ReadFC then
944 Put_Line("FAIL: read/write file chunk.");
945 else
946 Put_Line("PASS: read/write file chunk.");
947 end if;
948 end Serialize_File_Chunk;
949
950 procedure Serialize_Action is
951 O2 : Raw_Types.Octets_2;
952 U16: Interfaces.Unsigned_16;
953 Len: Raw_Types.Text_Len;
954 Counter: Interfaces.Unsigned_16;
955 begin
956 Put_Line("Generating a random action for testing.");
957 -- generate random counter
958 RNG.Get_Octets( O2 );
959 Counter := Raw_Types.Cast( O2 );
960
961 -- generate action length
962 RNG.Get_Octets( O2 );
963 U16 := Raw_Types.Cast( O2 );
964 if U16 < 1 then
965 U16 := 1;
966 else
967 if U16 + 5 > Raw_Types.Serpent_Msg'Length then
968 U16 := Raw_Types.Serpent_Msg'Length - 5;
969 end if;
970 end if;
971 Len := Raw_Types.Text_Len( U16 );
972
973 declare
974 A: Raw_Types.Text_Octets( Len );
975 B: Raw_Types.Text_Octets;
976 Msg: Raw_Types.Serpent_Msg;
977 ReadC : Interfaces.Unsigned_16;
978 begin
979 RNG.Get_Octets( A.Content );
980 begin
981 Write_Action( A, Counter, RNG_PAD, Msg );
982 Read_Action( Msg, ReadC, B );
983 if B /= A then
984 Put_Line("FAIL: read/write of Action.");
985 else
986 Put_Line("PASS: read/write of Action.");
987 end if;
988 exception
989 when Invalid_Msg =>
990 if Len + 5 > Raw_Types.Serpent_Msg'Length then
991 Put_Line("PASS: exception correctly raised for Action too long");
992 else
993 Put_Line("FAIL: exception INCORRECTLY raised at action r/w!");
994 end if;
995 end;
996 end;
997 end Serialize_Action;
998
999 procedure Converter_String_Octets is
1000 Len: constant Natural := 234;
1001 -- original values
1002 S: String(1..Len);
1003 O: Octets(1..Len);
1004 -- converted values
1005 CS: String(1..Len);
1006 CO: Octets(1..Len);
1007 begin
1008 -- original octets
1009 RNG.Get_Octets(O);
1010 Octets_To_String(O, CS);
1011 String_To_Octets(CS, CO);
1012 if CO /= O then
1013 Put_Line("FAIL: octets different after string/octets conversion.");
1014 else
1015 Put_Line("PASS: octets same after string/octets conversion.");
1016 end if;
1017
1018 -- original string
1019 for I in S'Range loop
1020 S(I) := Character'Val(I mod 12);
1021 end loop;
1022 String_To_Octets(S, CO);
1023 Octets_To_String(CO, CS);
1024 if CS /= S then
1025 Put_Line("FAIL: string different after string/octets conversion.");
1026 else
1027 Put_Line("PASS: string same after string/octets conversion.");
1028 end if;
1029 end Converter_String_Octets;
1030
1031 procedure Test_Padding is
1032 Msg : Raw_Types.Serpent_Msg := (others => 12);
1033 Old : Raw_Types.Serpent_Msg := Msg;
1034 Pos : Natural := 16;
1035 NewPos : Natural := Pos;
1036 Counter : Interfaces.Unsigned_16;
1037 U16 : Interfaces.Unsigned_16;
1038 O2 : Raw_Types.Octets_2;
1039 Pad : Raw_Types.Octets_8;
1040 Pass : Boolean;
1041 begin
1042 -- get random counter
1043 RNG.Get_Octets( O2 );
1044 Counter := Raw_Types.Cast( O2 );
1045
1046 -- test with random padding
1047 Pad := RNG_PAD;
1048 Write_End( Msg, NewPos, Counter, Pad );
1049 -- check NewPos and counter
1050 Pass := True;
1051 if NewPos /= Msg'Last + 1 then
1052 Put_Line("FAIL: incorrect Pos value after Write_End with rng.");
1053 Pass := False;
1054 end if;
1055 Read_U16(Msg, Pos, U16);
1056 if U16 /= Counter then
1057 Put_Line("FAIL: incorrect Counter by Write_End with rng.");
1058 Pass := False;
1059 end if;
1060 -- check that the padding is at least different...
1061 if Msg(Pos..Msg'Last) = Old(Pos..Old'Last) or
1062 Msg(Pos..Pos+Pad'Length-1) = Pad then
1063 Put_Line("FAIL: no padding written by Write_End with rng.");
1064 Pass := False;
1065 end if;
1066 if Pass then
1067 Put_Line("PASS: Write_End with rng.");
1068 end if;
1069
1070 -- prepare for the next test
1071 Pass := True;
1072 Pos := Pos - 2;
1073 NewPos := Pos;
1074 Msg := Old;
1075
1076 -- get random padding
1077 RNG.Get_Octets( Pad );
1078
1079 -- write with fixed padding and check
1080 Write_End( Msg, NewPos, Counter, Pad );
1081 Pass := True;
1082
1083 if NewPos = Msg'Last + 1 then
1084 -- check counter + padding
1085 Read_U16( Msg, Pos, U16 );
1086 if U16 /= Counter then
1087 Put_Line("FAIL: Counter was not written by Write_End.");
1088 Pass := False;
1089 end if;
1090 for I in Pos..Msg'Last loop
1091 if Msg( I ) /= Pad( Pad'First + (I - Pos) mod Pad'Length ) then
1092 Put_Line("FAIL: Msg(" & Natural'Image(I) & ")=" &
1093 Unsigned_8'Image(Msg(I)) & " /= Pad(" &
1094 Natural'Image(Pad'First+(I-Pos) mod Pad'Length) &
1095 ") which is " &
1096 Unsigned_8'Image(Pad(Pad'First+(I-Pos) mod Pad'Length)));
1097 Pass := False;
1098 end if;
1099 end loop;
1100 else
1101 Put_Line("FAIL: Pos is wrong after call to Write_End.");
1102 Pass := False;
1103 end if;
1104 if Pass then
1105 Put_Line("PASS: test for Write_End with fixed padding.");
1106 end if;
1107 end Test_Padding;
1108
1109 end Messages.Test_Serializing;
1110