-
Notifications
You must be signed in to change notification settings - Fork 803
Fix read/write certs with Ed25519/X25519 public key #2293
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
Conversation
Proper Ed25519/X25519 certs have pubkey algo with OID 1.3.101.112/110, according to RFC8410. This commit add these OIDs, and also fixes pubkey parsing/creation - according to the same RFC, it's just a bytestring, without ASN.1 wrapping. Also, according to the same RFC, EDDSA/X25519 MUST not have params, even empty.
|
Do I understand correctly, that SPKI still should follow RFCs about Algorithm Identifier? Like, RFC8410. With this MR, Ed25519/X25519 public keys exported with pkcs15-tool --read-public-key can be parsed by openssl, finally. |
|
@Jakuje could you, please, test if with Nitrokey? I think that this one should allow p11test to really test sign/derive (before this commit, these tests were ignored, as algorithm id was not known to OpenSSL, and RFC8410), and pubkeys read with pkcs15-tool should be parseable by openssl now: |
|
Tested with Nitrokey Start and it looks like working fine for me. Thanks! |
|
@Jakuje BTW, have you checked, what is the maximum amount of data, which can be signed by Nitrokey? I mean, it seems that in EDDSA, hashing is done as a part of algorithm, inside the token (at least for Yubikey), and OpenSC is now limited in 512 bytes. When I changed buffer sizes in pkcs15-sec.c and mechanism.c to 4096, I found that Yubikey can sign up to 3053 bytes. I wonder, if this limit could be found somewhere, and used as a size of buffer... P.S. Found some DOs and reader capabilities detect, will take a look into it |
|
I was able to get only 256 bytes signed with Nitrokey. If it is more, the driver attempts to chain the data in the next APDU and it fails for some reason: one byte less works fine as it fits into single APDU. I did not investigate the issue further. |
Yes, the hash size is based on the key size. Ed22519 uses SHA-256: RFC 8032 It also talks about the "prehash" function "PH" For Ed25519, PH is the message which could be any size. But it might be possible for a card driver to do the PH in software, or pass on the whole message to the card. So in any case OpenSC needs to pass on the message to the card driver. There is at least one card drivers that can do a hash in the driver. If card driver set the flags to include SC_ALGORITHM_ECDSA_HASH_SHA then it wants to do the hash in the driver or pass on to the card. So you may need to add code similar to card-sc-hsm.c or card-epass2003.c And for EDDSA, to not set the SC_ALGORITHM_ECDSA_HASH_NONE flag as this tells PKCS11 that the application can do the hash. It may be that one card is using Ed25519ph, and one is using Ed25519.
I don't have any devices to test any of the above. Value of context is set by the signer and verifier (maximum of 255 |
|
RFC 8032 has a few Erratas:
This restriction may be what is seen with the NitroKey. But not with the Yubikey. If it is possible to load a specific key on one or both of these devices, a good test would be to get the same key on both, maybe one of the the ones from RFC 8032 |
|
You where also asking about the format of SPKI. https://tools.ietf.org/html/rfc8410 has some examples of certificates and comments on https://tools.ietf.org/html/rfc8032 |
It applies to context, which is not the message, and used only by ed25519ctx and ed25519ph, which is not what tokens support (I think, it's just ed25519. From the RFC:
I've checked my keys against python implementation in cryptography library, and it can verify signature made by my key. I've also checked it against test vectors in the rfc. Oh, and I managed to hack XCA, to sign x509 certificate using my token, and then verify it via openssl - all is good (that's why I need more than 512 bytes, as certificates could be longer) |
The problem is that I need to know, how to inform OpenPGP token about variant of ed25519. I cannot find any info in OpenPGP 3.4, and according to it, ECDSA supports only prehashed messages, so, no other options for it as well
P.S. I've just checked gnupg, and it seems that it sends data as is, for EDDSA. And here is APDU: I'll check with gpg --sign, though P.P.S Just checked sign - gnupg is doing prehash, and put 64 bytes of sha512 hash in card, but it is not using any prefix, or DSI, or doesn't use any other APDUs to inform token that data is pre-hashed. So, I'm assuming that this is standard way to do so, but this means that token supports only PureEdDSA mode. |
|
Actually, maybe this discussion is little bit off-topic, as it has nothing to do with current MR. I'll create a issue, to discuss possible solutions. |
|
Certificates to be signed are a good example, but there should be no limit. A user could ask for a large document to be signed. https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/csprd01/pkcs11-curr-v3.0-csprd01.html has:
So I was suggesting that the card driver could collect up multiple segment of data much like a driver doing the hash in software but not doing the hash, which was why I brought up An trace of the Yubikey at the pcscd level would show what the the Yubkey driver or OpenPGP is doing. What I am saying is I don't think changing the size of the buffer in pkcs15-sec.c is the correct way to address this. PKCS11 implies there might be some token resource limit to what can be handled. If all the tokens have some reasonable limit, like 4K, then maybe pkcs15-sec.c buffer size would be OK. P.S. I found I do have a NitroKey Start token that supports Ed25519. I hope to be able to do some testing with it soon. |
|
@Jakuje Can I ask you, to test master branch of OpenSC, if EdDSA Pubkey from Nitrokey can be parsed by OpenSSL? Same command as #2293 (comment) |
Sure: It works fine in your branch though: |
|
This means, that tests will, almost certainly, silently fails for Nitrokey, as well, as I described in #2304. Thank you! So, this branch is good to fix this bug for any token, supporting ed25519/curve25519. |
|
I have also run some tests using a combined version of your PRs by doing the following: I felt it was most important to make sure these PR all work together. as I have both a Nitro Start and Yubikey 5 NFC. Both have a Ed25519 key for signature and one for authenticate. was run on both and creates a signature file and extract the public key Unfortunately, OpenSSL does not have a utility to verify an EdDSA signature. (I even looked at 3.0.0-alpha15.) And pkcs11-tool does not either. So I am attaching the 5 files here for your verification. the "-n" files are for the Nitrokey and the "-y" are for the Yubikey. The both used the 200 byte 200.txt file as input. the sig files are binary. I had to specify -m EDDSA, as it looks like pkcs11-tool does not figure that out based on the key. |
|
p11test are checking, that what is signed by token could be verified. If you compile it without -DNDEBUG, output will show something like This even works for messages of length 2048 (with hacked tests and increased buffer). I'll try to verify your files using python cryptography library (I had success using it, with my signatures) |
The 3.0 should have it, I think: At least that was what I used when I started testing Ed25519. |
|
@Jakuje I knew I saw instruction somewhere, but I forgot, where :) |
|
@dengert I checked your data, signature matches: verify should show an error, if signature is not matching, but it is not showing, so, verify works. But definitely, @Jakuje's way to test it is much more convenient. |
|
@Jakuje Thanks for 3.0.0 tip! I built OpenSSL 3.0.0-alpha15-dev from git. both return |
|
@dengert I think this PR is ready and it would make sense to apply it for 0.22.0, what do you think? |
|
I don't see any problems. But I have not tried anything since April, 19, and that was just to prove a Nitro Start with just a key worked. |
|
And do we have something else to try? For the input sizes, we have separate issue. |
|
Ok. I will merge this as without that, I have failures in |
Proper Ed25519/X25519 certs have pubkey algo with OID 1.3.101.112/110, according to
RFC8410. This commit add these OIDs, and also fixes pubkey parsing/creation - according
to the same RFC, it's just a bytestring, without ASN.1 wrapping.
Also, according to the same RFC, EDDSA/X25519 MUST not have params, even empty.
Checklist