Created
December 20, 2017 22:52
-
-
Save mattifestation/c712e525109f786fbaf6ed576b8d2832 to your computer and use it in GitHub Desktop.
A crude authroot.stl parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# http://www.bouncycastle.org/csharp/ | |
$BouncyCastlePath = 'Path\To\BouncyCastle.Crypto.dll' | |
$BouncyCastle = Add-Type -Path $BouncyCastlePath -PassThru | |
function Get-TrustedRootCertificateHash { | |
[OutputType([String])] | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('FullName')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Path | |
) | |
# Note: you should always be able to download the latest authroot.stl from: | |
# http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab | |
# You could then download each certificate directly from Microsoft for comparison: e.g. | |
# http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/CDD4EEAE6000AC7F40C3802C171E30148030C072.crt | |
# Where CDD4EEAE6000AC7F40C3802C171E30148030C072 is one of the present certificate hash values | |
# Thanks to http://unmitigatedrisk.com/?p=259 for this information. | |
$FullPath = Resolve-Path -Path $Path | |
$FileInfo = Get-Item -Path $FullPath | |
if ($FileInfo.Name -ne 'authroot.stl') { | |
Write-Error "You must specify the following filename: authroot.stl." | |
return | |
} | |
$FileStream = [IO.File]::OpenRead($FullPath) | |
if (-not $FileStream) { continue } | |
$ASN1InputStream = New-Object -TypeName Org.BouncyCastle.Asn1.Asn1InputStream -ArgumentList $FileStream | |
$ASN1Object = $ASN1InputStream.ReadObject() | |
if (-not $ASN1Object) { | |
Write-Error "$FullPath is not ASN.1 encoded data." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if (($ASN1Object.Count -lt 2)) { | |
Write-Error "$($FullPath): ASN.1 encoded data does not hold enough information to hold PKCS#7 ASN.1 SignedData (1.2.840.113549.1.7.2)." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if (-not ($ASN1Object[0] -is [Org.BouncyCastle.Asn1.DerObjectIdentifier])) { | |
Write-Error "$($FullPath): ASN.1 encoded data is not PKCS#7 ASN.1 SignedData (1.2.840.113549.1.7.2). It must contain an OID datatype." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if ($ASN1Object[0].Id -ne '1.2.840.113549.1.7.2') { | |
Write-Error "$($FullPath): ASN.1 encoded data is not PKCS#7 ASN.1 SignedData. Its OID must be 1.2.840.113549.1.7.2." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if (-not ($ASN1Object[1] -is [Org.BouncyCastle.Asn1.DerTaggedObject])) { | |
Write-Error "$($FullPath): ASN.1 encoded data is not PKCS#7 ASN.1 SignedData (1.2.840.113549.1.7.2). It must contain a context-specific tag." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if (($ASN1Object[1].TagNo -ne 0) -or ($ASN1Object[1].IsEmpty())) { | |
Write-Error "$($FullPath): ASN.1 encoded data is not PKCS#7 ASN.1 SignedData (1.2.840.113549.1.7.2). It must contain a non-empty context-specific tag ([0])." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
$SignedDataObject = $ASN1Object[1].GetObject() | |
# Check that the sequence count is at least 3: version, hash algorithm, and CTL entry list | |
if ($SignedDataObject.Count -lt 3) { | |
Write-Error "$($FullPath): Certificate trust list data must have at least three sections representing the version, hash algorithm, and CTL entries." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if ((-not ($SignedDataObject[0] -is [Org.BouncyCastle.Asn1.DerInteger])) -or ($SignedDataObject[0].Value.IntValue -ne 1)) { | |
Write-Error "$($FullPath): Inproper version field. The version field must be set to 1." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
$SHA1Algorithm = '1.3.14.3.2.26' | |
if ($SignedDataObject[1].GetObjectAt(0)[0].Id -ne $SHA1Algorithm) { | |
Write-Error "$($FullPath): Hashing algorithm is not set to SHA1 ($SHA1Algorithm)." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if ($SignedDataObject[2][0].Id -ne '1.3.6.1.4.1.311.10.1') { | |
Write-Error "$($FullPath): A valid certificate trust list (1.3.6.1.4.1.311.10.1) is not present." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
$CTLSequence = $SignedDataObject[2][1].GetObject() | |
if ($CTLSequence[0].Id -ne '1.3.6.1.4.1.311.10.3.9') { | |
Write-Error "$($FullPath): CTL does not have a Root List Signer tag (1.3.6.1.4.1.311.10.3.9)." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
# Skip over the sequence number and update times | |
# The SHA1 algorithm identifier should repeat here. | |
if ($CTLSequence[3][0].Id -ne $SHA1Algorithm) { | |
Write-Error "$($FullPath): Hashing algorithm is not set to SHA1 ($SHA1Algorithm)." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
if ((-not ($CTLSequence[4] -is [Org.BouncyCastle.Asn1.DerSequence])) -or ($CTLSequence.Count -lt 1)) { | |
Write-Error "$($FullPath): No CTL entries are present." | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
return | |
} | |
$CTLSequence[4] | ForEach-Object { | |
$_[0][0].ToString().TrimStart('#').ToUpper() | |
} | |
$ASN1InputStream.Close() | |
$FileStream.Close() | |
} | |
Get-TrustedRootCertificateHash -Path authroot.stl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment