Skip to content

Instantly share code, notes, and snippets.

@W00t3k
Forked from mattifestation/GetSTLCertHashes.ps1
Created January 19, 2018 16:47
Show Gist options
  • Save W00t3k/e89b8c40377befa65b1a563b7aa6da07 to your computer and use it in GitHub Desktop.
Save W00t3k/e89b8c40377befa65b1a563b7aa6da07 to your computer and use it in GitHub Desktop.
A crude authroot.stl parser
# 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