MatthiasValvekens / pyHanko

pyHanko: sign and stamp PDF files
MIT License
460 stars 68 forks source link

PKCS11: identifiying signing key #386

Closed msetina closed 4 months ago

msetina commented 4 months ago

pyHanko-0.21.0:

pyhanko.sign.general.SigningError: Please specify a signer's certificate through the 'cert_id', 'signing_cert' and/or 'cert_label' options

Documentation says: At least one of key_id, key_label and cert_label must be supplied.

So if I provide key_id the signer creation fails...

On the other hand. At least on my card a token contains on private key, one public key and a certificate belonging to the private key. All have the same label. Additionaly the same token includes 2 additional certificates that are part of cartificate chain.

I see two things in concepts that are off: When I open a session I provide a token and on this card it identifies a private key for signing and consequently a certificate to be used for verify (with the same label) (Please fix documentation: Signing is done with private key not certificate which contains public key)

Verification which is done for PAdES in my case fails because it trys to find issuer certs, but does not look to the token for the rest of certificates that are there for it.

msetina commented 4 months ago

I checked and the failing certificate for PAdES signing is the root certificate which is self signed. That means that issuer points to the subject of the certificate.

msetina commented 4 months ago

Got over the PAdES problem. It came to Validator problem. When I pushed root cert to trusted certs in validator the problem was solved. When I check signature with pdfsig, I get Certificate Validation: Certificate issuer isn't Trusted.

Label selection is still a problem. It is explained in description. The card is similar to Belgian eID..., but as in description if we culd start from private key in token all other things are defined.

MatthiasValvekens commented 4 months ago

When I open a session I provide a token and on this card it identifies a private key for signing and consequently a certificate to be used for verify (with the same label)

The "with the same label" part is not a universal property of all PKCS#11 implementations in my experience (although the setup you describe is certainly the most common one). I agree that trying to fetch the certificate by taking the cert with the same label as the key is a reasonable default, though. That's a valid feature request and probably not difficult to implement.

(Please fix documentation: Signing is done with private key not certificate which contains public key)

I am obviously well-aware of that. Nonetheless, the corresponding certificate still needs to be embedded in the signature object that goes into the PDF. In most cases this certificate is grabbed from the PKCS#11 token (but it can also be supplied out-of-band---I know of at least one vendor that ships a PKCS#11 "frontend" for a remote signing service where the user certificate is provisioned through a completely different channel and not part of the token unless the user deliberately adds it).

That said, if you'd point me to specific areas of the documentation that you believe are confusing on this point, I'm more than happy to take a look at those and adjust the wording as necessary.

MatthiasValvekens commented 4 months ago

I ended up implementing a slightly different defaulting pattern: if cert_id and cert_label are undefined, cert_id will be set to key_id (if defined) and cert_label will be set to key_label (if defined). The same goes in the other direction.