~nytpu/tlsada

134db3791ae3e412d0d4be7ae30b129c5b11d850 — cngimenez 1 year, 8 months ago 0a63fe0
Server_Example: Demonstrate reading of client certificates

Originally authored by: cngimenez <cnngimenez@disroot.org>
Cleaned up and slightly rewritten by: nytpu <alex@nytpu.com>
1 files changed, 33 insertions(+), 6 deletions(-)

M src/example/server_example.adb
M src/example/server_example.adb => src/example/server_example.adb +33 -6
@@ 8,6 8,7 @@
-- SPDX-License-Identifier: MPL-2.0
-- For more license details, see LICENSE or <https://www.mozilla.org/en-US/MPL/2.0/>.

with Ada.Calendar.Formatting;
with Ada.Directories;  use Ada.Directories;
with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Strings.Unbounded;  use Ada.Strings.Unbounded;


@@ 39,7 40,23 @@ procedure Server_Example is
	-- Variables --
	---------------

	Conf : TLS.Configure.Config;
	-- Server configuration values
	-- A server REQUIRES a Cert_File and Key_File to be specified
	Conf : constant TLS.Configure.Config := (
		Cert_File => To_Unbounded_String(Cert_File),
		Key_File => To_Unbounded_String(Key_File),
		-- For Gemini (and possibly even HTTP applications) you probably don't
		-- care about CA-certified client cert.
		Verify_Certs => False,
		Verify_Expirys => False,
		-- Do not *require* a client cert to even connect, however request one
		-- if the client has one to send.
		Verify_Client_Cert => TLS.Configure.Optional,
		-- Configuration options are sensible by default so we can leave the
		-- others alone
		others => <>
	);

	Address : Sock_Addr_Type;
	Server_Socket : Socket_Type;
	Server_TLS : aliased TLS.Contexts.Server.Server_Context;


@@ 59,9 76,6 @@ begin
	Listen_Socket(Server_Socket);

	-- Configure the server
	-- A server REQUIRES a Cert_File and Key_File to be specified
	Conf.Cert_File := To_Unbounded_String(Cert_File);
	Conf.Key_File := To_Unbounded_String(Key_File);
	Server_TLS.Configure(Conf);

	-- Accept incoming connections and write output.  If you were fancy you


@@ 71,6 85,7 @@ begin
		declare
			Connection_Socket : Socket_Type;
			Connection_TLS : aliased TLS.Contexts.Server.Server_Context;
			Cert_Info : TLS.Contexts.Certificate_Info;
		begin
			-- First accept the unencrypted connection.  If you allow
			-- unencrypted connections then do whatever you need to here to


@@ 81,6 96,19 @@ begin
			TLS.Contexts.Server.Accept_TLS(Server_TLS, Connection_Socket, Connection_TLS);

			Put_Line("Got connection from '" & Image(Address.Addr) & "'!");
			if Connection_TLS.Peer_Certificate_Provided then
				-- Building the *_Info structures are comparatively expensive
				-- operations, so you should save the values if you need them
				-- more than once or twice.
				Cert_Info := Connection_TLS.Get_Certificate_Info;
				Put_Line("Certificate provided:");
				Put_Line("  Hash: " & To_String(Cert_Info.Hash));
				Put_Line("  Issuer: " & To_String(Cert_Info.Issuer));
				Put_Line("  Subject: " & To_String(Cert_Info.Subject));
				Put_Line("  Expiry: " & Ada.Calendar.Formatting.Image(Cert_Info.Not_After));
			else
				Put_Line("No certificate provided by " & Image(Address.Addr));
			end if;

			-- Read request header (and discard).  Read/write work exactly the
			-- same as for Client_Contexts


@@ 98,8 126,7 @@ begin
				else
					String'Write(
						Connection_TLS'Access,
						"20 text/gemini;charset=utf-8" &
						ASCII.CR & ASCII.LF &
						"20 text/gemini;charset=utf-8" & ASCII.CR & ASCII.LF &
						"hello, world!" & ASCII.LF
					);
				end if;