Using .NET System.Security.Cryptography.X509Certificates.X509Certificate from ASP

More info about System.Security.Cryptography.X509Certificates.X509Certificate class at MSDN Library.

Output


Sources

/dot-NET/System.Security.Cryptography.X509Certificates.X509Certificate.asp

<%@ language="VBScript" %>
<!--#include virtual="/lib/unit-tests.asp"-->
<!--#include file="helpers.asp"-->
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link href="/lib/unit-tests.css" rel="stylesheet" type="text/css" />
<h1>Using .NET System.Security.Cryptography.X509Certificates.X509Certificate from ASP</h1>
<p>
	More info about System.Security.Cryptography.X509Certificates.X509Certificate class at <a href="https://msdn.microsoft.com/en-us/library/System.Security.Cryptography.X509Certificates.X509Certificate.aspx">MSDN Library</a>.
</p>
<h2>Output</h2>
<div class="code"><pre><%
 
' PS> new-object System.Security.Cryptography.X509Certificates.X509Certificate | gm | format-list > System.Security.Cryptography.X509Certificates.X509Certificate.txt
 
'System.Security.Cryptography.X509Certificates.X509Certificate
 
'	bool Equals(System.Object obj),
'	bool Equals(System.Security.Cryptography.X509Certificates.X509Certificate other)
 
'	byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType),
'	byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string password),
'	byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, securestring password)
 
'	byte[] GetCertHash()
 
'	string GetCertHashString()
 
'	string GetEffectiveDateString()
 
'	string GetExpirationDateString()
 
'	string GetFormat()
 
'	int GetHashCode()
 
'	string GetIssuerName()
 
'	string GetKeyAlgorithm()
 
'	byte[] GetKeyAlgorithmParameters()
 
'	string GetKeyAlgorithmParametersString()
 
'	string GetName()
 
'	void ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
 
'	byte[] GetPublicKey()
 
'	string GetPublicKeyString()
 
'	byte[] GetRawCertData()
 
'	string GetRawCertDataString()
 
'	byte[] GetSerialNumber()
 
'	string GetSerialNumberString()
 
'	type GetType()
 
'	void Import(byte[] rawData),
'	void Import(byte[] rawData, string password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags),
'	void Import(byte[] rawData, securestring password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags),
'	void Import(string fileName),
'	void Import(string fileName, string password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags),
'	void Import(string fileName, securestring password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags)
 
'	void IDeserializationCallback.OnDeserialization(System.Object sender)
 
'	void Reset()
 
'	string ToString(),
'	string ToString(bool fVerbose)
 
'	System.IntPtr Handle {get;}
 
'	string Issuer {get;}
 
'	string Subject {get;}
 
with Server.createObject("System.Security.Cryptography.X509Certificates.X509Certificate")
end with
 
%></pre></div>
<hr />
<h2>Sources</h2>
<h3><%= Request.ServerVariables("SCRIPT_NAME") %></h3>
<div class="code"><%= geshify( loadTextFile( Server.mapPath( Request.ServerVariables("SCRIPT_NAME") ) ), "asp" ) %></div>
<h3>helpers.asp</h3>
<div class="code"><%= geshify( loadTextFile( Server.mapPath("helpers.asp") ), "asp" ) %></div>
 
 

helpers.asp

<script language="VBScript" runat="Server">
 
function strwrap(byVal w, byVal n, byVal break)
	dim i, iK
	iK = int(len(w)/n)
	with Server.createObject("System.Text.StringBuilder")
		for i = 0 to iK
			.append_3 break & mid(w, i * n + 1, n)
		next
		strwrap = mid(.toString(), len(break) + 1)
	end with
end function
 
function load_text_file(byVal path, byVal charset)
	with Server.createObject("ADODB.Stream")
		.type = adTypeText
		.mode = adModeReadWrite
		.charset = charset
		.open()
		.loadFromFile(path)
		load_text_file = .readText()
		.close()
	end with
end function
 
sub save_text_file(byVal path, byVal value, byVal charset)
	with Server.createObject("ADODB.Stream")
		.type = adTypeText
		.mode = adModeReadWrite
		.charset = charset
		.open()
		.writeText value
		.position = 0
		.saveToFile path, adSaveCreateOverwrite
		.close()
	end with
end sub
 
