New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow public init from P384 PublicKey #18
Conversation
Allows to initialize a public key directly from a P384 Public Key.
Thanks for the PR! The reason I didn't export this method publicly was that I couldn't find (and am still having trouble finding) documentation about whether or not Apple's CryptoKit does point validation when constructing the Right now the library only accepts public keys which are represented as compressed points (which is the approach recommended by the paseto standard), which ensures that the public key imported ends up on the curve. Unless we can find docs stating that the points are being validated, I'll probably have to implement point validation for this constructor 🙂 |
I cannot find any documentation that answers your question. Honestly, I lack the knowledge to know where to look for. But I did have a look at Apple's Swift Crypto source code. Apparently, when constructing a P384 public key using pemRepresentation
So it's not documentation, but code. Maybe you can tell if this includes point validation. Googling Another option could be to create an initializer that warns the user: |
This is a pretty familiar story trying to dig into Apple's CryptoKit unfortunately 😅 What I may do here despite a little bit of inefficiency, for the publicly exposed initialiser: I'll export the public key into compressed form and then re-import it. It's not pretty, but it'll avoid needing to do explicit point checks and funnel things through a common (safe) initialiser where invalid points are a non-issue. |
I think this is a great solution. The inefficiency is not a problem for me. But I decided to ask our question at swift-crypto anyhow. |
@aidantwoods Both swift-crypto and CryptoKit do point validation. That means we can make the |
This test being possible would seem to indicate it is possible to construct invalid public keys (the invalid point I used is only caught when using the new PASETO constructor, but CryptoKit allows the key to be constructed). |
I'll report at the Developer Forum. |
FYI, in the test I ran, constructing the identity point was allowed on CryptoKit (it wasn't in Swift Crypto), but operations using it failed, so it could be that invalid public keys can be constructed in CryptoKit, but that the validity check is delayed in the operations using them. |
@aidantwoods Maybe we can try if we can replicate this in your test? |
Replicating for signing is a little more difficult, because I'd need to construct a malicious signature that I'd expect to be validated by a carefully chosen invalid key 😅 It also makes me nervous to make decisions based on observed behaviour (even if validation is being done at point of use, who knows what OS versions that might apply to). That aside, the API I want to strive for in this library is to detect attacks as soon as possible (and not pass around a bad key as if it were valid, hopefully refusing to use it at the last minute). I'd only feel comfortable accepting these key objects directly with the validation step in place (already now implemented in this PR), so that bad keys are caught on import. |
I see @remko published your findings at the Developer Forum. Let's see what they come up with. |
@aidantwoods Shall we merge this in? It could take a while before we get our answer. I think your work is a perfect solution that can be changed in the future if needed. |
It seems there was a BC break in the initialiser I could probably bug report the BC break and retrospectively switch back to support older versions again at some point, but given that this seems to be broken on latest OS, that's really the priority to get working again. |
Apple seeimingly broke the x963Representation constructor when releasing the new compressedRepresentaion constructor, the former no longer accepts compressed points which is a BC break. This would be fine, except the new method cannot be used by newer OS versions if we want to support older OS versions at the same time. Either we need to avoid using the x963 constructor, or only support macOS 13 and similar. This is pretty new, and not even GitHub supports it yet for pipelines. It's not ideal, but it seems the only workable alternative is the implement handling of compressed points manually. This is annoted pretty heavily to follow the steps and notation in the spec.
7df0c5f adds a library specific implementation for handling compressed points. It's not possible to use Apple's constructors anymore because of the BC break on This is all pretty unfortunate, and hopefully temporary. I'll likely switch back to |
@aidantwoods Wonderful, thanks for all your work here! |
Fixed a couple of bugs with another pass of the spec, and now confirming that my implementation matches the behaviour of the new I'm going to make another slow pass through the spec tomorrow to make sure I don't spot any nits, but then should be good to merge. |
This isn't a great practice and can't be used in the main package code, is fine for the sake of making the tests compile
Thanks for the MR @frederikbosch! 😄 |
This allows to initialize a public key directly from a P384 Public Key.
In my case, I have a PEM file as public key, which I read from a file and then I need to initialize
Version3.AsymmetricPublicKey
.