# encoding: ascii
# api: csharp
# title: Get-Cert
# description: A script to retrieve the SSL Certificate used by a remote host … demonstrates using Invoke-Inline to compile C# code, and handling the RemoteCertificateValidationCallback to override the normal security policy …
# version: 0.1
# author: Joel Bennett
# license: CC0
# x-poshcode-id: 69
# x-archived: 2017-04-30T12:50:10
# x-published: 2008-12-09T11:37:00
#
#
$UsingStatements = @"
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
"@

$GetCert = @"
RemoteCertificateValidationCallback callback = delegate(
	object sender, 
	X509Certificate cert,
	X509Chain chain, 
	SslPolicyErrors sslError)
{
	X509Certificate2 x509 = new X509Certificate2(cert);
	result.Add(x509);

	// Print to console information contained in the certificate.
	Console.WriteLine("Subject: {0}", x509.Subject);
	Console.WriteLine("Issuer: {0}", x509.Issuer);
	Console.WriteLine("Version: {0}", x509.Version);
	Console.WriteLine("Valid Date: {0}", x509.NotBefore);
	Console.WriteLine("Expiry Date: {0}", x509.NotAfter);
	Console.WriteLine("Thumbprint: {0}", x509.Thumbprint);
	Console.WriteLine("Serial Number: {0}", x509.SerialNumber);
	Console.WriteLine("Friendly Name: {0}", x509.PublicKey.Oid.FriendlyName);
	Console.WriteLine("Public Key Format: {0}", x509.PublicKey.EncodedKeyValue.Format(true));
	Console.WriteLine("Raw Data Length: {0}", x509.RawData.Length);
//	Console.WriteLine("Certificate to string: {0}", x509.ToString(true));
//	Console.WriteLine("Certificate to XML String: {0}", x509.PublicKey.Key.ToXmlString(false));

	Console.WriteLine("Added a certificate. Total: " + result.Count );
	
	if (sslError != SslPolicyErrors.None) {
		Console.WriteLine("Certificate error: " + sslError);
	}
		
	return false; // always stop, we have what we need
};

foreach(string serverName in args) { 
	Console.WriteLine("\n\nFetching SSL cert for {0}\n", serverName);
	// int secondArg = (int) ((object[]) arg)[1]; 


	// Create a TCP/IP client socket to a machine name
	TcpClient client = new TcpClient(serverName,443);
	// Create an SSL stream that will close the client's stream.
	SslStream sslStream = new SslStream( client.GetStream(), false, callback, null );
	
	try 
	{
		sslStream.AuthenticateAsClient(serverName);
	} 
	catch (AuthenticationException e)
	{
		Console.WriteLine("Exception: {0}", e.Message);
		if (e.InnerException != null)
		{
			Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
		}
		Console.WriteLine ("Authentication failed - closing the connection.");
	}
	client.Close();
}
"@

.\Invoke-Inline $UsingStatements,$GetCert $args -ref @()