function load_binary_file(byVal path)
	with Server.createObject("ADODB.Stream")
		.type = adTypeBinary
		.mode = adModeReadWrite
		.open()
		.loadFromFile(path)
		load_binary_file = .read()
		.close()
	end with
end function
 
sub save_binary_file(byVal path, byRef bytes)
	with Server.createObject("ADODB.Stream")
		.type = adTypeBinary
		.mode = adModeReadWrite
		.open()
		.write bytes
		.position = 0
		.saveToFile path, adSaveCreateOverwrite
		.close()
	end with
end sub
 
function get_bit_mask(byVal bit)
	if bit > 32 then
		Err.raise 6, typename(Me) & " runtime error", "Overflow. Given bit is too high."
	elseif bit < 32 then
		get_bit_mask = clng( 2 ^ ( bit - 1 ) )
	else
		' 10000000 00000000 00000000 00000000
		' If the high bit is one then the signed interpretation is equal to the unsigned interpretation minus 2^32
		get_bit_mask = clng( &H80000000 )' 32 is the sign bit
	end if
end function
 
function decimal_to_bitstr(byVal d)
	dim bits, a, i
	select case vartype(d)
		case vbLong
			bits = 32
		case vbInteger
			bits = 16
		case vbByte
			bits = 8
		case else
			Err.raise 13, typename(Me) & " runtime error", "Type mismatch. Conversion cannot be performed."
	end select
	redim a(bits)
	for i = bits to 1 step -1
		if d and get_bit_mask(i) then
			a(i) = 1
		else
			a(i) = 0
		end if
	next
	decimal_to_bitstr = strReverse( join( a, "" ) )
end function
 
function bitstr_to_decimal(byVal bits)
	dim binary, K, i
	bits = replace(bits, " ", "")
	binary = trim( right( bits, len(bits) - instr( bits, 1 ) + 1 ) )
	K = len(binary)
	if K > 32 then Err.raise 6, typename(Me) & " runtime error", "Overflow. Given bits is too high."
	for i = 1 to len(binary)
		select case mid(binary, i, 1)
			case "1"
				bitstr_to_decimal = bitstr_to_decimal or get_bit_mask( K - i + 1 )
			case "0"
				' pass
			case else
				Err.raise 13, typename(Me) & " runtime error", "Type mismatch. Bits should contain only 1 and 0."
		end select
	next
end function
 
function bytes_to_unicode(byRef bytes)
	with Server.createObject("System.Text.UnicodeEncoding")
		bytes_to_unicode = .getString( (bytes) )
	end with
end function
 
function unicode_to_bytes(byVal unicode)
	with Server.createObject("System.Text.UnicodeEncoding")
		unicode_to_bytes = .getBytes_4(unicode)
	end with
end function
 
function bytes_to_utf8(byRef bytes)
	with Server.createObject("System.Text.UTF8Encoding")
		bytes_to_utf8 = .getString( (bytes) )
	end with
end function
 
function utf8_to_bytes(byVal utf8)
	with Server.createObject("System.Text.UTF8Encoding")
		utf8_to_bytes = .getBytes_4(utf8)
	end with
end function
 
function bytes_to_ascii(byRef bytes)
	with Server.createObject("System.Text.ASCIIEncoding")
		bytes_to_ascii = .getString( (bytes) )
	end with
end function
 
function ascii_to_bytes(byVal ascii)
	with Server.createObject("System.Text.ASCIIEncoding")
		ascii_to_bytes = .getBytes_4(ascii)
	end with
end function
 
'Data Type Mapping
'-----------------
'VT_BSTR   	 string
'VT_BSTR   	 number
'VT_I4     	 Int
'VT_CY     	 Fixed.14.4
'VT_BOOL   	 Boolean
'VT_DATE   	 dateTime
'VT_DATE   	 dateTime.tz
'VT_DATE   	 Date
'VT_DATE   	 Time
'VT_DATE   	 Time.tz
'VT_I1     	 i1 byte
'VT_I2     	 i2
'VT_I4     	 i4, int
'VT_UI1    	 ui1
'VT_UI2    	 ui2
'VT_UI4    	 ui4
'VT_FLOAT  	 r4
'VT_DOUBLE 	 r8, float
'VT_BSTR   	 uuid
'VT_ARRAY  	 bin.hex
'VT_ARRAY  	 bin.base64
 
' MORE: <https://msdn.microsoft.com/en-us/library/ms762308%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396>
 
