How to tell if an assembly is delay signed or not.
.Net framework has a great feature called delay signing. Every strongly named assembly has a public key, and a strong name hash stored in the metadata. At runtime CLR uses the public key to verify the strong name hash to make sure the assembly is not tampered. When delay signing is requested, the compiler reserves a space in the metadata, but does not fit the space with the real strong name hash. You can use SDK tool sn.exe to request skip strong name verification for your assembly so strong name verification check will not be performed at runtime by CLR. In a company developers usually have access to public key. But private key is kept secretly, only accessible by a few people. This feature allows developers to develop/QA with only public key. Build lab will sign the product with the real private key.
Keep this in mind, now suppose you successfully loaded an assembly, how can you tell this assembly is fully signed or it is delay signed, and strong name verification is skipped?
mscoree.dll have an API StrongNameSignatureVerficationEx. If you have SDK installed, this API is defined in strongname.h as following.
// Verify a strong name/manifest against a public key blob.
SNAPI StrongNameSignatureVerificationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
BOOLEAN fForceVerification, // [in] verify even if settings in the registry disable it
BOOLEAN *pfWasVerified); // [out] set to false if verify succeeded due to registry settings
The comment is very clear about how to use this API. You pass the file path of the assembly in wszFilePath, set fForceVerification to TRUE. After this API returns, *pfWasVerfied will tell you whether this assembly passed strong name signature verification or not. If *pfWasVerified is FALSE, this assembly is delay signed.
There is no managed equavalent today. But this API is very easy to be wrapped in P/Invoke.