Async signing of repository objects. #163
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR is a proposal for a way to allow both blocking and async signers.
It twists the traits around: Instead of having a signer trait, it provides two traits
SignWithKey
andSign
(the names are temporary, I suppose the first one should really bePrepareForSign
or something) that are implemented by types that want to be signed. There are two traits since signing happens in two stages: first, the public key is given to the object viaSignWithKey
so it can use it to create the actual content to be signed if that includes information about the public key (e.g., in RPKI, the Subject of certificate is based on the hash of the public key). It then returns an intermediary object that has the data to be signed. It provides access to that data viaSign::signed_data
so a signer can grab an octets slice to do the signing on. Once it is finished, it gives the signature to the object which transforms itself into the final output object.The
OpenSslSigner
implements the signer interface for this via the two methodssign_with_key
andsign_with_one_off_key
(names temporary to not collide with the existing signer trait methods). They both take something that implementsSignWithKey
and do the dance described above.To see if this works in practice, the new reverse signer traits have been implement for certificates and signed objects. There is a lot of extra types necessary, particularly for signed objects, but if we adopt this approach, the current builders can be cleaned up to better work with these types. Currently, this is just a quick and dirty implementation.
The user side is a lot less tedious. You can see it in action in the
reverse_signer_test
modules of bothrepository::cert
andrepository::sigobj
. In the latter case, you need to explicitly sign in two stages – first with the one-off key for signing the attributes and then with the issuer key to create the certificate. But I think that’s okay.For a blocking signer, we can adjust the existing
Signer
trait to actually use the new facilities and re-implement the existing methods on the various signed types so that there will be no actual user-visible changes.