@@ -69,9 +69,19 @@ package body AWS.Net.SSL is
6969
7070 subtype Datum_Type is Certificate.Impl.Datum_Type;
7171
72+ type String_Access is access all String (Positive);
73+ function To_String_Access is
74+ new Unchecked_Conversion (TSSL.a_unsigned_char_t, String_Access);
75+
76+ function To_String (Datum : TSSL.gnutls_datum_t) return String is
77+ (To_String_Access (Datum.data) (1 .. Integer (Datum.size)));
78+
7279 function Load_File (Filename : String) return Datum_Type
7380 renames Certificate.Impl.Load_File;
7481
82+ procedure ALPN_Set (Socket : Socket_Type);
83+ -- Set ALPN from config to secure socket before handshake
84+
7585 type PCert_Array is
7686 array (Positive range <>) of aliased TSSL.gnutls_pcert_st
7787 with Convention => C;
@@ -163,7 +173,7 @@ package body AWS.Net.SSL is
163173
164174 function Equal (Left, Right : TSSL.gnutls_datum_t) return Boolean;
165175
166- function Hash (Item : TSSL.gnutls_datum_t) return Containers.Hash_Type;
176+ function Hash (Item : TSSL.gnutls_datum_t) return Ada. Containers.Hash_Type;
167177
168178 procedure Check_File (Prefix, Filename : String);
169179 -- Check that Filename is present, raise an exception adding
@@ -175,14 +185,14 @@ package body AWS.Net.SSL is
175185 end record ;
176186
177187 package Session_Container is
178- new Containers.Hashed_Maps
188+ new Ada. Containers.Hashed_Maps
179189 (Key_Type => TSSL.gnutls_datum_t,
180190 Element_Type => Session_Element,
181191 Hash => Hash,
182192 Equivalent_Keys => Equal);
183193
184194 package Time_Set is
185- new Containers.Ordered_Maps
195+ new Ada. Containers.Ordered_Maps
186196 (Key_Type => Calendar.Time,
187197 Element_Type => TSSL.gnutls_datum_t,
188198 " <" => Calendar." <" ,
@@ -235,6 +245,7 @@ package body AWS.Net.SSL is
235245 CRL_File : C.Strings.chars_ptr := C.Strings.Null_Ptr;
236246 CRL_Semaphore : Utils.Semaphore;
237247 CRL_Time_Stamp : Calendar.Time := Utils.AWS_Epoch;
248+ ALPN : SV.Vector;
238249 end record ;
239250
240251 procedure Initialize
@@ -284,7 +295,8 @@ package body AWS.Net.SSL is
284295 Certificate_Required : Boolean;
285296 Trusted_CA_Filename : String;
286297 CRL_Filename : String;
287- Session_Cache_Size : Natural);
298+ Session_Cache_Size : Natural;
299+ ALPN : SV.Vector);
288300
289301 private
290302 Done : Boolean := False;
@@ -445,6 +457,68 @@ package body AWS.Net.SSL is
445457 (Host, (new PCert_Array'(Load_PCert_List (4 )), TLS_PK));
446458 end Add_Host_Certificate ;
447459
460+ -- ------------
461+ -- ALPN_Get --
462+ -- ------------
463+
464+ function ALPN_Get (Socket : Socket_Type) return String is
465+ use type System.Address;
466+ Datum : aliased TSSL.gnutls_datum_t;
467+ Code : constant C.int :=
468+ TSSL.gnutls_alpn_get_selected_protocol
469+ (Socket.SSL, Datum'Access );
470+ begin
471+ if Code = TSSL.GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE then
472+ Datum.data := System.Null_Address;
473+ else
474+ Check_Error_Code (Code);
475+ end if ;
476+
477+ if Datum.data = System.Null_Address then
478+ return " " ;
479+ end if ;
480+
481+ return To_String (Datum);
482+ end ALPN_Get ;
483+
484+ -- ------------
485+ -- ALPN_Set --
486+ -- ------------
487+
488+ procedure ALPN_Set (Socket : Socket_Type) is
489+ type Datum_List is
490+ array (1 .. Natural (Socket.Config.ALPN.Length)) of
491+ aliased TSSL.gnutls_datum_t
492+ with Convention => C;
493+
494+ type Datum_List_Access is access all Datum_List;
495+
496+ function To_Datum_Access is new Ada.Unchecked_Conversion
497+ (Datum_List_Access, TSSL.a_gnutls_datum_t);
498+
499+ Datums : aliased Datum_List;
500+
501+ begin
502+ for J in Datums'Range loop
503+ Datums (J).data := Socket.Config.ALPN (J).Element.all 'Address;
504+ Datums (J).size := Socket.Config.ALPN (J).Element'Length;
505+ end loop ;
506+
507+ Check_Error_Code
508+ (TSSL.gnutls_alpn_set_protocols
509+ (Socket.SSL, To_Datum_Access (Datums'Access ), Datums'Length,
510+ flags => 0 ));
511+ end ALPN_Set ;
512+
513+ -- ------------
514+ -- ALPN_Set --
515+ -- ------------
516+
517+ procedure ALPN_Set (Config : SSL.Config; Protocols : SV.Vector) is
518+ begin
519+ Config.ALPN := Protocols;
520+ end ALPN_Set ;
521+
448522 -- ----------------
449523 -- Check_Config --
450524 -- ----------------
@@ -742,9 +816,11 @@ package body AWS.Net.SSL is
742816 Certificate_Required : Boolean;
743817 Trusted_CA_Filename : String;
744818 CRL_Filename : String;
745- Session_Cache_Size : Natural) is
819+ Session_Cache_Size : Natural;
820+ ALPN : SV.Vector) is
746821 begin
747822 if not Done then
823+ Default_Config.ALPN := ALPN;
748824 Initialize
749825 (Default_Config,
750826 Certificate_Filename, Security_Mode, Priorities,
@@ -1029,14 +1105,9 @@ package body AWS.Net.SSL is
10291105 -- --------
10301106
10311107 function Hash
1032- (Item : TSSL.gnutls_datum_t) return Containers.Hash_Type
1033- is
1034- type String_Access is access all String (Positive);
1035- function To_Access is
1036- new Unchecked_Conversion (TSSL.a_unsigned_char_t, String_Access);
1108+ (Item : TSSL.gnutls_datum_t) return Ada.Containers.Hash_Type is
10371109 begin
1038- return Strings.Hash
1039- (To_Access (Item.data) (1 .. Natural (Item.size)));
1110+ return Strings.Hash (To_String (Item));
10401111 end Hash ;
10411112
10421113 -- ---------
@@ -1073,20 +1144,23 @@ package body AWS.Net.SSL is
10731144 procedure Initialize
10741145 (Config : in out SSL.Config;
10751146 Certificate_Filename : String;
1076- Security_Mode : Method := TLS;
1077- Priorities : String := " " ;
1078- Ticket_Support : Boolean := False;
1079- Key_Filename : String := " " ;
1080- Exchange_Certificate : Boolean := False;
1081- Certificate_Required : Boolean := False;
1082- Trusted_CA_Filename : String := " " ;
1083- CRL_Filename : String := " " ;
1084- Session_Cache_Size : Natural := 16#4000# ) is
1147+ Security_Mode : Method := TLS;
1148+ Priorities : String := " " ;
1149+ Ticket_Support : Boolean := False;
1150+ Key_Filename : String := " " ;
1151+ Exchange_Certificate : Boolean := False;
1152+ Certificate_Required : Boolean := False;
1153+ Trusted_CA_Filename : String := " " ;
1154+ CRL_Filename : String := " " ;
1155+ Session_Cache_Size : Natural := 16#4000# ;
1156+ ALPN : SV.Vector := SV.Empty_Vector) is
10851157 begin
10861158 if Config = null then
10871159 Config := new TS_SSL;
10881160 end if ;
10891161
1162+ Config.ALPN := ALPN;
1163+
10901164 Initialize
10911165 (Config.all ,
10921166 Certificate_Filename => Certificate_Filename,
@@ -1271,20 +1345,21 @@ package body AWS.Net.SSL is
12711345
12721346 procedure Initialize_Default_Config
12731347 (Certificate_Filename : String;
1274- Security_Mode : Method := TLS;
1275- Priorities : String := " " ;
1276- Ticket_Support : Boolean := False;
1277- Key_Filename : String := " " ;
1278- Exchange_Certificate : Boolean := False;
1279- Certificate_Required : Boolean := False;
1280- Trusted_CA_Filename : String := " " ;
1281- CRL_Filename : String := " " ;
1282- Session_Cache_Size : Natural := 16#4000# ) is
1348+ Security_Mode : Method := TLS;
1349+ Priorities : String := " " ;
1350+ Ticket_Support : Boolean := False;
1351+ Key_Filename : String := " " ;
1352+ Exchange_Certificate : Boolean := False;
1353+ Certificate_Required : Boolean := False;
1354+ Trusted_CA_Filename : String := " " ;
1355+ CRL_Filename : String := " " ;
1356+ Session_Cache_Size : Natural := 16#4000# ;
1357+ ALPN : SV.Vector := SV.Empty_Vector) is
12831358 begin
12841359 Default_Config_Sync.Initialize
12851360 (Certificate_Filename, Security_Mode, Priorities, Ticket_Support,
12861361 Key_Filename, Exchange_Certificate, Certificate_Required,
1287- Trusted_CA_Filename, CRL_Filename, Session_Cache_Size);
1362+ Trusted_CA_Filename, CRL_Filename, Session_Cache_Size, ALPN );
12881363 end Initialize_Default_Config ;
12891364
12901365 procedure Initialize_Default_Config is
@@ -1993,6 +2068,8 @@ package body AWS.Net.SSL is
19932068 -- Retrieve_Certificate for client.
19942069
19952070 TSSL.gnutls_session_set_ptr (Socket.SSL, Socket.Config.all 'Address);
2071+
2072+ ALPN_Set (Socket);
19962073 end Session_Transport ;
19972074
19982075 -- --------------
0 commit comments