First, you need to ask Windows to validate the signature on the EXE. Your DLL can do this using the WinVerifyTrust() API, and Microsoft provide example code for doing this here.
That will tell you that the Windows you're running on is happy with the signature on the EXE. A maliciously configured machine could have an EXE signed with a self-issued certificate that had been installed on the machine, so this doesn't fulfil all your requirements, but it does it least force the opponent to do his job thoroughly.
Then, to check on the certificates, use CertGetCertificateChain(), followed by CertVerifyCertificateChainPolicy(). You can ask these functions to check for revocation, and do several other kinds of check: it's worth reading their documentation closely. There's an example program here.
Through these APIs, you can get the CERT_INFO structures for the certificates in the appropriate chain, and can check those however you like.
If you know which certificates could have been used to make valid signatures, the strongest check is to get the public keys from the certificates in the chain and check them against the public keys of the known certificates.
There is a counter to this check, if the opponent is smart, which is to edit your DLL to change the public keys stored in it to the ones the opponent is using. So you have to hide those public keys, by encrypting them, spreading their bits out over a larger piece of data, or similar tricks. Most software copy-protection comes down to trying to hide data from an opponent while still making use of it, and this is no exception. A sufficiently persistent opponent will always win this battle; your task is to make it sufficiently difficult that they give up before solving the problem.