-- S.MG, 2018 with Ada.Sequential_IO; with Raw_Types; use Raw_Types; with Ada.Text_IO; use Ada.Text_IO; with Interfaces; use Interfaces; package body IO_RSA is procedure ReadRSAKey( Filename : in String; E_Len_Chars : in Positive; D_Len_Chars : in Positive; Key : out RSA_OAEP.RSA_skey ) is package Char_IO is new Ada.Sequential_IO(Character); use Char_IO; Full : String(1..RSA_len'Length*2) := (others => '0'); Half : String(1..RSA_half'Length*2) := (others => '0'); e : String(1..E_Len_Chars) := (others => '0'); d : String(1..D_Len_Chars) := (others => '0'); F : Char_IO.File_Type; C : Character; begin Open( File => F, Mode => In_File, Name => Filename ); -- read n for I in Full'Range loop Read(F, Full(I)); end loop; -- read new line character and convert to hex Read(F, C); Hex2Octets(Full, Key.n); -- read e for I in e'Range loop Read(F, e(I)); end loop; -- read new line character and convert to hex, pad with 0 if needed Read(F, C); -- move it to Half, possibly at the end if e'len < half'len (0-led) if e'Length > Half'Length then raise Incorrect_E_Len; else Half(Half'Last-e'Length+1 .. Half'Last) := e; end if; Hex2Octets(Half, Key.e); -- read d for I in d'Range loop Read(F, d(I)); end loop; -- read new line character and convert to hex Read(F, C); if d'Length > Full'Length then raise Incorrect_D_Len; else Full := ( others => '0' ); Full(Full'Last-d'Length+1 .. Full'Last) := d; end if; Hex2Octets(Full, Key.d); -- read p for I in Half'Range loop Read(F, Half(I)); end loop; -- read new line character and convert to hex Read(F, C); Hex2Octets(Half, Key.p); -- read q for I in Half'Range loop Read(F, Half(I)); end loop; -- read new line character and convert to hex Read(F, C); Hex2Octets(Half, Key.q); -- read u for I in Half'Range loop Read(F, Half(I)); end loop; Hex2Octets(Half, Key.u); -- Close file Close( F ); exception when Char_IO.End_Error => Put_Line("ReadRSAKey ERROR: Unexpected end of file in " & Filename); when others => Put_Line("ReadRSAKey ERROR: can not open file " & Filename); end ReadRSAKey; procedure Hex2Octets( Hex: in String; O: out Raw_Types.Octets ) is S : String := "16#AA#"; -- to make sure that input String has EVEN number of chars (ie full octets) H : String(1..Hex'Length+Hex'Length mod 2) := (others=>'0'); begin -- first char is 0 if needed to cover full octet... H(H'Last-Hex'Length+1..H'Last) := Hex; O := (others => 0); for I in 0 .. H'Length/2-1 loop S := "16#" & H(H'First + I*2 .. H'First + I*2 + 1) & "#"; O(O'Last - H'Length/2 + 1 + I) := Unsigned_8'Value(S); end loop; end Hex2Octets; end IO_RSA;