function bytes_to_base64(byRef bytes)
	with Server.createObject("MSXML2.DOMDocument.6.0")
		with .createElement("base64")
			.dataType = "bin.base64"
			.nodeTypedValue = bytes
			bytes_to_base64 = replace( .text, vbLF, "" )
		end with
	end with
end function
 
function base64_to_bytes(byVal base64)
	with Server.createObject("MSXML2.DOMDocument.6.0")
		with .createElement("base64")
			.dataType = "bin.base64"
			.text = base64
			base64_to_bytes = .nodeTypedValue
		end with
	end with
end function
 
function bytes_to_hex(byRef bytes)
	with Server.createObject("MSXML2.DOMDocument.6.0")
		with .createElement("hex")
			.dataType = "bin.hex"
			.nodeTypedValue = bytes
			bytes_to_hex = .text
		end with
	end with
end function
 
function hex_to_bytes(byVal hex)
	with Server.createObject("MSXML2.DOMDocument.6.0")
		with .createElement("hex")
			.dataType = "bin.hex"
			.text = hex
			hex_to_bytes = .nodeTypedValue
		end with
	end with
end function
 
' Distinguished Encoding Rules <https://msdn.microsoft.com/en-us/library/windows/desktop/dd408078(v=vs.85).aspx>
 
function pem_to_der(byVal kind, byVal ascii)
	dim header, footer
	header = "-----BEGIN " & kind & "-----"
	footer = "-----END " & kind & "-----"
 
	dim p0, pf, base64
	p0 = instr( 1, ascii, header, vbTextCompare) + len(header)
	pf = instr(p0, ascii, footer, vbTextCompare)
 
	base64 = mid( ascii, p0, ( pf - p0 ) )
	pem_to_der = base64_to_bytes(base64)
end function
 
function der_to_pem(byVal kind, byRef bytes)
	dim header, footer
	header = "-----BEGIN " & kind & "-----"
	footer = "-----END " & kind & "-----"
	der_to_pem = join( array( _
		  header _
		, strwrap(bytes_to_base64(bytes), 64, vbLF) _
		, footer _
	), vbLF )
end function
 
function der_to_obj(byRef der)
	dim stream
	set stream = Server.createObject("ADODB.Stream")
	with stream
		.type = adTypeBinary
		.mode = adModeReadWrite
		.open()
		.write der
		.setEOS()
		set der_to_obj = tokenize_asn1(stream, 0, .size)
		.close()
	end with
	set stream = nothing
end function
 
function tokenize_asn1(byRef stream, byVal p0, byVal lBytes)
	dim B, hB
 
	stream.position = p0
	B  = stream.read(1)
	hB = bytes_to_hex(B)
 
	select case hB
		case "30"' SEQUENCE
			set tokenize_asn1 = tokenize_asn1_sequence(stream, p0, lBytes)
 
		case "06"' OBJECT_IDENTIFIER
			set tokenize_asn1 = tokenize_asn1_object_identifier(stream, p0, lBytes)
 
		case "05"' NULL
			set tokenize_asn1 = tokenize_asn1_null(stream, p0, lBytes)
 
		case "03"' BIT_STRING
			set tokenize_asn1 = tokenize_asn1_bit_string(stream, p0, lBytes)
 
		case "02"' INTEGER
			set tokenize_asn1 = tokenize_asn1_integer(stream, p0, lBytes)
 
		case else
			set tokenize_asn1 = JSON.parse("{}")
			tokenize_asn1.set "tag", "UNKNOWN or UNIMPLEMENTED TAG 0x" & hB
	end select
end function
 
function tokenize_asn1_sequence(byRef stream, byVal p0, byVal lBytes)
	dim B, hB, lB, sz _
	  , entry_p0
 
	set tokenize_asn1_sequence = JSON.parse("{ ""tag"": ""SEQUENCE"", ""data"": [] }")
 
	' skip tag byte
	stream.position = p0 + 1
 
	' skip length bytes
	B  = stream.read(1)
	hB = bytes_to_hex(B)
	sz = clng( "&H" & hB )
	if( sz >= 128 ) then _
		stream.position = stream.position + ( sz - 128 )
 
	' get entries
	while not stream.EOS and stream.position <= p0 + lBytes
		' save entry position
		entry_p0 = stream.position
 
		' skip tag byte
		stream.position = stream.position + 1
 
		' get length
		B  = stream.read(1)
		hB = bytes_to_hex(B)
		sz = clng( "&H" & hB )
		if( sz >= 128 ) then
			B  = stream.read( sz - 128 )
			hB = bytes_to_hex(B)
			sz = clng( "&H" & hB )
		end if
 
		tokenize_asn1_sequence.data.push( tokenize_asn1( stream, entry_p0, sz ) )
	wend
