Remote Signature Device Support?
See original GitHub issueHi! Thanks for this project, a good PDF signing library for Python was missing!
I have a mechanism for remote signature creation, i.e., I have an interface where I can provide the hash of a PDF document (already prepared with an empty signature placeholder) from the interface I get back a CMS object representing the signature for this document and the certificate of the signer; potentially I get some revocation information as well.
Compared to the BeID example that you already provide, there are some differences for this remote signature interace. Most importantly, I cannot know the signer’s certificate beforehand, as this certificate is short-lived and is created on-demand.
I would be happy to provide code for remote signature devices for your library. It seems that implementing a Signer
class is the way to go, but from what I saw so far it seems that the library assumes that the certificate is known beforehand. It would be great if you could provide me some pointers on the following topics:
- What are the interfaces I would need to implement to just grab the hash of a prepared document?
- How would I provide the CMS object and revocation information to your library?
Issue Analytics
- State:
- Created 3 years ago
- Comments:20 (11 by maintainers)
FYI: Remote signing with pyHanko has been integrated into a library for the yes® banking ecosystem: https://github.com/yescom/pyyes
Thanks again for the support!
Hi Daniel,
Thanks for checking in!
First, the fact that
signature_bytes
is used twice isn’t that weird by itself: it’s used both to embed the actual signature, and to compute a hash to key an entry in the VRI section of the Document Security Store. Having said that, pretty much no-one bothers with VRI these days. It was intended as a mechanism to optimise validation, but it ended up largely unused, and is pretty much deprecated in recent PAdES if I recall correctly. VRI generation is also togglable since0.8.0
. Anyway, that’s just a minor background detail.However, if you do things right,
finish_signing()
already callsadd_dss()
for you in the background, provided that you set up the signing process to do PAdES-style signing. This wasn’t the case back when we had our first conversation on this topic. Actually, the way you’re currently doing things (callingadd_dss()
beforefinish_signing()
) kind of only works by accident. The resulting document is likely correct right now, but the way you’re calling the API is sort of fragile.Ordinarily, I would recommend letting pyHanko do the revocation info bookkeeping entirely on its own, but from what I remember, you don’t have access to the certificate & revocation information until after submitting a hash to the server, right? Either way, I would at least swap the
add_dss()
andfinish_signing()
calls. If you calladd_dss()
yourself, there’s no need to keep tabs on the value forpost_sign_instr
you got from the API earlier. You also don’t need to pass in a validation context tofinish_signing()
, that only matters for document timestamps.As an alternative to calling
add_dss()
manually, you may want to instantiate your own value forpost_sign_instr
in the call tofinish_signing()
instead, in order to get something slightly more declarative. See here for further documentation on how to set that up. Essentially, if all you need is PAdES-B-LT (without the extra document timestamp) then you only need to supply a value for thevalidation_info
field. That one also has lots of subfields, but in your case, passing in the CRL and OCSP values is probably enough (you can probably even leavesigner_path
empty).Hope that helps, and if anything else is unclear: let me know! These low(ish)-level APIs are tricky to document holistically, since they have to accommodate so many different workflows…