cscの作法 その207

# 概要
cscの作法、調べてみた。
サイトの証明書、叩いてみた。
sslstream使ってみた。

# サンプルコード

```

using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Text;

public class Program {
	private static void PrintCertificate(X509Certificate certificate) {
		Console.WriteLine("===========================================");
		Console.WriteLine("Subject={0}", certificate.Subject);
		Console.WriteLine("Issuer={0}", certificate.Issuer);
		Console.WriteLine("Format={0}", certificate.GetFormat());
		Console.WriteLine("ExpirationDate={0}", certificate.GetExpirationDateString());
		Console.WriteLine("EffectiveDate={0}", certificate.GetEffectiveDateString());
		Console.WriteLine("KeyAlgorithm={0}", certificate.GetKeyAlgorithm());
		Console.WriteLine("PublicKey={0}", certificate.GetPublicKeyString());
		Console.WriteLine("SerialNumber={0}", certificate.GetSerialNumberString());
		Console.WriteLine("===========================================");
	}
	private static Boolean RemoteCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
		PrintCertificate(certificate);
		if (sslPolicyErrors == SslPolicyErrors.None)
		{
			Console.WriteLine("サーバー証明書の検証に成功しました\n");
			return true;
		}
		else
		{
			if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
			{
				Console.WriteLine("ChainStatusが、空でない配列を返しました");
			}
			if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
			{
				Console.WriteLine("証明書名が不一致です");
			}
			if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
			{
				Console.WriteLine("証明書が利用できません");
			}
			return false;
		}
	}
	public static void Main() {
		String hostName = "google.com";
		Int32 port = 443;
		using (TcpClient client = new TcpClient())
		{
			IPAddress[] ipAddresses = Dns.GetHostAddresses(hostName);
			client.Connect(new IPEndPoint(ipAddresses[0], port));
			using (SslStream sslStream = new SslStream(client.GetStream(), false, RemoteCertificateValidationCallback))
			{
				sslStream.AuthenticateAsClient(hostName);
				Byte[] req = Encoding.ASCII.GetBytes(String.Format("GET / HTTP/1.0\r\nHost: {0}\r\n\r\n", hostName));
				sslStream.Write(req);
				sslStream.Flush();
				Byte[] res = new Byte[1024];
				Int32 n;
				while ( (n = sslStream.Read(res, 0, res.Length) ) > 0)
				{
					String s = Encoding.ASCII.GetString(res, 0, n);
					Console.WriteLine(s);
				}
			}
		}
	}
}

```

# 実行結果

```
>ssl4
===========================================
Subject=CN=*.google.com
Issuer=CN=GTS CA 1C3, O=Google Trust Services LLC, C=US
Format=X509
ExpirationDate=2022/08/29 17:29:45
EffectiveDate=2022/06/06 17:29:46
KeyAlgorithm=1.2.840.10045.2.1
PublicKey=0495DAEEDDFD96636B9E5D340384D2D1CE924A00BAA68EF50317E4F27C97DC39AAD327E9C2BDE4D63BB9B1721974BB6DF00BB34A1FC329222957A1D0A18911344C
SerialNumber=58ACE5940B417864129D531A39CB0067
===========================================
サーバー証明書の検証に成功しました

HTTP/1.0 301 Moved Permanently
Location: https://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Thu, 23 Jun 2022 01:13:05 GMT
Expires: Sat, 23 Jul 2022 01:13:05 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>






```


以上。