Can someone please help me with the following question
I want to check the signature on a CSR (X509 certificate signing request) is valid I believe I know how to do this (as follows) but not certain if my understanding is correct and would be very grateful if someone could check/correct/confirm my method.
I am using PowerShell (but understand the basic concepts of C’# too) I have a text file on my hard drive which is basically a base64 encoded CSR called csr.txt
So in PowerShell I do the following
$CSR = get-content c:\temp\csr.txt –raw $RequestComObj = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10 $RequestComObj.InitializeDecode($CSR,6)
Now I have the CSR there is a CheckSignature method on it which requires a Pkcs10AllowedSignatureTypes in the constructor, when I look into this I see there are two hex values representing the possible options
AllowedKeySignature = 0x1 AllowedNullSignature = 0x2
From what I have read/tried this far I can pass the constructor one of these two values either 0x1 for SHA1 or 0x2 for SHA2 (SHA256 for example) Therefore my question is if I have a CSR signed using SHA1 and I want to check this SHA1 signature if valid the last part of my script should look like this?
$RequestComObj.CheckSignature(0x1)
or possibly just
$RequestComObj.CheckSignature(1)
If the CSR is signed SHA2 I would use
$RequestComObj.CheckSignature(0x2)
or possibly just
$RequestComObj.CheckSignature(2)
When I try the above PowerShell does not return anything to the console (providing the CSR is signed accordingly) which is normal for PowerShell i.e. if no error return nothing.
Is the above correct? e.g. valid for checking signatures as I think it is
Thanks All
__AUser
I am editing my question to respond to the answers below (as too big to post as a comment)
Hello vcsjones and Crypt32
Thanks very much to both of you for taking the time to reply to my question (the COM > CRL wrapper and error masking was very helpful to for my broader understanding).
So if I understand you correctly (forgive me I am not a programmer/developer) if I use 0x1 as above it only checks if the Digest (e.g. Hash) is SHA1 and OK and does NOT check if the signature is the correct one for that digest? in other words it may be possible to have a valid signature but for a different digest and it would still pass if using 0x1
Is my understanding above correct please?
if so does this also mean using 0x2 above would old check is the digest is SHA2 and not that the signature actually belongs to that digest?
Also you mentioned above rather than using CheckSignature() I should use KeySignature
When I look at the members of the $RequestComObj PowerShell object above I do not see a member called KeySignature (unless it is buried further down) rather I see the following collecting of COM members
Type : 1
EnrollmentContext : 1
Silent : False
ParentWindow :
UIContextMessage :
SuppressDefaults : False
ClientId : 9
CspInformations :
HashAlgorithm : System.__ComObject
AlternateSignatureAlgorithm : False
TemplateObjectId :
PublicKey : System.__ComObject
PrivateKey :
NullSigned : False
ReuseKey : False
Subject : System.__ComObject
CspStatuses :
SmimeCapabilities : False
SignatureInformation : System.__ComObject
KeyContainerNamePrefix :
CryptAttributes : System.__ComObject
X509Extensions : System.__ComObject
CriticalExtensions : System.__ComObject
SuppressOids : System.__ComObject
PolicyServer :
Template :
AttestPrivateKey : False
EncryptionAlgorithm :
EncryptionStrength :
ChallengePassword :
NameValuePairs : System.__ComObject
ClaimType :
AttestPrivateKeyPreferred : False
From the above I worked out I can obtain a Base64 encoded version of the Signature and the Public Key using the following methods
$RequestComObj.Signature()
ysZ//Y3EvJnCy3UoBwhZlIoIh7w733+kocDJ9i3+jMdpFu/2YEF6jQQ3UZ8vbrdC
eq6ORbL9yZX2LlBM/H5w30in/ipM9KR3Ynv1ssc0eLyCNL5HILxdgREAFqpTDM6F
3XFpRtzffHs0C5czrIgDmncncKLsUeRVtd4Z9QfP7NnFoiUaquKLFou0ANn7X5cK
LLe9nzYsi9/fuAj6gQAgBTKWWY17ke8nFlPtQsQlxP3nIPLEpDVDZCcvTRcgaamA
xwKsf4isW1zjHkv6pvMEtjuxkrX0/Y91VuPx2WnbciFmpYIH9cE1oKG3L3J34w6d
mcHwPy0EmPZ8bJjL9hiBMA==
$RequestComObj.PublicKey.EncodedKey()
MIIBCgKCAQEAlQdqVHQgzd1uJ9MFb935Vfyg1Y1mZXn4OMwJudOhEzx7m1+4C8lD
OXn5hglHG0FFad+KkLok/GcAzdc2iwBOholJ2MYPXCnfkJLYXHLRj+CKRvhCHWJO
XkQQQ0apdXh1MhiDBD/BIKqmMm54XLFhZqjQiNeIVHFb9GS06Ps/xuOWzqY54xSM
/047nzYNU50FrTHuBCiqtJtHpKtdrCWyhWi7was0noCx/XGm6g8nVnzPTQCSeAPp
6mSt4kSMtdoVZYg1n5pmMW+QYAero/UWrbNp1WlkpUH4s96H6pUrbF7RIkXpCwWo
cxBHAXVcMst2HYvwstAETxvqeKTOvVEEAQIDAQAB
So now I am thinking I have the CSR, I have the signature and I have the public key from these three pieces of information I must be able to check if the signature on the CSR is valid?
I just need a bit of help with the code if you would be so kind please, C# is find as I can use this in line with PowerShell etc.
Thanks very much again much appreciated
__AUser