------------------------------------------------------------------------------ -- Ada Web Server -- -- -- -- Copyright (C) 2013, AdaCore -- -- -- -- This is free software; you can redistribute it and/or modify it -- -- under terms of the GNU General Public License as published by the -- -- Free Software Foundation; either version 3, or (at your option) any -- -- later version. This software is distributed in the hope that it will -- -- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -- -- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- -- General Public License for more details. -- -- -- -- You should have received a copy of the GNU General Public License -- -- distributed with this software; see file COPYING3. If not, go -- -- to http://www.gnu.org/licenses for a complete copy of the license. -- ------------------------------------------------------------------------------ -- This must be the exact same test than tgetparam. The only difference is -- that it uses HTTPS protocol. We test that output is the same as the non -- secure version. with Ada.Calendar.Formatting; with Ada.Calendar.Time_Zones; with Ada.Exceptions; with Ada.Text_IO; with AWS.Client; with AWS.Config.Set; with AWS.Messages; with AWS.MIME; with AWS.Net.SSL.Certificate; with AWS.Parameters; with AWS.Response; with AWS.Server.Status; with AWS.Status; with AWS.URL; procedure Cert_Status is use Ada; use Ada.Text_IO; use AWS; function CB (Request : Status.Data) return Response.Data; procedure Display_Certificate (Socket : Net.SSL.Socket_Type); procedure Display_Certificate (Cert : Net.SSL.Certificate.Object); function Image (DT : Calendar.Time) return String; -------- -- CB -- -------- function CB (Request : Status.Data) return Response.Data is URI : constant String := Status.URI (Request); Sock : constant Net.Socket_Type'Class := Status.Socket (Request); begin if URI = "/simple" then New_Line; Put_Line ("Client certificate as received by the server:"); Display_Certificate (Net.SSL.Socket_Type (Sock)); New_Line; return Response.Build (MIME.Text_HTML, "simple ok"); else Put_Line ("Unknown URI " & URI); return Response.Build (MIME.Text_HTML, URI & " not found", Messages.S404); end if; end CB; ------------------------- -- Display_Certificate -- ------------------------- procedure Display_Certificate (Cert : Net.SSL.Certificate.Object) is use type Net.SSL.Certificate.Object; begin if Cert = Net.SSL.Certificate.Undefined then Put_Line ("No certificate."); else Put_Line ("Subject : " & Net.SSL.Certificate.Subject (Cert)); Put_Line ("Issuer : " & Net.SSL.Certificate.Issuer (Cert)); Put_Line ("Activation : " & Image (Net.SSL.Certificate.Activation_Time (Cert))); Put_Line ("Expiration : " & Image (Net.SSL.Certificate.Expiration_Time (Cert))); Put_Line ("Verified : " & Boolean'Image (Net.SSL.Certificate.Verified (Cert))); end if; end Display_Certificate; procedure Display_Certificate (Socket : Net.SSL.Socket_Type) is Cert : constant Net.SSL.Certificate.Object := Net.SSL.Certificate.Get (Socket); begin Display_Certificate (Cert); New_Line; end Display_Certificate; ----------- -- Image -- ----------- function Image (DT : Calendar.Time) return String is begin return Calendar.Formatting.Image (DT, Time_Zone => Calendar.Time_Zones.UTC_Time_Offset (DT)); end Image; ------------- -- Request -- ------------- procedure Request (URL : String) is O_URL : constant AWS.URL.Object := AWS.URL.Parse (URL); R : Response.Data; C : Client.HTTP_Connection; Cert : Net.SSL.Certificate.Object; begin Client.Create (C, URL, Certificate => "aws-client-expired.pem"); begin Cert := Client.Get_Certificate (C); exception when others => Put_Line ("Client connection closed by peer."); return; end; New_Line; Put_Line ("Server certificate as received by the client:"); Display_Certificate (Cert); New_Line; Client.Get (C, R, AWS.URL.Abs_Path (O_URL)); Put_Line ("=> " & Response.Message_Body (R)); New_Line; Client.Close (C); end Request; ----------------- -- Verify_Cert -- ----------------- function Verify_Cert (Cert : Net.SSL.Certificate.Object) return Boolean is use type Calendar.Time; begin Text_IO.Put_Line ("Client certificate from verify routine:"); Display_Certificate (Cert); Put_Line ("Status : " & Long_Integer'Image (Net.SSL.Certificate.Status (Cert))); Put_Line ("Message : " & Net.SSL.Certificate.Status_Message (Cert)); New_Line; -- Return verified status from the SSL layer return Net.SSL.Certificate.Verified (Cert); end Verify_Cert; HTTP : Server.HTTP; Conf : Config.Object; --------------------- -- Set_Certificate -- --------------------- procedure Set_Certificate (Index : Character) is SSL : Net.SSL.Config; begin -- SSL config, no trusted CA Net.SSL.Initialize (SSL, Certificate_Filename => "aws-server" & Index & ".crt", Key_Filename => "aws-server" & Index & ".key", Exchange_Certificate => True, Certificate_Required => True, Trusted_CA_Filename => "CA-clt.crt"); Net.SSL.Certificate.Set_Verify_Callback (SSL, Verify_Cert'Unrestricted_Access); Server.Set_SSL_Config (HTTP, SSL); end Set_Certificate; begin Put_Line ("Start main, wait for server to start..."); Config.Set.Server_Host (Conf, "localhost"); Config.Set.Server_Port (Conf, 0); Config.Set.Max_Connection (Conf, 5); Config.Set.Security (Conf, True); Set_Certificate ('1'); -- Run Server.Start (HTTP, CB'Unrestricted_Access, Conf); Put_Line ("Server started"); New_Line; Request (AWS.Server.Status.Local_URL (HTTP) & "/simple"); Set_Certificate ('2'); Request (AWS.Server.Status.Local_URL (HTTP) & "/simple"); Server.Shutdown (HTTP); exception when E : others => Put_Line ("Main Error " & Exceptions.Exception_Information (E)); Server.Shutdown (HTTP); end Cert_Status;