end function
 
function tokenize_asn1_object_identifier(byRef stream, byVal p0, byVal lBytes)
	dim B, hB, sz, bytes, byt, bitstr, oid
 
	set tokenize_asn1_object_identifier = JSON.parse("{ ""tag"": ""OBJECT_IDENTIFIER"", ""data"": """" }")
 
	' skip tag byte
	stream.position = p0 + 1
 
	' get length
	B  = stream.read(1)
	hB = bytes_to_hex(B)
	sz = clng( "&H" & hB )
	if( sz >= 128 ) then
		B  = stream.read( sz - 128 )
		hB = bytes_to_hex(B)
		sz = clng( "&H" & hB )
	end if
 
	' evaluate bytes
	bytes = stream.read(sz)
	with Server.createObject("ADODB.Stream")
		.type = adTypeBinary
		.mode = adModeReadWrite
		.open()
		.write bytes
		.setEOS
 
		' first and second nodes
		.position = 0
		B = .read(1)
		byt = cbyte( "&H" & bytes_to_hex(B) )
		oid = int( byt / 40 ) & "." & ( byt mod 40 )
 
		bitstr = ""
		while not .EOS
			B  = .read(1)
			hB = bytes_to_hex(B)
			byt = cbyte( "&H" & hB )
			if( byt < 128 ) then
				oid = oid & "." & bitstr_to_decimal( bitstr & mid( decimal_to_bitstr(byt), 2 ) )
				bitstr = ""
			else
				bitstr = bitstr & mid( decimal_to_bitstr(byt), 2 )
			end if
		wend
 
		.close()
	end with
 
	tokenize_asn1_object_identifier.set "data", oid
end function
 
function tokenize_asn1_null(byRef stream, byVal p0, byVal lBytes)
	set tokenize_asn1_null = JSON.parse("{ ""tag"": ""NULL"" }")
 
	' skip tag and length bytes
	stream.position = p0 + 2
end function
 
function tokenize_asn1_bit_string(byRef stream, byVal p0, byVal lBytes)
	dim B, hB, lB, sz _
	  , entry_p0
 
	set tokenize_asn1_bit_string = JSON.parse("{ ""tag"": ""BIT_STRING"", ""data"": [] }")
 
	' skip tag byte
	stream.position = p0 + 1
 
	' skip length bytes
	B  = stream.read(1)
	hB = bytes_to_hex(B)
	sz = clng( "&H" & hB )
	if( sz >= 128 ) then _
		stream.position = stream.position + ( sz - 128 )
 
	' get unused bits
	B  = stream.read(1)
	lB = clng( "&H" & bytes_to_hex(B) )
 
	tokenize_asn1_bit_string.set "unused_bits", lB
 
	' get entries
	while not stream.EOS and stream.position <= p0 + lBytes
		' save entry position
		entry_p0 = stream.position
 
		' skip tag byte
		stream.position = stream.position + 1
 
		' get length
		B  = stream.read(1)
		hB = bytes_to_hex(B)
		sz = clng( "&H" & hB )
		if( sz >= 128 ) then
			B  = stream.read( sz - 128 )
			hB = bytes_to_hex(B)
			sz = clng( "&H" & hB )
		end if
 
		tokenize_asn1_bit_string.data.push( tokenize_asn1( stream, entry_p0, sz ) )
	wend
end function
 
function tokenize_asn1_integer(byRef stream, byVal p0, byVal lBytes)
	dim B, hB, sz
 
	set tokenize_asn1_integer = JSON.parse("{ ""tag"": ""INTEGER"", ""data"": ""bin.hex"" }")
 
	' skip tag byte
	stream.position = p0 + 1
 
	' get length
	B  = stream.read(1)
	hB = bytes_to_hex(B)
	sz = clng( "&H" & hB )
	if( sz >= 128 ) then
		B  = stream.read( sz - 128 )
		hB = bytes_to_hex(B)
		sz = clng( "&H" & hB )
	end if
 
	tokenize_asn1_integer.set "data", bytes_to_hex( stream.read(sz) )
end function
 
</script>