var ( OidSpcIndirectDataContent = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 4} OidSpcStatementType = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 11} OidSpcSpOpusInfo = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 12} OidSpcPeImageData = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 15} OidSpcIndividualPurpose = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 21} OidSpcCabImageData = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 25} OidSpcSipInfo = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 30} OidSpcPageHashV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 3, 1} OidSpcPageHashV2 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 3, 2} OidSpcCabPageHash = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 5, 1} OidCertTrustList = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 1} OidCatalogList = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 12, 1, 1} OidCatalogListMember = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 12, 1, 2} OidCatalogListMemberV2 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 12, 1, 3} OidCatalogNameValue = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 12, 2, 1} OidCatalogMemberInfo = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 12, 2, 2} OidCatalogMemberInfoV2 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 12, 2, 3} SpcUUIDPageHashes = []byte{0xa6, 0xb5, 0x86, 0xd5, 0xb4, 0xa1, 0x24, 0x66, 0xae, 0x05, 0xa2, 0x17, 0xda, 0x8e, 0x60, 0xd6} // SIP or Subject Interface Package is an internal Microsoft API for // transforming arbitrary files into a digestible stream. These ClassIDs // are found in the indirect data section and identify the type of processor needed to validate the signature. // SIP related DLLs are registered at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllCreateIndirectData // although these particular ClassIDs do not seem to appear there. // Relevant DLLs include: WINTRUST.DLL, MSISIP.DLL, pwrshsip.dll SpcUUIDSipInfoMsi = []byte{0xf1, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} SpcUUIDSipInfoPs = []byte{0x1f, 0xcc, 0x3b, 0x60, 0x59, 0x4b, 0x08, 0x4e, 0xb7, 0x24, 0xd2, 0xc6, 0x29, 0x7e, 0xf3, 0x51} // This one is used in V1 security catalogs CryptSipCreateIndirectData = "{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" )
func AllSigStyles() []string
Return all supported PowerShell signature styles
func DigestMSI(cdf *comdoc.ComDoc, hash crypto.Hash, extended bool) (imprint, prehash []byte, err error)
Calculate the digest (imprint) of a MSI file. If extended is true then the MsiDigitalSignatureEx value is also hashed and returned.
func DigestMsiTar(r io.Reader, hash crypto.Hash, extended bool) ([]byte, error)
Digset a tarball produced by MsiToTar
func FixPEChecksum(f *os.File) error
func InsertMSISignature(cdf *comdoc.ComDoc, pkcs, exsig []byte) error
Add a signature blob to an open MSI file. The extended signature blob is added or updated if provided, or deleted if nil.
func MsiToTar(cdf *comdoc.ComDoc, w io.Writer) error
Convert MSI to a tar archive in a form that can be digested and signed as a stream
func NewPEChecksum(peStart int) hash.Hash
Hasher that calculates the undocumented, non-CRC checksum used in PE images. peStart is the offset found at 0x3c in the DOS header.
func PrehashMSI(cdf *comdoc.ComDoc, hash crypto.Hash) ([]byte, error)
Calculates the MsiDigitalSignatureEx blob for a MSI file
func SignCabImprint(ctx context.Context, digest *cabfile.CabinetDigest, cert *certloader.Certificate) (*binpatch.PatchSet, *pkcs9.TimestampedSignature, error)
Create the Authenticode structure for a CAB file signature using a previously-calculated digest (imprint).
func SignMSIImprint(ctx context.Context, digest []byte, hash crypto.Hash, cert *certloader.Certificate) (*pkcs9.TimestampedSignature, error)
Create the Authenticode structure for a MSI file signature using a previously-calculated digest (imprint).
func SignSip(ctx context.Context, imprint []byte, hash crypto.Hash, sipInfo SpcSipInfo, cert *certloader.Certificate) (*pkcs9.TimestampedSignature, error)
func VerifyPowershell(r io.ReadSeeker, style PsSigStyle, skipDigests bool) (*pkcs9.TimestampedSignature, error)
Verify a PowerShell script. The signature "style" must already have been determined by calling GetSigStyle
type CabSignature struct { pkcs9.TimestampedSignature Indirect *SpcIndirectDataContentPe HashFunc crypto.Hash PatchSet *binpatch.PatchSet }
func VerifyCab(f io.ReaderAt, skipDigests bool) (*CabSignature, error)
Extract and verify the signature of a CAB file. Does not check X509 chains.
type Catalog struct { Version int Hash crypto.Hash Sha1Entries, Sha2Entries []CertTrustEntry }
func NewCatalog(hash crypto.Hash) *Catalog
func (cat *Catalog) Add(indirect SpcIndirectDataContentPe) error
func (cat *Catalog) Marshal() ([]byte, error)
func (cat *Catalog) Sign(ctx context.Context, cert *certloader.Certificate) (*pkcs9.TimestampedSignature, error)
type CertTrustAttributes struct { }
type CertTrustEntry struct { Tag []byte Values []CertTrustValue `asn1:"set"` }
type CertTrustList struct { SubjectUsage []asn1.ObjectIdentifier ListIdentifier []byte EffectiveDate time.Time SubjectAlgorithm pkix.AlgorithmIdentifier Entries []CertTrustEntry Attributes *CertTrustAttributes `asn1:"optional,explicit,tag:0"` }
type CertTrustMemberInfoV1 struct { ClassID asn1.RawValue Unknown1 int }
type CertTrustValue struct { Attribute asn1.ObjectIdentifier Value asn1.RawValue }
type DigestInfo struct { DigestAlgorithm pkix.AlgorithmIdentifier Digest []byte }
type MSISignature struct { pkcs9.TimestampedSignature Indirect *SpcIndirectDataContentMsi HashFunc crypto.Hash }
func VerifyMSI(f io.ReaderAt, skipDigests bool) (*MSISignature, error)
Extract and verify the signature of a MSI file. Does not check X509 chains.
type PEDigest struct { OrigSize int64 Imprint []byte PageHashes []byte Hash crypto.Hash // contains filtered or unexported fields }
func DigestPE(r io.Reader, hash crypto.Hash, doPageHash bool) (*PEDigest, error)
Calculate a digest (message imprint) over a PE image. Returns a structure that can be used to sign the imprint and produce a binary patch to apply the signature.
func (pd *PEDigest) GetIndirect() (indirect SpcIndirectDataContentPe, err error)
func (pd *PEDigest) MakePatch(sig []byte) (*binpatch.PatchSet, error)
Create a patchset that will add or replace the signature from a previously digested image with a new one
func (pd *PEDigest) Sign(ctx context.Context, cert *certloader.Certificate) (*binpatch.PatchSet, *pkcs9.TimestampedSignature, error)
Sign the digest and return an Authenticode structure
type PESignature struct { pkcs9.TimestampedSignature Indirect *SpcIndirectDataContentPe ImageHashFunc crypto.Hash PageHashes []byte PageHashFunc crypto.Hash }
func VerifyPE(r io.ReadSeeker, skipDigests bool) ([]PESignature, error)
Extract and verify the signature from a PE/COFF image file. Does not check X509 chains.
type PsDigest struct { Imprint []byte HashFunc crypto.Hash TextSize, SigSize int64 SigStyle PsSigStyle IsUtf16 bool }
func DigestPowershell(r io.Reader, style PsSigStyle, hash crypto.Hash) (*PsDigest, error)
Digest a PowerShell script from a stream, returning the sum and the length of the digested bytes.
PowerShell scripts are digested in UTF-16-LE format so, unless already in that format, the text is converted first. Existing signatures are discarded.
func (pd *PsDigest) MakePatch(sig []byte) (*binpatch.PatchSet, error)
Create a patchset that will add or replace the signature on the digested script
func (pd *PsDigest) Sign(ctx context.Context, cert *certloader.Certificate) (*binpatch.PatchSet, *pkcs9.TimestampedSignature, error)
Sign a previously digested PowerShell script and return the Authenticode structure
Type of signature formatting used for different PowerShell file formats
type PsSigStyle int
const ( // "Hash" style used by e.g. .ps1 files SigStyleHash PsSigStyle = iota + 1 // XML style used by e.g. .ps1xml files SigStyleXML // C# style used by .mof files SigStyleC )
func GetSigStyle(filename string) (PsSigStyle, bool)
Get the PowerShell signature style for a filename or extension
type SpcAttributeMsiImageData struct { Type asn1.ObjectIdentifier Value SpcSipInfo `asn1:"optional"` }
type SpcAttributePageHashes struct { Type asn1.ObjectIdentifier Hashes [][]byte `asn1:"set"` }
type SpcAttributePeImageData struct { Type asn1.ObjectIdentifier Value SpcPeImageData `asn1:"optional"` }
type SpcIndirectDataContentMsi struct { Data SpcAttributeMsiImageData MessageDigest DigestInfo }
type SpcIndirectDataContentPe struct { Data SpcAttributePeImageData MessageDigest DigestInfo }
type SpcLink struct { URL string `asn1:"optional,tag:0,ia5"` Moniker SpcSerializedObject `asn1:"optional,tag:1"` File SpcString `asn1:"optional,tag:2"` }
type SpcPeImageData struct { Flags asn1.BitString File SpcLink `asn1:"tag:0"` }
type SpcSerializedObject struct { ClassID []byte SerializedData []byte }
type SpcSipInfo struct { A int UUID []byte B, C, D, E, F int }
type SpcSpOpusInfo struct { ProgramName SpcString `asn1:"optional,tag:0"` MoreInfo SpcLink `asn1:"optional,tag:1"` }
type SpcSpStatementType struct { Type asn1.ObjectIdentifier }
type SpcString struct { Unicode string `asn1:"optional,tag:0,utf8"` ASCII string `asn1:"optional,tag:1,ia5"` }